fix(persist): zero nresvals_to_sched after free_name_val_list

Crash: encode_NameValue_list called with count=21, s=NULL on worker
rejoin, causing SIGSEGV in persist_worker_hook_fun.

Root cause: free_name_val_list(xce_name_val_t***, int) accepted count by
value. It zeroed *vals (resvals_to_sched = NULL) but could not zero
nresvals_to_sched. Any caller that freed the scheduler resource snapshot
(opget.c workerlist, reply.c clusterconf, dataex.c, sched.c dispatch)
left nresvals_to_sched stale. When the worker later rejoined and the
WAL HOOK fired, the WAL encoder read count=21 with a NULL pointer.

Fix: change signature to free_name_val_list(xce_name_val_t***, int*)
so both fields are zeroed atomically. Update all 7 call sites.
This commit is contained in:
Rongsong Shen 2026-05-20 09:39:07 +00:00
parent 0d783b16e3
commit e5fde7b55f
7 changed files with 14 additions and 15 deletions

View file

@ -143,7 +143,7 @@ static int xcesched_push_configs(cluster_t* c)
rc = xce_pushconfig_req(c->sched.ep, c->myhost, &configdata);
free_name_val_list(&(configdata.data.conf4sched->resvals),
configdata.data.conf4sched->nresvals);
&(configdata.data.conf4sched->nresvals));
FREEUP(configdata.data.conf4sched);
@ -223,7 +223,7 @@ static int xcesched_push_workers(cluster_t* c)
for (i = 0; i < workers.n_total; i++) {
xce_worker_t* w = workers.workers[i];
free_name_val_list(&(w->resvals_to_sched), w->nresvals_to_sched);
free_name_val_list(&(w->resvals_to_sched), &(w->nresvals_to_sched));
}
unlock_collect_workers(&wlist);
@ -461,7 +461,7 @@ static int sched_worker_change(int type, int situation, void* data,
#if 0
/*FIXME*/
free_name_val_list(&(w->host.resvals_to_sched),
w->host.nresvals_to_sched);
&(w->host.nresvals_to_sched));
#endif
xlist_fini(&resvalist);