bug-1979: test.c never included resobj.h, so makeResource() was an implicitly declared function in this TU -- its 64-bit pointer return was truncated to int (0x50b000000118 -> 0x118) and sign-extended back. Dormant since E2 Phase 1 (the test only TEST_ASSERT_NOT_NULL'd it and re-derived the real pointer via key_find); the leak-fix teardown's dereference(made) was its first real use and SEGV'd under ASAN_OPTIONS=detect_leaks=1 (the xce-build.sh all direct-run step). - include resobj.h: makeResource now declared with its true prototype - unmeet: memset-only -- sched_check_shared_satisfy_() xvec_idval_init()s it itself; the pre-init leaked the vector it replaced (2x4B per call) - uncomitted: single xvec_init/xvec_fini pair (was init'd twice, fini'd once) - teardown: collect-then-dereference the refcount-1 resource object, then destroy(resmgr), then xstring_table_fini() -- mirrors xce_sched_core_fini() (core.c:405) Verified: ASAN_OPTIONS=detect_leaks=1 direct run rc=0, 17/17 PASS, zero leak reports; xce-build.sh all green (137/137 suites + manual sched_test + Go tests). Co-Authored-By: Claude Code <noreply@anthropic.com>
3.8 KiB
| id | status | status_updated | status_note | component | severity | timestamp | last_seen | occurrences | files | tags | related | summary | |||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| bug-1979 | open | 2026-10-29 | newly logged | scheduler | crash | 2026-10-29T03:16:20Z | 2026-10-29T03:16:20Z | 1 |
|
|
sched_test: makeResource() implicitly declared -- pointer truncated, dereference SEGVs |
bug-1979: makeResource() implicitly declared in sched_test -- pointer truncated, dereference SEGVs
Description
Observed:
ASAN_OPTIONS=detect_leaks=1 ./scheduler/testsuite/sched_test SEGVs in
dereference after all 17 tests PASS:
==659821==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000258
#0 in dereference ../subprojects/librtti/src/ref.c:31
#1 in test_unsatisfy_external_skips_inuse_shared_leg ../scheduler/testsuite/test.c:826
Expected: the test's teardown dereference(made) releases the
refcount-1 resource object registered by makeResource().
Impact: sched_test cannot run with leak detection enabled (the
xce-build.sh all manual direct-run step); crashes after a clean PASS.
Found by: ASAN direct run while closing out the feature/license-resources -> working merge verification.
Environment
- OS: Ubuntu 24.04.2 LTS; kernel Linux 6.8.0-147-generic x86_64
- libc: glibc 2.39 (host ldd)
- Toolchain: gcc (GCC) 15.2.0, meson 1.9.1
- Build: asan (xce.build)
- Code: working @ 9b652d93-dirty (test.c local leak-fix edit)
- Deployment: n/a (unit test, no cluster)
Reproduction
meson compile -C src/xce.build sched_testASAN_OPTIONS=detect_leaks=1 ./src/xce.build/scheduler/testsuite/sched_test(full run or-t test_unsatisfy_external_skips_inuse_shared_leg)
- Frequency: deterministic
- Evidence: not kept (transient ASAN stderr; repro command above)
Root cause
test.c never includes resobj.h and has no local extern, so
makeResource() is an implicitly declared function in this TU
(gnu17 + this gcc emits only a warning; the build proceeds). An implicit
declaration returns int: the real 64-bit pointer 0x50b000000118 is
truncated to 32-bit eax (0x118) and sign-extended back
(cltq visible in the disassembly right after the
call makeResource), so made == 0x118 -- garbage.
The bug was introduced with the test itself (E2 Phase 1, 2fcacac2) but
lay dormant: the test only ever did TEST_ASSERT_NOT_NULL(made)
(0x118 != NULL always passes) and key_find-re-derived the real
pointer into r for the flag overwrite. The merge-verification leak fix
added dereference(made) in the teardown -- the FIRST real use of the
truncated pointer -- which turned the latent defect into a SEGV.
Fix
#include "resobj.h" in src/scheduler/testsuite/test.c (the header that
declares extern xce_resource_t* makeResource(var, xce_resource_t*)),
plus the leak fixes that motivated the teardown:
symmetric single xvec_init/xvec_fini for uncomitted, memset-only
unmeet (sched_check_shared_satisfy_() xvec_idval_init()s it itself),
and the collect-then-dereference teardown
(dereference(made) -> destroy(core.resmgr) -> xstring_table_fini(),
mirroring xce_sched_core_fini()/core.c:405).
Verification
- Test: test_unsatisfy_external_skips_inuse_shared_leg
(src/scheduler/testsuite/test.c); the SEGV itself was the RED state
(deterministic, both full-run and single-test mode), GREEN after the
include: rc=0, 17/17 PASS, zero leak reports under
ASAN_OPTIONS=detect_leaks=1, single-test mode too. - Suites:
meson test --suite controller6/6 OK; fullxce-build.sh allre-run pending at logging time. - Live: n/a (unit test only).
References
- Related: bug-1429 (the XCE_TESTING reaper convention this teardown
complements), E2 Phase 1 (
2fcacac2) where the test was introduced.