fix: add bounds checks in eval_select_simple for null/empty host_eval_ctx; remove empty_ctx hack

- simple_num/simple_str: guard h->numvals/strvals NULL and idx out-of-range before array access
- eval_select_simple SEL_RESNAME: guard host->numvals NULL and idx bounds before deref
- eval_select_inner SEL_RESNAME (memoizing path): same NULL/bounds guards for numvals and strvals
- build_host_eval_ctx: return valid empty context (num_res=0, NULL arrays) instead of NULL when num_res<=0
- sched_meet_host_selection: remove empty_ctx stack hack; always call build_host_eval_ctx which now handles the zero-resource case cleanly
This commit is contained in:
Rongsong Shen 2026-04-30 05:20:37 +00:00
parent 40261b7e96
commit 8cff4ac889
2 changed files with 27 additions and 27 deletions

View file

@ -132,8 +132,9 @@ build_host_eval_ctx(const xce_sched_worker_t* w, int num_res)
if (ctx == NULL) return NULL;
if (num_res <= 0) {
free(ctx);
return NULL;
/* valid empty context — numvals/strvals remain NULL, bounds checks protect access */
ctx->num_res = 0;
return ctx;
}
double* numvals = calloc(num_res, sizeof(double));
@ -185,26 +186,14 @@ int sched_meet_host_selection(xce_scheduler_t* sched, xce_sched_worker_t* w,
int num_res = (int)w->resvals.caps;
/* When num_res == 0, build_host_eval_ctx returns NULL (no resource slots).
* Use an empty stack-allocated context so eval_select_simple can still
* evaluate constant sub-expressions (SEL_TRUE, SEL_FALSE, SEL_ANY). */
host_eval_ctx_t empty_ctx = { .num_res = 0, .numvals = NULL, .strvals = NULL };
host_eval_ctx_t* hctx;
if (num_res <= 0) {
hctx = &empty_ctx;
} else {
hctx = build_host_eval_ctx(w, num_res);
if (hctx == NULL) {
/* OOM: conservatively pass host */
return 1;
}
host_eval_ctx_t* hctx = build_host_eval_ctx(w, num_res);
if (hctx == NULL) {
/* OOM: conservatively pass host */
return 1;
}
int rc = eval_select_simple(s->root, hctx);
if (hctx != &empty_ctx) {
free_host_eval_ctx(hctx);
}
free_host_eval_ctx(hctx);
/* eval_select_simple: 1=match, 0=no-match, <0=error (treat as no-match) */
return (rc > 0) ? 1 : 0;