fix(scheduler): release interned queue resreq with dereference, not free (bug-1858)
q->resreq holds an interned makeString() value (pointer past the xstring object header). core_upsert_queue() and sched_update_existing_queue() released the old value with FREEUP()/free() when a queue update carried a new resreq, an ASAN bad-free. Seen as HA soak replay-parity errors=1: the sim replay of a snapshot-restored queue followed by a config push aborted in core_upsert_queue. Both sites now dereference() the old value (NULL-guarded). Regression tests cover each site; the existing queue-update test had skipped the resreq branch. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
441008cd30
commit
9e9f2798a0
4 changed files with 65 additions and 2 deletions
|
|
@ -350,6 +350,27 @@ test_update_existing_queue_real(void)
|
|||
TEST_ASSERT_EQUAL_INT(3, q->sched_delay);
|
||||
}
|
||||
|
||||
/* bug-1858: q->resreq is an interned makeString() instance, so replacing
|
||||
* it must dereference() the old value -- a plain free() is an ASAN
|
||||
* bad-free (pointer is past the xstring object header). */
|
||||
static void
|
||||
test_update_existing_queue_replaces_interned_resreq(void)
|
||||
{
|
||||
xce_scheduler_t sched;
|
||||
fixture_init(&sched);
|
||||
|
||||
xce_sched_queue_t* q = make_test_queue("q1", 1);
|
||||
q->resreq = makeString("type == any");
|
||||
|
||||
xce_queue_t upd;
|
||||
memset(&upd, 0, sizeof(upd));
|
||||
upd.queue = makeString("q1");
|
||||
upd.resreq = makeString("type == local");
|
||||
|
||||
TEST_ASSERT_EQUAL_INT(0, sched_update_existing_queue(&sched, &upd));
|
||||
TEST_ASSERT_EQUAL_STRING("type == local", q->resreq);
|
||||
}
|
||||
|
||||
static void
|
||||
test_update_unknown_queue_returns_enoent(void)
|
||||
{
|
||||
|
|
@ -416,6 +437,7 @@ int main(int argc, char* argv[])
|
|||
RUN_TEST(test_rusage_unknown_job_returns_enoent, 0);
|
||||
RUN_TEST(test_rusage_null_returns_einval, 0);
|
||||
RUN_TEST(test_update_existing_queue_real, 0);
|
||||
RUN_TEST(test_update_existing_queue_replaces_interned_resreq, 0);
|
||||
RUN_TEST(test_update_unknown_queue_returns_enoent, 0);
|
||||
RUN_TEST(test_update_queue_null_returns_einval, 0);
|
||||
RUN_TEST(test_ctx_init_defaults_alloc_mode_to_normal, 0);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue