fix(libxce): bug-1600 -- makeGroup() freed rtti makeString() pointer via raw free()
makeGroup()'s existing-group update path (hit whenever a config-push re-applies a group name that already has members, e.g. a retried config push during controller failover) released xce_g_member_t.u.name via FREEUP() (plain free()). u.name is allocated by makeString(), an rtti-managed, refcounted pointer that is not a malloc()-base address -- freeing it directly corrupts the heap. group_killer() in the same file already releases the identical field correctly via dereference(). Switch both FREEUP(m->u.name) call sites to dereference(m->u.name) to match. Add a regression test that re-applies config for the same group name twice, reproducing the exact ASAN bad-free at group.c:234 pre-fix. This is the root cause of the reproducible xce_scheduler "free(): invalid pointer" SIGABRT crashes seen during 3-attempt controller-failover config-push retries (8 confirmed core dumps). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
parent
6522a73459
commit
ddee884c1b
4 changed files with 62 additions and 3 deletions
|
|
@ -231,7 +231,7 @@ xce_group_t* makeGroup(var mgr, xce_group_config_t* config,
|
|||
continue;
|
||||
}
|
||||
if (m->is_group == 0) {
|
||||
FREEUP(m->u.name);
|
||||
dereference(m->u.name);
|
||||
}
|
||||
|
||||
FREEUP(m);
|
||||
|
|
@ -244,7 +244,7 @@ xce_group_t* makeGroup(var mgr, xce_group_config_t* config,
|
|||
continue;
|
||||
}
|
||||
if (m->is_group == 0) {
|
||||
FREEUP(m->u.name);
|
||||
dereference(m->u.name);
|
||||
}
|
||||
|
||||
FREEUP(m);
|
||||
|
|
|
|||
|
|
@ -255,12 +255,51 @@ static void test_nest2(void)
|
|||
destroy(mgr);
|
||||
}
|
||||
|
||||
static void test_reconfigure_same_group_members(void)
|
||||
{
|
||||
var mgr;
|
||||
xce_group_config_t gdata1 = {
|
||||
.name = "g1",
|
||||
.members = { .count = 1, .data = (char*[]) { "rshen" } }
|
||||
};
|
||||
xce_group_config_t gdata2 = {
|
||||
.name = "g1",
|
||||
.members = { .count = 1, .data = (char*[]) { "alice" } }
|
||||
};
|
||||
|
||||
xce_group_t* g = NULL;
|
||||
int rc = 0;
|
||||
|
||||
groupmgr_init(&mgr, 16, 16);
|
||||
|
||||
g = makeGroup(mgr, &gdata1, NULL);
|
||||
|
||||
TEST_ASSERT_TRUE(g != NULL);
|
||||
|
||||
/* Re-applying config for the SAME group name (e.g. a repeated config
|
||||
* push) exercises makeGroup()'s existing-group update path, which must
|
||||
* release the old members without corrupting the heap. */
|
||||
g = makeGroup(mgr, &gdata2, NULL);
|
||||
|
||||
TEST_ASSERT_TRUE(g != NULL);
|
||||
|
||||
rc = is_in_group(g, "alice");
|
||||
|
||||
TEST_ASSERT_TRUE(rc != 0);
|
||||
|
||||
rc = is_in_group(g, "rshen");
|
||||
|
||||
TEST_ASSERT_TRUE(rc == 0);
|
||||
|
||||
destroy(mgr);
|
||||
}
|
||||
|
||||
void test_group(void)
|
||||
{
|
||||
printf("\n>> group test\n\n");
|
||||
|
||||
xstring_table_init(139);
|
||||
|
||||
|
||||
RUN_TEST(test_all);
|
||||
RUN_TEST(test_empty);
|
||||
RUN_TEST(test_all_1);
|
||||
|
|
@ -271,6 +310,7 @@ void test_group(void)
|
|||
RUN_TEST(test_exclude);
|
||||
RUN_TEST(test_nest);
|
||||
RUN_TEST(test_nest2);
|
||||
RUN_TEST(test_reconfigure_same_group_members);
|
||||
|
||||
xstring_table_fini();
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue