]> git.ipfire.org Git - thirdparty/libcgroup.git/commitdiff
api.c: fix segfault in cgroup_attach_task_pid()
authorKamalesh Babulal <kamalesh.babulal@oracle.com>
Mon, 19 Dec 2022 16:18:44 +0000 (09:18 -0700)
committerTom Hromatka <tom.hromatka@oracle.com>
Mon, 19 Dec 2022 16:18:57 +0000 (09:18 -0700)
When the user passes NULL in place of struct cgroup argument, the pid
passed as the second parameter is expected to be attached to root
hierarchies of the controllers in the case of legacy/hybrid modes and
to the root hierarchy in the case of unified mode.

The current code will segfault, while attempting to dereference a NULL
pointer, fix it by using the controller names, from cg_mount_table(),
that is already populated with the information and also remove the
controller_is_enabled check is specific to the cgroup v2 hierarchy.
With the root cgroup v2 hierarchy, all the controllers are enabled by
default, hence the check returns true always.

Reproducer:

int main(int argc, char *argv[]) {
        pid_t pid = atoi(argv[1]);
        int ret;

        ret = cgroup_init();
        if (ret) {
                printf("Failed to initialize: %s\n", cgroup_strerror(ret));
                exit(1);
        }

        ret = cgroup_attach_task_pid(NULL, pid);
        if (ret) {
                printf("Failed to attach %d to root cgroup(s): %s\n", pid, cgroup_strerror(ret));
                exit(1);
        }

        exit (0);
}

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

index d8163e6769de8f298fce4fd3f544f07e78e76b48..2354704ff739326b6d3251c76d1ef8e3c6621be7 100644 (file)
--- a/src/api.c
+++ b/src/api.c
@@ -1957,16 +1957,13 @@ int cgroup_attach_task_pid(struct cgroup *cgroup, pid_t tid)
                cgroup_warn("libcgroup is not initialized\n");
                return ECGROUPNOTINITIALIZED;
        }
+
+       /* if the cgroup is NULL, attach the task to the root cgroup. */
        if (!cgroup) {
                pthread_rwlock_rdlock(&cg_mount_table_lock);
                for (i = 0; i < CG_CONTROLLER_MAX && cg_mount_table[i].name[0] != '\0'; i++) {
-                       ret = cgroupv2_controller_enabled(cgroup->name,
-                                                         cgroup->controller[i]->name);
-                       if (ret)
-                               return ret;
-
-                       ret = cgroup_build_tasks_procs_path(path, sizeof(path), cgroup->name,
-                                                           cgroup->controller[i]->name);
+                       ret = cgroup_build_tasks_procs_path(path, sizeof(path), NULL,
+                                                           cg_mount_table[i].name);
                        if (ret)
                                return ret;