diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/libsystemd-bus/bus-control.c | 13 | ||||
| -rw-r--r-- | src/libsystemd-bus/bus-creds.c | 50 | ||||
| -rw-r--r-- | src/libsystemd-bus/bus-creds.h | 2 | ||||
| -rw-r--r-- | src/libsystemd-bus/bus-internal.h | 2 | ||||
| -rw-r--r-- | src/libsystemd-bus/bus-kernel.c | 10 | ||||
| -rw-r--r-- | src/libsystemd-bus/sd-bus.c | 1 | ||||
| -rw-r--r-- | src/shared/cgroup-util.c | 52 | ||||
| -rw-r--r-- | src/shared/cgroup-util.h | 1 | ||||
| -rw-r--r-- | src/test/test-cgroup-util.c | 16 | 
9 files changed, 126 insertions, 21 deletions
| diff --git a/src/libsystemd-bus/bus-control.c b/src/libsystemd-bus/bus-control.c index 55986f349b..511ca20ee3 100644 --- a/src/libsystemd-bus/bus-control.c +++ b/src/libsystemd-bus/bus-control.c @@ -33,6 +33,7 @@  #include "bus-control.h"  #include "bus-bloom.h"  #include "bus-util.h" +#include "cgroup-util.h"  _public_ int sd_bus_get_unique_name(sd_bus *bus, const char **unique) {          int r; @@ -489,6 +490,18 @@ static int bus_get_owner_kdbus(                                          goto fail;                                  } +                                if (!bus->cgroup_root) { +                                        r = cg_get_root_path(&bus->cgroup_root); +                                        if (r < 0) +                                                goto fail; +                                } + +                                c->cgroup_root = strdup(bus->cgroup_root); +                                if (!c->cgroup_root) { +                                        r = -ENOMEM; +                                        goto fail; +                                } +                                  c->mask |= m;                          }                          break; diff --git a/src/libsystemd-bus/bus-creds.c b/src/libsystemd-bus/bus-creds.c index ffd72a7a3d..b2cf687377 100644 --- a/src/libsystemd-bus/bus-creds.c +++ b/src/libsystemd-bus/bus-creds.c @@ -91,6 +91,7 @@ _public_ sd_bus_creds *sd_bus_creds_unref(sd_bus_creds *c) {                          free(c->capability);                          free(c->label);                          free(c->unique_name); +                        free(c->cgroup_root);                          free(c);                  }          } else { @@ -283,7 +284,13 @@ _public_ int sd_bus_creds_get_unit(sd_bus_creds *c, const char **ret) {          assert(c->cgroup);          if (!c->unit) { -                r = cg_path_get_unit(c->cgroup, (char**) &c->unit); +                const char *shifted; + +                r = cg_shift_path(c->cgroup, c->cgroup_root, &shifted); +                if (r < 0) +                        return r; + +                r = cg_path_get_unit(shifted, (char**) &c->unit);                  if (r < 0)                          return r;          } @@ -304,7 +311,13 @@ _public_ int sd_bus_creds_get_user_unit(sd_bus_creds *c, const char **ret) {          assert(c->cgroup);          if (!c->user_unit) { -                r = cg_path_get_user_unit(c->cgroup, (char**) &c->user_unit); +                const char *shifted; + +                r = cg_shift_path(c->cgroup, c->cgroup_root, &shifted); +                if (r < 0) +                        return r; + +                r = cg_path_get_user_unit(shifted, (char**) &c->user_unit);                  if (r < 0)                          return r;          } @@ -325,7 +338,13 @@ _public_ int sd_bus_creds_get_slice(sd_bus_creds *c, const char **ret) {          assert(c->cgroup);          if (!c->slice) { -                r = cg_path_get_slice(c->cgroup, (char**) &c->slice); +                const char *shifted; + +                r = cg_shift_path(c->cgroup, c->cgroup_root, &shifted); +                if (r < 0) +                        return r; + +                r = cg_path_get_slice(shifted, (char**) &c->slice);                  if (r < 0)                          return r;          } @@ -346,7 +365,13 @@ _public_ int sd_bus_creds_get_session(sd_bus_creds *c, const char **ret) {          assert(c->cgroup);          if (!c->session) { -                r = cg_path_get_session(c->cgroup, (char**) &c->session); +                const char *shifted; + +                r = cg_shift_path(c->cgroup, c->cgroup_root, &shifted); +                if (r < 0) +                        return r; + +                r = cg_path_get_session(shifted, (char**) &c->session);                  if (r < 0)                          return r;          } @@ -356,6 +381,9 @@ _public_ int sd_bus_creds_get_session(sd_bus_creds *c, const char **ret) {  }  _public_ int sd_bus_creds_get_owner_uid(sd_bus_creds *c, uid_t *uid) { +        const char *shifted; +        int r; +          assert_return(c, -EINVAL);          assert_return(uid, -EINVAL); @@ -364,7 +392,11 @@ _public_ int sd_bus_creds_get_owner_uid(sd_bus_creds *c, uid_t *uid) {          assert(c->cgroup); -        return cg_path_get_owner_uid(c->cgroup, uid); +        r = cg_shift_path(c->cgroup, c->cgroup_root, &shifted); +        if (r < 0) +                return r; + +        return cg_path_get_owner_uid(shifted, uid);  }  _public_ int sd_bus_creds_get_cmdline(sd_bus_creds *c, char ***cmdline) { @@ -711,6 +743,10 @@ int bus_creds_add_more(sd_bus_creds *c, uint64_t mask, pid_t pid, pid_t tid) {                  if (r < 0)                          return r; +                r = cg_get_root_path(&c->cgroup_root); +                if (r < 0) +                        return r; +                  c->mask |= missing & (SD_BUS_CREDS_CGROUP|SD_BUS_CREDS_UNIT|SD_BUS_CREDS_USER_UNIT|SD_BUS_CREDS_SLICE|SD_BUS_CREDS_SESSION|SD_BUS_CREDS_OWNER_UID);          } @@ -816,6 +852,10 @@ int bus_creds_extend_by_pid(sd_bus_creds *c, uint64_t mask, sd_bus_creds **ret)                  if (!n->cgroup)                          return -ENOMEM; +                n->cgroup_root = strdup(c->cgroup_root); +                if (!n->cgroup_root) +                        return -ENOMEM; +                  n->mask |= mask & (SD_BUS_CREDS_CGROUP|SD_BUS_CREDS_SESSION|SD_BUS_CREDS_UNIT|SD_BUS_CREDS_USER_UNIT|SD_BUS_CREDS_SLICE|SD_BUS_CREDS_OWNER_UID);          } diff --git a/src/libsystemd-bus/bus-creds.h b/src/libsystemd-bus/bus-creds.h index 089a64bfca..d8b4aca2a0 100644 --- a/src/libsystemd-bus/bus-creds.h +++ b/src/libsystemd-bus/bus-creds.h @@ -62,6 +62,8 @@ struct sd_bus_creds {          char *unique_name;          char **well_known_names; + +        char *cgroup_root;  };  sd_bus_creds* bus_creds_new(void); diff --git a/src/libsystemd-bus/bus-internal.h b/src/libsystemd-bus/bus-internal.h index 673f30eb91..e4ef6e64ec 100644 --- a/src/libsystemd-bus/bus-internal.h +++ b/src/libsystemd-bus/bus-internal.h @@ -264,6 +264,8 @@ struct sd_bus {          struct kdbus_creds fake_creds;          char *fake_label; + +        char *cgroup_root;  };  #define BUS_DEFAULT_TIMEOUT ((usec_t) (25 * USEC_PER_SEC)) diff --git a/src/libsystemd-bus/bus-kernel.c b/src/libsystemd-bus/bus-kernel.c index 19d97b7e00..8a5b210fe4 100644 --- a/src/libsystemd-bus/bus-kernel.c +++ b/src/libsystemd-bus/bus-kernel.c @@ -35,6 +35,7 @@  #include "bus-kernel.h"  #include "bus-bloom.h"  #include "bus-util.h" +#include "cgroup-util.h"  #define UNIQUE_NAME_MAX (3+DECIMAL_STR_MAX(uint64_t)) @@ -845,6 +846,15 @@ static int bus_kernel_make_message(sd_bus *bus, struct kdbus_msg *k) {                  case KDBUS_ITEM_CGROUP:                          m->creds.cgroup = d->str;                          m->creds.mask |= (SD_BUS_CREDS_CGROUP|SD_BUS_CREDS_UNIT|SD_BUS_CREDS_USER_UNIT|SD_BUS_CREDS_SLICE|SD_BUS_CREDS_SESSION|SD_BUS_CREDS_OWNER_UID) & bus->creds_mask; + +                        if (!bus->cgroup_root) { +                                r = cg_get_root_path(&bus->cgroup_root); +                                if (r < 0) +                                        goto fail; +                        } + +                        m->creds.cgroup_root = bus->cgroup_root; +                          break;                  case KDBUS_ITEM_AUDIT: diff --git a/src/libsystemd-bus/sd-bus.c b/src/libsystemd-bus/sd-bus.c index 910a5f8136..77690a07b1 100644 --- a/src/libsystemd-bus/sd-bus.c +++ b/src/libsystemd-bus/sd-bus.c @@ -142,6 +142,7 @@ static void bus_free(sd_bus *b) {          free(b->kernel);          free(b->machine);          free(b->fake_label); +        free(b->cgroup_root);          free(b->exec_path);          strv_free(b->exec_argv); diff --git a/src/shared/cgroup-util.c b/src/shared/cgroup-util.c index 74889b6363..27eee8eacd 100644 --- a/src/shared/cgroup-util.c +++ b/src/shared/cgroup-util.c @@ -1082,42 +1082,62 @@ int cg_get_root_path(char **path) {          return 0;  } -int cg_pid_get_path_shifted(pid_t pid, const char *root, char **cgroup) { -        _cleanup_free_ char *cg_root = NULL; -        char *cg_process, *p; +int cg_shift_path(const char *cgroup, const char *root, const char **shifted) { +        _cleanup_free_ char *rt = NULL; +        char *p;          int r; -        assert(pid >= 0);          assert(cgroup); +        assert(shifted);          if (!root) {                  /* If the root was specified let's use that, otherwise                   * let's determine it from PID 1 */ -                r = cg_get_root_path(&cg_root); +                r = cg_get_root_path(&rt);                  if (r < 0)                          return r; -                root = cg_root; +                root = rt;          } -        r = cg_pid_get_path(SYSTEMD_CGROUP_CONTROLLER, pid, &cg_process); +        p = path_startswith(cgroup, root); +        if (p) +                *shifted = p - 1; +        else +                *shifted = cgroup; + +        return 0; +} + +int cg_pid_get_path_shifted(pid_t pid, const char *root, char **cgroup) { +        _cleanup_free_ char *raw = NULL; +        const char *c; +        int r; + +        assert(pid >= 0); +        assert(cgroup); + +        r = cg_pid_get_path(SYSTEMD_CGROUP_CONTROLLER, pid, &raw);          if (r < 0)                  return r; -        p = path_startswith(cg_process, root); -        if (p) { -                char *c; +        r = cg_shift_path(raw, root, &c); +        if (r < 0) +                return r; -                c = strdup(p - 1); -                free(cg_process); +        if (c == raw) { +                *cgroup = raw; +                raw = NULL; +        } else { +                char *n; -                if (!c) +                n = strdup(c); +                if (!n)                          return -ENOMEM; -                *cgroup = c; -        } else -                *cgroup = cg_process; +                *cgroup = n; +        }          return 0;  } diff --git a/src/shared/cgroup-util.h b/src/shared/cgroup-util.h index 3e6a3f6abe..743d902e2d 100644 --- a/src/shared/cgroup-util.h +++ b/src/shared/cgroup-util.h @@ -103,6 +103,7 @@ int cg_path_get_user_unit(const char *path, char **unit);  int cg_path_get_machine_name(const char *path, char **machine);  int cg_path_get_slice(const char *path, char **slice); +int cg_shift_path(const char *cgroup, const char *cached_root, const char **shifted);  int cg_pid_get_path_shifted(pid_t pid, const char *cached_root, char **cgroup);  int cg_pid_get_session(pid_t pid, char **session); diff --git a/src/test/test-cgroup-util.c b/src/test/test-cgroup-util.c index f94f213f54..12dcc17ddb 100644 --- a/src/test/test-cgroup-util.c +++ b/src/test/test-cgroup-util.c @@ -246,6 +246,21 @@ static void test_slice_to_path(void) {          test_slice_to_path_one("a-b-c-d-e.slice", "a.slice/a-b.slice/a-b-c.slice/a-b-c-d.slice/a-b-c-d-e.slice", 0);  } +static void test_shift_path_one(const char *raw, const char *root, const char *shifted) { +        const char *s = NULL; + +        assert_se(cg_shift_path(raw, root, &s) >= 0); +        assert_se(streq(s, shifted)); +} + +static void test_shift_path(void) { + +        test_shift_path_one("/foobar/waldo", "/", "/foobar/waldo"); +        test_shift_path_one("/foobar/waldo", "", "/foobar/waldo"); +        test_shift_path_one("/foobar/waldo", "/foobar", "/waldo"); +        test_shift_path_one("/foobar/waldo", "/fuckfuck", "/foobar/waldo"); +} +  int main(void) {          test_path_decode_unit();          test_path_get_unit(); @@ -258,6 +273,7 @@ int main(void) {          TEST_REQ_RUNNING_SYSTEMD(test_escape());          test_controller_is_valid();          test_slice_to_path(); +        test_shift_path();          return 0;  } | 
