bus: properly shift cgroup data returned from kdbus by the container's root before parsing
This commit is contained in:
parent
4e6a9570b6
commit
751bc6ac79
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue