]> git.ipfire.org Git - thirdparty/libcgroup.git/commitdiff
api.c: fix segfault in cgroup_populate_mount_points()
authorKamalesh Babulal <kamalesh.babulal@oracle.com>
Mon, 2 May 2022 21:40:36 +0000 (15:40 -0600)
committerTom Hromatka <tom.hromatka@oracle.com>
Mon, 2 May 2022 21:40:41 +0000 (15:40 -0600)
In cgroup_populate_mount_points(),  cgroup v1/v2 mount points get read
from /proc/mounts and populated into cg_mount_table[].  The size of
cg_mount_table[] is set to CG_CONTROLLER_MAX, that's defined as 100 and
if the system has more than CG_CONTROLLER_MAX, unique mount points, it
will segfault while processing them.  Fix this by checking, the mount
point count after processing every mount entry and bailout in case it
reaches CG_CONTROLLER_MAX.

The issue can be reproduced using, following simple bash commands on
cgroup v1:
1. sudo for i in $(seq 0 100); do sudo mkdir /name$i; done
2. sudo for i in $(seq 0 86); do sudo mount -t cgroup -o none,name=named$i
none /name$i; done
3. sudo cgget -g <controller>:<existing cgroup name>

Signed-off-by: Kamalesh Babulal <kamalesh.babulal@oracle.com>
Signed-off-by: Tom Hromatka <tom.hromatka@oracle.com>
src/api.c

index 8ba4a952f50be684c1c484801e78c2cb12b7a3fa..814660a1a064339bb093833c0de1b0a9d01d4c15 100644 (file)
--- a/src/api.c
+++ b/src/api.c
@@ -1466,6 +1466,9 @@ static int cgroup_populate_mount_points(char *controllers[CG_CONTROLLER_MAX])
                        if (ret)
                                goto err;
 
+                       if (found_mnt >= CG_CONTROLLER_MAX)
+                               break;
+
                        continue;
                }
 
@@ -1481,12 +1484,20 @@ static int cgroup_populate_mount_points(char *controllers[CG_CONTROLLER_MAX])
 
                        if (ret)
                                goto err;
+
+                       if (found_mnt >= CG_CONTROLLER_MAX)
+                               break;
                }
        }
 
        if (!found_mnt)
                ret = ECGROUPNOTMOUNTED;
 
+       if (found_mnt >= CG_CONTROLLER_MAX) {
+               cgroup_err("Mount points exceeds CG_CONTROLLER_MAX");
+               ret = ECGMAXVALUESEXCEEDED;
+       }
+
 err:
        if (proc_mount)
                fclose(proc_mount);