Previously trying to create an event group with no name (=NULL) caused a segfault. Fix this and test it in the validation suite.
Signed-off-by: Matias Elo <[email protected]> --- platform/linux-generic/odp_schedule.c | 26 +++++++++++++++------- platform/linux-generic/odp_schedule_sp.c | 11 +++++++-- .../validation/api/scheduler/scheduler.c | 9 +++++++- 3 files changed, 35 insertions(+), 11 deletions(-) diff --git a/platform/linux-generic/odp_schedule.c b/platform/linux-generic/odp_schedule.c index 78982d9..e24eec3 100644 --- a/platform/linux-generic/odp_schedule.c +++ b/platform/linux-generic/odp_schedule.c @@ -181,6 +181,7 @@ typedef struct { struct { char name[ODP_SCHED_GROUP_NAME_LEN]; odp_thrmask_t mask; + int allocated; } sched_grp[NUM_SCHED_GRPS]; struct { @@ -869,11 +870,19 @@ static odp_schedule_group_t schedule_group_create(const char *name, odp_spinlock_lock(&sched->grp_lock); for (i = SCHED_GROUP_NAMED; i < NUM_SCHED_GRPS; i++) { - if (sched->sched_grp[i].name[0] == 0) { - strncpy(sched->sched_grp[i].name, name, - ODP_SCHED_GROUP_NAME_LEN - 1); + if (!sched->sched_grp[i].allocated) { + char *grp_name = sched->sched_grp[i].name; + + if (name == NULL) { + grp_name[0] = 0; + } else { + strncpy(grp_name, name, + ODP_SCHED_GROUP_NAME_LEN - 1); + grp_name[ODP_SCHED_GROUP_NAME_LEN - 1] = 0; + } odp_thrmask_copy(&sched->sched_grp[i].mask, mask); group = (odp_schedule_group_t)i; + sched->sched_grp[i].allocated = 1; break; } } @@ -889,10 +898,11 @@ static int schedule_group_destroy(odp_schedule_group_t group) odp_spinlock_lock(&sched->grp_lock); if (group < NUM_SCHED_GRPS && group >= SCHED_GROUP_NAMED && - sched->sched_grp[group].name[0] != 0) { + sched->sched_grp[group].allocated) { odp_thrmask_zero(&sched->sched_grp[group].mask); memset(sched->sched_grp[group].name, 0, ODP_SCHED_GROUP_NAME_LEN); + sched->sched_grp[group].allocated = 0; ret = 0; } else { ret = -1; @@ -928,7 +938,7 @@ static int schedule_group_join(odp_schedule_group_t group, odp_spinlock_lock(&sched->grp_lock); if (group < NUM_SCHED_GRPS && group >= SCHED_GROUP_NAMED && - sched->sched_grp[group].name[0] != 0) { + sched->sched_grp[group].allocated) { odp_thrmask_or(&sched->sched_grp[group].mask, &sched->sched_grp[group].mask, mask); @@ -949,7 +959,7 @@ static int schedule_group_leave(odp_schedule_group_t group, odp_spinlock_lock(&sched->grp_lock); if (group < NUM_SCHED_GRPS && group >= SCHED_GROUP_NAMED && - sched->sched_grp[group].name[0] != 0) { + sched->sched_grp[group].allocated) { odp_thrmask_t leavemask; odp_thrmask_xor(&leavemask, mask, &sched->mask_all); @@ -973,7 +983,7 @@ static int schedule_group_thrmask(odp_schedule_group_t group, odp_spinlock_lock(&sched->grp_lock); if (group < NUM_SCHED_GRPS && group >= SCHED_GROUP_NAMED && - sched->sched_grp[group].name[0] != 0) { + sched->sched_grp[group].allocated) { *thrmask = sched->sched_grp[group].mask; ret = 0; } else { @@ -992,7 +1002,7 @@ static int schedule_group_info(odp_schedule_group_t group, odp_spinlock_lock(&sched->grp_lock); if (group < NUM_SCHED_GRPS && group >= SCHED_GROUP_NAMED && - sched->sched_grp[group].name[0] != 0) { + sched->sched_grp[group].allocated) { info->name = sched->sched_grp[group].name; info->thrmask = sched->sched_grp[group].mask; ret = 0; diff --git a/platform/linux-generic/odp_schedule_sp.c b/platform/linux-generic/odp_schedule_sp.c index 2e28aa4..b7b1de4 100644 --- a/platform/linux-generic/odp_schedule_sp.c +++ b/platform/linux-generic/odp_schedule_sp.c @@ -501,8 +501,15 @@ static odp_schedule_group_t schedule_group_create(const char *name, for (i = NUM_STATIC_GROUP; i < NUM_GROUP; i++) { if (!sched_group->s.group[i].allocated) { - strncpy(sched_group->s.group[i].name, name, - ODP_SCHED_GROUP_NAME_LEN); + char *grp_name = sched_group->s.group[i].name; + + if (name == NULL) { + grp_name[0] = 0; + } else { + strncpy(grp_name, name, + ODP_SCHED_GROUP_NAME_LEN - 1); + grp_name[ODP_SCHED_GROUP_NAME_LEN - 1] = 0; + } odp_thrmask_copy(&sched_group->s.group[i].mask, thrmask); sched_group->s.group[i].allocated = 1; diff --git a/test/common_plat/validation/api/scheduler/scheduler.c b/test/common_plat/validation/api/scheduler/scheduler.c index 919cfb6..dd3f6cd 100644 --- a/test/common_plat/validation/api/scheduler/scheduler.c +++ b/test/common_plat/validation/api/scheduler/scheduler.c @@ -273,7 +273,7 @@ void scheduler_test_groups(void) ODP_SCHED_SYNC_ORDERED}; int thr_id = odp_thread_id(); odp_thrmask_t zeromask, mymask, testmask; - odp_schedule_group_t mygrp1, mygrp2, lookup; + odp_schedule_group_t mygrp1, mygrp2, null_grp, lookup; odp_schedule_group_info_t info; odp_thrmask_zero(&zeromask); @@ -327,6 +327,10 @@ void scheduler_test_groups(void) CU_ASSERT(rc == 0); CU_ASSERT(!odp_thrmask_isset(&testmask, thr_id)); + /* Create group with no name */ + null_grp = odp_schedule_group_create(NULL, &zeromask); + CU_ASSERT(null_grp != ODP_SCHED_GROUP_INVALID); + /* We shouldn't be able to find our second group before creating it */ lookup = odp_schedule_group_lookup("Test Group 2"); CU_ASSERT(lookup == ODP_SCHED_GROUP_INVALID); @@ -338,6 +342,9 @@ void scheduler_test_groups(void) lookup = odp_schedule_group_lookup("Test Group 2"); CU_ASSERT(lookup == mygrp2); + /* Destroy group with no name */ + CU_ASSERT_FATAL(odp_schedule_group_destroy(null_grp) == 0); + /* Verify we're not part of it */ rc = odp_schedule_group_thrmask(mygrp2, &testmask); CU_ASSERT(rc == 0); -- 2.7.4
