X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Fshared%2Fcgroup-util.c;h=be00b40fa2346afb2ebf43ab6847d4d61a025f6f;hb=9f26c90cb50c45d4549c4dd569917b4ac143b94d;hp=f0d0d4855b28cfc38d4d6f1cfdd9e38ad4d812bb;hpb=96cde13ace6406582688028f3df5668a172ba628;p=elogind.git diff --git a/src/shared/cgroup-util.c b/src/shared/cgroup-util.c index f0d0d4855..be00b40fa 100644 --- a/src/shared/cgroup-util.c +++ b/src/shared/cgroup-util.c @@ -37,6 +37,7 @@ #include "path-util.h" #include "strv.h" #include "unit-name.h" +#include "fileio.h" int cg_enumerate_processes(const char *controller, const char *path, FILE **_f) { char *fs; @@ -811,7 +812,7 @@ int cg_get_by_pid(const char *controller, pid_t pid, char **path) { continue; l++; - if (strncmp(l, controller, cs) != 0) + if (!strneq(l, controller, cs)) continue; if (l[cs] != ':') @@ -990,6 +991,8 @@ int cg_split_spec(const char *spec, char **controller, char **path) { assert(spec); if (*spec == '/') { + if (!path_is_safe(spec)) + return -EINVAL; if (path) { t = strdup(spec); @@ -1007,7 +1010,7 @@ int cg_split_spec(const char *spec, char **controller, char **path) { e = strchr(spec, ':'); if (!e) { - if (strchr(spec, '/') || spec[0] == 0) + if (!filename_is_safe(spec)) return -EINVAL; if (controller) { @@ -1024,29 +1027,34 @@ int cg_split_spec(const char *spec, char **controller, char **path) { return 0; } - if (e[1] != '/' || e == spec || memchr(spec, '/', e-spec)) + t = strndup(spec, e-spec); + if (!t) + return -ENOMEM; + if (!filename_is_safe(t)) { + free(t); return -EINVAL; - - if (controller) { - t = strndup(spec, e-spec); - if (!t) - return -ENOMEM; - } - if (path) { - u = strdup(e+1); - if (!u) { - free(t); - return -ENOMEM; - } + u = strdup(e+1); + if (!u) { + free(t); + return -ENOMEM; + } + if (!path_is_safe(u)) { + free(t); + free(u); + return -EINVAL; } if (controller) *controller = t; + else + free(t); if (path) *path = u; + else + free(u); return 0; } @@ -1290,3 +1298,32 @@ int cg_pid_get_unit(pid_t pid, char **unit) { int cg_pid_get_user_unit(pid_t pid, char **unit) { return cg_pid_get("/user/", pid, unit); } + +int cg_controller_from_attr(const char *attr, char **controller) { + const char *dot; + char *c; + + assert(attr); + assert(controller); + + if (!filename_is_safe(attr)) + return -EINVAL; + + dot = strchr(attr, '.'); + if (!dot) { + *controller = NULL; + return 0; + } + + c = strndup(attr, dot - attr); + if (!c) + return -ENOMEM; + + if (!filename_is_safe(c)) { + free(c); + return -EINVAL; + } + + *controller = c; + return 1; +}