]> git.ipfire.org Git - thirdparty/libcgroup.git/commitdiff
api.c: Fix handling of full cg_mount_table[]
authorTom Hromatka <tom.hromatka@oracle.com>
Thu, 9 Jun 2022 18:45:29 +0000 (12:45 -0600)
committerTom Hromatka <tom.hromatka@oracle.com>
Thu, 9 Jun 2022 18:46:48 +0000 (12:46 -0600)
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 <tom.hromatka@oracle.com>
Reviewed-by: Kamalesh Babulal <kamalesh.babulal@oracle.com>
src/api.c

index ab5c8ef0e642ac06e421a70be52e722c7aa2d8da..86a57e04a4b8fb0e146f6d109dc7a66fe3c249ed 100644 (file)
--- 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: