fix(controller): sched_worker_change() use-after-free on worker disconnect (bug-1578)
sched_worker_change() aliased w->host.resvals_to_sched to a local xlist_t's backing array, pushed it to the scheduler, then freed that array via xlist_fini() without resetting the alias - leaving a dangling pointer for the rest of the worker's life. On disconnect (handle_worker_leave -> mark_worker_unavail -> persist_worker_hook_fun -> capnp_encode_worker -> encode_Worker -> encode_NameValue_list), this dereferenced freed memory and crashed the controller - but only once a scheduler had ever connected (on_scheduler_join gates the hook registration), which made it easy to miss in isolated worker-only testing. The correct reset already existed in the function but was dead-code'd behind #if 0 /*FIXME*/ - apparently from a prior fix attempt that got wrapped instead of landed. Fix mirrors the proven-correct pattern already used by the sibling apiserver_worker_change(): null the alias before xlist_fini() frees the backing array, rather than double-freeing via free_name_val_list() first. Adds test_sched_worker_change.c, a regression test driving the real production hook-dispatch path (xce_run_hooks -> sched_worker_hook_fun -> sched_worker_dead -> sched_worker_change) and the real encode_Worker() encoder the original crash traversed - confirmed to reproduce the exact ASAN heap-use-after-free when the fix is reverted, and pass clean when restored, closing the gap that let this regress silently once already. Found while live-testing the resource-value-verification feature (deploying a scheduler + injecting worker resource values via xce_test, then disconnecting) - unrelated to that feature's own changes. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
parent
23c3fd6b6a
commit
b406dd762a
3 changed files with 392 additions and 5 deletions
|
|
@ -545,11 +545,8 @@ static int sched_worker_change(int type, int situation, void* data,
|
|||
}
|
||||
mylock_unlock(&(c->sched.lock));
|
||||
|
||||
#if 0
|
||||
/*FIXME*/
|
||||
free_name_val_list(&(w->host.resvals_to_sched),
|
||||
&(w->host.nresvals_to_sched));
|
||||
#endif
|
||||
w->host.nresvals_to_sched = 0;
|
||||
w->host.resvals_to_sched = NULL;
|
||||
xlist_fini(&resvalist);
|
||||
|
||||
return rc;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue