diff --git a/src/basic/cgroup-util.c b/src/basic/cgroup-util.c index 24a59dd7f5..4c82552904 100644 --- a/src/basic/cgroup-util.c +++ b/src/basic/cgroup-util.c @@ -686,17 +686,17 @@ int cg_get_xattr_malloc(const char *path, const char *name, char **ret) { } int cg_get_xattr_bool(const char *path, const char *name) { - _cleanup_free_ char *val = NULL; + _cleanup_free_ char *fs = NULL; int r; assert(path); assert(name); - r = cg_get_xattr_malloc(path, name, &val); + r = cg_get_path(SYSTEMD_CGROUP_CONTROLLER, path, NULL, &fs); if (r < 0) return r; - return parse_boolean(val); + return getxattr_at_bool(AT_FDCWD, fs, name, /* flags= */ 0); } int cg_remove_xattr(const char *path, const char *name) { @@ -2263,17 +2263,27 @@ int cg_is_delegated(const char *path) { assert(path); r = cg_get_xattr_bool(path, "trusted.delegate"); - if (ERRNO_IS_NEG_XATTR_ABSENT(r)) { - /* If the trusted xattr isn't set (preferred), then check the - * untrusted one. Under the assumption that whoever is trusted - * enough to own the cgroup, is also trusted enough to decide - * if it is delegated or not this should be safe. */ - r = cg_get_xattr_bool(path, "user.delegate"); - if (ERRNO_IS_NEG_XATTR_ABSENT(r)) - return false; - } + if (!ERRNO_IS_NEG_XATTR_ABSENT(r)) + return r; - return r; + /* If the trusted xattr isn't set (preferred), then check the untrusted one. Under the assumption + * that whoever is trusted enough to own the cgroup, is also trusted enough to decide if it is + * delegated or not this should be safe. */ + r = cg_get_xattr_bool(path, "user.delegate"); + return ERRNO_IS_NEG_XATTR_ABSENT(r) ? false : r; +} + +int cg_is_delegated_fd(int fd) { + int r; + + assert(fd >= 0); + + r = getxattr_at_bool(fd, /* path= */ NULL, "trusted.delegate", /* flags= */ 0); + if (!ERRNO_IS_NEG_XATTR_ABSENT(r)) + return r; + + r = getxattr_at_bool(fd, /* path= */ NULL, "user.delegate", /* flags= */ 0); + return ERRNO_IS_NEG_XATTR_ABSENT(r) ? false : r; } int cg_has_coredump_receive(const char *path) { diff --git a/src/basic/cgroup-util.h b/src/basic/cgroup-util.h index 1022caf23c..bfb3830520 100644 --- a/src/basic/cgroup-util.h +++ b/src/basic/cgroup-util.h @@ -211,6 +211,7 @@ int cg_rmdir(const char *controller, const char *path); int cg_is_threaded(const char *path); int cg_is_delegated(const char *path); +int cg_is_delegated_fd(int fd); int cg_has_coredump_receive(const char *path); diff --git a/src/basic/os-util.c b/src/basic/os-util.c index 86318a8263..dbd067fd44 100644 --- a/src/basic/os-util.c +++ b/src/basic/os-util.c @@ -92,8 +92,7 @@ static int extension_release_strict_xattr_value(int extension_release_fd, const assert(filename); /* No xattr or cannot parse it? Then skip this. */ - _cleanup_free_ char *extension_release_xattr = NULL; - r = fgetxattr_malloc(extension_release_fd, "user.extension-release.strict", &extension_release_xattr); + r = getxattr_at_bool(extension_release_fd, /* path= */ NULL, "user.extension-release.strict", /* flags= */ 0); if (ERRNO_IS_NEG_XATTR_ABSENT(r)) return log_debug_errno(r, "%s/%s does not have user.extension-release.strict xattr, ignoring.", extension_release_dir_path, filename); @@ -102,11 +101,6 @@ static int extension_release_strict_xattr_value(int extension_release_fd, const extension_release_dir_path, filename); /* Explicitly set to request strict matching? Skip it. */ - r = parse_boolean(extension_release_xattr); - if (r < 0) - return log_debug_errno(r, - "%s/%s: Failed to parse 'user.extension-release.strict' extended attribute from file, ignoring: %m", - extension_release_dir_path, filename); if (r > 0) { log_debug("%s/%s: 'user.extension-release.strict' attribute is true, ignoring file.", extension_release_dir_path, filename); diff --git a/src/basic/xattr-util.c b/src/basic/xattr-util.c index 700fdf44b6..d2daf87ec9 100644 --- a/src/basic/xattr-util.c +++ b/src/basic/xattr-util.c @@ -12,6 +12,7 @@ #include "fd-util.h" #include "macro.h" #include "missing_syscall.h" +#include "parse-util.h" #include "sparse-endian.h" #include "stat-util.h" #include "stdio-util.h" @@ -118,6 +119,20 @@ int getxattr_at_malloc( } } +int getxattr_at_bool(int fd, const char *path, const char *name, int flags) { + _cleanup_free_ char *v = NULL; + int r; + + r = getxattr_at_malloc(fd, path, name, flags, &v); + if (r < 0) + return r; + + if (memchr(v, 0, r)) /* Refuse embedded NUL byte */ + return -EINVAL; + + return parse_boolean(v); +} + static int parse_crtime(le64_t le, usec_t *usec) { uint64_t u; diff --git a/src/basic/xattr-util.h b/src/basic/xattr-util.h index 649a842fe2..19ee3e1c45 100644 --- a/src/basic/xattr-util.h +++ b/src/basic/xattr-util.h @@ -18,6 +18,8 @@ static inline int fgetxattr_malloc(int fd, const char *name, char **ret) { return getxattr_at_malloc(fd, NULL, name, AT_EMPTY_PATH, ret); } +int getxattr_at_bool(int fd, const char *path, const char *name, int flags); + int fd_setcrtime(int fd, usec_t usec); int fd_getcrtime_at(int fd, const char *name, int flags, usec_t *ret); diff --git a/src/random-seed/random-seed.c b/src/random-seed/random-seed.c index 12eb1f7eac..bad18ada3b 100644 --- a/src/random-seed/random-seed.c +++ b/src/random-seed/random-seed.c @@ -49,7 +49,6 @@ typedef enum CreditEntropy { static SeedAction arg_action = _ACTION_INVALID; static CreditEntropy may_credit(int seed_fd) { - _cleanup_free_ char *creditable = NULL; const char *e; int r; @@ -76,7 +75,7 @@ static CreditEntropy may_credit(int seed_fd) { } /* Determine if the file is marked as creditable */ - r = fgetxattr_malloc(seed_fd, "user.random-seed-creditable", &creditable); + r = getxattr_at_bool(seed_fd, /* path= */ NULL, "user.random-seed-creditable", /* flags= */ 0); if (r < 0) { if (ERRNO_IS_XATTR_ABSENT(r)) log_debug_errno(r, "Seed file is not marked as creditable, not crediting."); @@ -85,14 +84,8 @@ static CreditEntropy may_credit(int seed_fd) { return CREDIT_ENTROPY_NO_WAY; } - - r = parse_boolean(creditable); - if (r <= 0) { - if (r < 0) - log_warning_errno(r, "Failed to parse user.random-seed-creditable extended attribute, ignoring: %s", creditable); - else - log_debug("Seed file is marked as not creditable, not crediting."); - + if (r == 0) { + log_debug("Seed file is marked as not creditable, not crediting."); return CREDIT_ENTROPY_NO_WAY; } diff --git a/src/shared/cgroup-show.c b/src/shared/cgroup-show.c index b77bab0215..c2ee1c5aef 100644 --- a/src/shared/cgroup-show.c +++ b/src/shared/cgroup-show.c @@ -140,13 +140,11 @@ static int show_cgroup_name( bool delegate; int r; - if (FLAGS_SET(flags, OUTPUT_CGROUP_XATTRS) || FLAGS_SET(flags, OUTPUT_CGROUP_ID)) { - fd = open(path, O_PATH|O_CLOEXEC|O_NOFOLLOW|O_DIRECTORY, 0); - if (fd < 0) - log_debug_errno(errno, "Failed to open cgroup '%s', ignoring: %m", path); - } + fd = open(path, O_PATH|O_CLOEXEC|O_NOFOLLOW|O_DIRECTORY, 0); + if (fd < 0) + return log_debug_errno(errno, "Failed to open cgroup '%s', ignoring: %m", path); - r = cg_is_delegated(fd >= 0 ? FORMAT_PROC_FD_PATH(fd) : path); + r = cg_is_delegated_fd(fd); if (r < 0) log_debug_errno(r, "Failed to check if cgroup is delegated, ignoring: %m"); delegate = r > 0; @@ -156,11 +154,11 @@ static int show_cgroup_name( int mnt_id = -1; if (name_to_handle_at( - fd < 0 ? AT_FDCWD : fd, - fd < 0 ? path : "", + fd, + "", &fh.file_handle, &mnt_id, - fd < 0 ? 0 : AT_EMPTY_PATH) < 0) + AT_EMPTY_PATH) < 0) log_debug_errno(errno, "Failed to determine cgroup ID of %s, ignoring: %m", path); else cgroupid = CG_FILE_HANDLE_CGROUPID(fh); @@ -187,7 +185,7 @@ static int show_cgroup_name( printf("\n"); - if (FLAGS_SET(flags, OUTPUT_CGROUP_XATTRS) && fd >= 0) { + if (FLAGS_SET(flags, OUTPUT_CGROUP_XATTRS)) { _cleanup_free_ char *nl = NULL; r = flistxattr_malloc(fd, &nl); @@ -266,7 +264,7 @@ int show_cgroup_by_path( continue; if (!shown_pids) { - show_cgroup_one_by_path(path, prefix, n_columns, true, flags); + (void) show_cgroup_one_by_path(path, prefix, n_columns, true, flags); shown_pids = true; } @@ -292,7 +290,7 @@ int show_cgroup_by_path( return r; if (!shown_pids) - show_cgroup_one_by_path(path, prefix, n_columns, !!last, flags); + (void) show_cgroup_one_by_path(path, prefix, n_columns, !!last, flags); if (last) { r = show_cgroup_name(last, prefix, SPECIAL_GLYPH_TREE_RIGHT, flags);