From 517587ef58a7dfd0bbc597963fd9a99ab4099420 Mon Sep 17 00:00:00 2001 From: Christian Brauner Date: Sun, 30 Oct 2016 14:44:33 +0100 Subject: [PATCH] cgfs: explicitly check for NULL Somehow this implementation of a cgroupfs backend decided to use the hierarchy numbers it detects in /proc/cgroups and /proc/self/cgroups as indices for the hierarchy struct. Controller numbering usually starts at 1 but may start at 0 if: a) the controller is not mounted on a cgroups v1 hierarchy; b) the controller is bound to the cgroups v2 single unified hierarchy; or c) the controller is disabled To avoid having to rework our fallback backend significantly, we should explicitly check for each controller if hierarchy[i] != NULL. Signed-off-by: Christian Brauner --- src/lxc/cgroups/cgfs.c | 28 ++++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/src/lxc/cgroups/cgfs.c b/src/lxc/cgroups/cgfs.c index a30ad9132..84992009a 100644 --- a/src/lxc/cgroups/cgfs.c +++ b/src/lxc/cgroups/cgfs.c @@ -512,7 +512,7 @@ static bool find_hierarchy_mountpts( struct cgroup_meta_data *meta_data, char ** goto out; h = NULL; - for (k = 1; k <= meta_data->maximum_hierarchy; k++) { + for (k = 0; k <= meta_data->maximum_hierarchy; k++) { if (meta_data->hierarchies[k] && meta_data->hierarchies[k]->subsystems[0] && lxc_string_in_array(meta_data->hierarchies[k]->subsystems[0], (const char **)subsystems)) { @@ -654,6 +654,8 @@ static struct cgroup_hierarchy *lxc_cgroup_find_hierarchy(struct cgroup_meta_dat size_t i; for (i = 0; i <= meta_data->maximum_hierarchy; i++) { struct cgroup_hierarchy *h = meta_data->hierarchies[i]; + if (!h) + continue; if (h && lxc_string_in_array(subsystem, (const char **)h->subsystems)) return h; } @@ -892,6 +894,8 @@ static struct cgroup_process_info *lxc_cgroupfs_create(const char *name, const c /* find mount points we can use */ for (info_ptr = base_info; info_ptr; info_ptr = info_ptr->next) { h = info_ptr->hierarchy; + if (!h) + continue; mp = lxc_cgroup_find_mount_point(h, info_ptr->cgroup_path, true); if (!mp) { ERROR("Could not find writable mount point for cgroup hierarchy %d while trying to create cgroup.", h->index); @@ -981,6 +985,9 @@ static struct cgroup_process_info *lxc_cgroupfs_create(const char *name, const c for (i = 0, info_ptr = base_info; info_ptr; info_ptr = info_ptr->next, i++) { char *parts2[3]; + if (!info_ptr->hierarchy) + continue; + if (lxc_string_in_array("ns", (const char **)info_ptr->hierarchy->subsystems)) continue; current_entire_path = NULL; @@ -1079,6 +1086,8 @@ skip: /* we're done, now update the paths */ for (i = 0, info_ptr = base_info; info_ptr; info_ptr = info_ptr->next, i++) { + if (!info_ptr->hierarchy) + continue; /* ignore legacy 'ns' subsystem here, lxc_cgroup_create_legacy * will take care of it * Since we do a continue in above loop, new_cgroup_paths[i] is @@ -1116,6 +1125,9 @@ static int lxc_cgroup_create_legacy(struct cgroup_process_info *base_info, const int r; for (info_ptr = base_info; info_ptr; info_ptr = info_ptr->next) { + if (!info_ptr->hierarchy) + continue; + if (!lxc_string_in_array("ns", (const char **)info_ptr->hierarchy->subsystems)) continue; /* @@ -1200,6 +1212,9 @@ static int lxc_cgroupfs_enter(struct cgroup_process_info *info, pid_t pid, bool snprintf(pid_buf, 32, "%lu", (unsigned long)pid); for (info_ptr = info; info_ptr; info_ptr = info_ptr->next) { + if (!info_ptr->hierarchy) + continue; + char *cgroup_path = (enter_sub && info_ptr->cgroup_path_sub) ? info_ptr->cgroup_path_sub : info_ptr->cgroup_path; @@ -1444,6 +1459,10 @@ static bool cgroupfs_mount_cgroup(void *hdata, const char *root, int type) for (info = base_info; info; info = info->next) { size_t subsystem_count, i; struct cgroup_mount_point *mp = info->designated_mount_point; + + if (!info->hierarchy) + continue; + if (!mountpoint_is_accessible(mp)) mp = lxc_cgroup_find_mount_point(info->hierarchy, info->cgroup_path, true); @@ -1930,6 +1949,8 @@ find_info_for_subsystem(struct cgroup_process_info *info, const char *subsystem) struct cgroup_process_info *info_ptr; for (info_ptr = info; info_ptr; info_ptr = info_ptr->next) { struct cgroup_hierarchy *h = info_ptr->hierarchy; + if (!h) + continue; if (lxc_string_in_array(subsystem, (const char **)h->subsystems)) return info_ptr; } @@ -2426,7 +2447,7 @@ static bool cgfs_escape(void *hdata) if (!md) return false; - for (i = 1; i <= md->maximum_hierarchy; i++) { + for (i = 0; i <= md->maximum_hierarchy; i++) { struct cgroup_hierarchy *h = md->hierarchies[i]; struct cgroup_mount_point *mp; char *tasks; @@ -2636,6 +2657,9 @@ static bool cgfs_chown(void *hdata, struct lxc_conf *conf) return false; for (info_ptr = d->info; info_ptr; info_ptr = info_ptr->next) { + if (!info_ptr->hierarchy) + continue; + if (!info_ptr->designated_mount_point) { info_ptr->designated_mount_point = lxc_cgroup_find_mount_point(info_ptr->hierarchy, info_ptr->cgroup_path, true); if (!info_ptr->designated_mount_point) { -- 2.47.2