Skip to content

Commit 7d3ba9d

Browse files
committed
Fix handling of /proc/PID/cgroups entries with colons in paths
This change ensures that the handling of the /proc/PID/cgroups file is within spec and that paths containing colons are not truncated. With this change, the entire string after the second colon is treated as the cgrpup path instead of trucating at the next (third) colon if present. Paths with colons occur when using systemd as the Kubelet cgroup-driver. Signed-off-by: Evan Lezar <[email protected]>
1 parent ac02636 commit 7d3ba9d

File tree

1 file changed

+37
-13
lines changed

1 file changed

+37
-13
lines changed

src/nvc_container.c

Lines changed: 37 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -83,24 +83,48 @@ cgroup_mount(char *line, char *prefix, const char *subsys)
8383
static char *
8484
cgroup_root(char *line, char *prefix, const char *subsys)
8585
{
86-
char *root, *substr;
87-
88-
for (int i = 0; i < 2; ++i)
89-
substr = strsep(&line, ":");
90-
root = strsep(&line, ":");
91-
92-
if (root == NULL || substr == NULL)
86+
char *heirarchy_id, *controller_list, *cgroup_path;
87+
88+
// From: https://man7.org/linux/man-pages/man7/cgroups.7.html
89+
// The lines of the /proc/{pid}/cgroup file have the following format:
90+
// hierarchy-ID:controller-list:cgroup-path
91+
// Here we attempt to parse the separate sections. If this is not
92+
// possible, we return NULL
93+
heirarchy_id = strsep(&line, ":");
94+
if (heirarchy_id == NULL) {
95+
// line contained no colons
9396
return (NULL);
94-
if (*root == '\0' || *substr == '\0')
97+
}
98+
controller_list = strsep(&line, ":");
99+
if (controller_list == NULL) {
100+
// line contains only a single colon
95101
return (NULL);
96-
if (strstr(substr, subsys) == NULL)
102+
}
103+
// Since strsep modifies the pointer *line,
104+
// the remaining string is the cgroup path
105+
cgroup_path = line;
106+
if (cgroup_path == NULL) {
97107
return (NULL);
98-
if (strlen(root) >= PATH_MAX || str_has_prefix(root, "/.."))
108+
}
109+
if (*cgroup_path == '\0' || *controller_list == '\0') {
110+
// The controller list or cgroup_path are empty strings
111+
return (NULL);
112+
}
113+
if (strstr(controller_list, subsys) == NULL) {
114+
// The desired subsystem name is not in the controller list
99115
return (NULL);
100-
if (!str_equal(prefix, "/") && str_has_prefix(root, prefix))
101-
root += strlen(prefix);
116+
}
117+
if (strlen(cgroup_path) >= PATH_MAX || str_has_prefix(cgroup_path, "/..")) {
118+
// The cgroup path is malformed: It is too long or is a relative path
119+
return (NULL);
120+
}
121+
if (!str_equal(prefix, "/") && str_has_prefix(cgroup_path, prefix)) {
122+
// Strip the supplied prefix from the cgroup path unless
123+
// it is a "/"
124+
cgroup_path += strlen(prefix);
125+
}
102126

103-
return (root);
127+
return (cgroup_path);
104128
}
105129

106130
static char *

0 commit comments

Comments
 (0)