diff options
author | Lennart Poettering <lennart@poettering.net> | 2018-06-29 15:57:49 +0200 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2018-11-29 20:21:39 +0100 |
commit | 846b3bd61e1d575b0b28f73c4d15385f94bb1662 (patch) | |
tree | 6c5a149cf229086e30ee76a0c9d0a55f67ea8e3a /src/core | |
parent | cgroups: beef up DeviceAllow= syntax a bit (diff) | |
download | systemd-846b3bd61e1d575b0b28f73c4d15385f94bb1662.tar.xz systemd-846b3bd61e1d575b0b28f73c4d15385f94bb1662.zip |
stat-util: add new APIs device_path_make_{major_minor|canonical}() and device_path_parse_major_minor()
device_path_make_{major_minor|canonical) generate device node paths
given a mode_t and a dev_t. We have similar code all over the place,
let's unify this in one place. The former will generate a "/dev/char/"
or "/dev/block" path, and never go to disk. The latter then goes to disk
and resolves that path to the actual path of the device node.
device_path_parse_major_minor() reverses device_path_make_major_minor(),
also withozut going to disk.
We have similar code doing something like this at various places, let's
unify this in a single set of functions. This also allows us to teach
them special tricks, for example handling of the
/run/systemd/inaccessible/{blk|chr} device nodes, which we use for
masking device nodes, and which do not exist in /dev/char/* and
/dev/block/*
Diffstat (limited to 'src/core')
-rw-r--r-- | src/core/cgroup.c | 52 |
1 files changed, 2 insertions, 50 deletions
diff --git a/src/core/cgroup.c b/src/core/cgroup.c index dd9b992ef1..72af5e855f 100644 --- a/src/core/cgroup.c +++ b/src/core/cgroup.c @@ -408,56 +408,8 @@ static int lookup_block_device(const char *p, dev_t *ret) { return 0; } -static int shortcut_special_device_path(const char *p, struct stat *ret) { - const char *w; - mode_t mode; - dev_t devt; - int r; - - assert(p); - assert(ret); - - if (path_equal(p, "/run/systemd/inaccessible/chr")) { - *ret = (struct stat) { - .st_mode = S_IFCHR, - .st_rdev = makedev(0, 0), - }; - return 0; - } - - if (path_equal(p, "/run/systemd/inaccessible/blk")) { - *ret = (struct stat) { - .st_mode = S_IFBLK, - .st_rdev = makedev(0, 0), - }; - return 0; - } - - w = path_startswith(p, "/dev/block/"); - if (w) - mode = S_IFBLK; - else { - w = path_startswith(p, "/dev/char/"); - if (!w) - return -ENODEV; - - mode = S_IFCHR; - } - - r = parse_dev(w, &devt); - if (r < 0) - return r; - - *ret = (struct stat) { - .st_mode = mode, - .st_rdev = devt, - }; - - return 0; -} - static int whitelist_device(BPFProgram *prog, const char *path, const char *node, const char *acc) { - struct stat st; + struct stat st = {}; int r; assert(path); @@ -466,7 +418,7 @@ static int whitelist_device(BPFProgram *prog, const char *path, const char *node /* Some special handling for /dev/block/%u:%u, /dev/char/%u:%u, /run/systemd/inaccessible/chr and * /run/systemd/inaccessible/blk paths. Instead of stat()ing these we parse out the major/minor directly. This * means clients can use these path without the device node actually around */ - r = shortcut_special_device_path(node, &st); + r = device_path_parse_major_minor(node, &st.st_mode, &st.st_rdev); if (r < 0) { if (r != -ENODEV) return log_warning_errno(r, "Couldn't parse major/minor from device path '%s': %m", node); |