From 50de38f821f5ea367f9a92a802a45659dc45614d Mon Sep 17 00:00:00 2001 From: Tom Hromatka Date: Thu, 9 Jun 2022 12:45:29 -0600 Subject: [PATCH] api.c: Fix handling of full cg_mount_table[] Commit 9ce90c7edd28 ("api.c: fix segfault in cgroup_populate_mount_points()") added logic to handle the case when there are 100+ cgroup mounts and not overflow the cg_mount_table[]. But elsewhere in the libcgroup code, it's expected that the last entry in the cg_mount_table[] has a null name entry. When the cg_mount_table[] is full, make the name of the last entry null so that loops know to exit. Also, add a couple bail out points in cgroup_populate_mount_points() to ensure that we don't write beyond the end of the table. Depending upon the order in which the tests are run, this failure can manifest itself as follows: $ cat tests/ftests/ftests-nocontainer.sh.log free(): invalid pointer ./ftests-nocontainer.sh: line 18: 199390 Aborted (core dumped) ./ftests.py -l 10 -L "$START_DIR/ftests-nocontainer.py.log" --no-container -n Libcg"$RANDOM" FAIL ftests-nocontainer.sh (exit status: 134) Fixes: 9ce90c7edd28 ("api.c: fix segfault in cgroup_populate_mount_points()") Signed-off-by: Tom Hromatka Reviewed-by: Kamalesh Babulal --- src/api.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/api.c b/src/api.c index ab5c8ef0..86a57e04 100644 --- a/src/api.c +++ b/src/api.c @@ -1172,6 +1172,9 @@ STATIC int cgroup_process_v1_mnt(char *controllers[], struct mntent *ent, cgroup_cg_mount_table_append(controllers[i], ent->mnt_dir, CGROUP_V1, mnt_tbl_idx, ent->mnt_opts, shared_mnt); + + if ((*mnt_tbl_idx) >= CG_CONTROLLER_MAX) + goto out; } /* @@ -1325,6 +1328,9 @@ STATIC int cgroup_process_v2_mnt(struct mntent *ent, int *mnt_tbl_idx) cgroup_cg_mount_table_append(controller, ent->mnt_dir, CGROUP_V2, mnt_tbl_idx, controller, shared_mnt); + + if ((*mnt_tbl_idx) >= CG_CONTROLLER_MAX) + goto out; } while ((controller = strtok_r(NULL, " ", &stok_buff))); out: @@ -1498,6 +1504,11 @@ static int cgroup_populate_mount_points(char *controllers[CG_CONTROLLER_MAX]) if (found_mnt >= CG_CONTROLLER_MAX) { cgroup_err("Mount points exceeds CG_CONTROLLER_MAX"); ret = ECGMAXVALUESEXCEEDED; + /* + * There are loops in the libcgroup codebase that expect there + * to be a null name entry at the end of the cg_mount_table[]. + */ + cg_mount_table[CG_CONTROLLER_MAX - 1].name[0] = '\0'; } err: -- 2.47.2