From 00675c363ffdb0144873ae24ce555556aedcab0d Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 10 Oct 2022 11:06:56 +0200 Subject: [PATCH] tree-wide: add ERRNO_IS_XATTR_ABSENT() helper We check the same list of error codes on various xattr operations, and we should on some more. Add a common helper for this purpose. --- src/basic/errno-util.h | 7 +++++++ src/basic/os-util.c | 2 +- src/core/cgroup.c | 4 ++-- src/core/execute.c | 2 +- src/home/homework-luks.c | 2 +- src/home/user-record-util.c | 2 +- src/oom/oomd-util.c | 7 ++++--- src/portable/portable.c | 2 +- src/random-seed/random-seed.c | 4 ++-- src/shared/cgroup-show.c | 4 ++-- src/shared/chown-recursive.c | 2 +- src/shared/dissect-image.c | 4 ++-- src/test/test-chown-rec.c | 6 ++---- src/test/test-xattr-util.c | 2 +- src/udev/udevd.c | 2 +- 15 files changed, 29 insertions(+), 23 deletions(-) diff --git a/src/basic/errno-util.h b/src/basic/errno-util.h index 648de50eb49..a14167f5267 100644 --- a/src/basic/errno-util.h +++ b/src/basic/errno-util.h @@ -153,3 +153,10 @@ static inline bool ERRNO_IS_DEVICE_ABSENT(int r) { ENXIO, ENOENT); } + +/* Quite often we want to handle cases where the backing FS doesn't support extended attributes at all and + * where it simply doesn't have the requested xattr the same way */ +static inline bool ERRNO_IS_XATTR_ABSENT(int r) { + return abs(r) == ENODATA || + ERRNO_IS_NOT_SUPPORTED(r); +} diff --git a/src/basic/os-util.c b/src/basic/os-util.c index 96ba6832768..04e146f648f 100644 --- a/src/basic/os-util.c +++ b/src/basic/os-util.c @@ -126,7 +126,7 @@ int open_extension_release(const char *root, const char *extension, char **ret_p /* No xattr or cannot parse it? Then skip this. */ _cleanup_free_ char *extension_release_xattr = NULL; k = fgetxattr_malloc(extension_release_fd, "user.extension-release.strict", &extension_release_xattr); - if (k < 0 && !ERRNO_IS_NOT_SUPPORTED(k) && k != -ENODATA) + if (k < 0 && !ERRNO_IS_XATTR_ABSENT(k)) log_debug_errno(k, "%s/%s: Failed to read 'user.extension-release.strict' extended attribute from file: %m", extension_release_dir_path, de->d_name); diff --git a/src/core/cgroup.c b/src/core/cgroup.c index 6d40faa48b0..cc18da1f223 100644 --- a/src/core/cgroup.c +++ b/src/core/cgroup.c @@ -752,7 +752,7 @@ static void unit_remove_xattr_graceful(Unit *u, const char *cgroup_path, const c } r = cg_remove_xattr(SYSTEMD_CGROUP_CONTROLLER, cgroup_path, name); - if (r < 0 && r != -ENODATA) + if (r < 0 && !ERRNO_IS_XATTR_ABSENT(r)) log_unit_debug_errno(u, r, "Failed to remove '%s' xattr flag on control group %s, ignoring: %m", name, empty_to_root(cgroup_path)); } @@ -3089,7 +3089,7 @@ int unit_check_oomd_kill(Unit *u) { return 0; r = cg_get_xattr_malloc(SYSTEMD_CGROUP_CONTROLLER, u->cgroup_path, "user.oomd_ooms", &value); - if (r < 0 && r != -ENODATA) + if (r < 0 && !ERRNO_IS_XATTR_ABSENT(r)) return r; if (!isempty(value)) { diff --git a/src/core/execute.c b/src/core/execute.c index 6a4e1e09547..734111bc759 100644 --- a/src/core/execute.c +++ b/src/core/execute.c @@ -3254,7 +3254,7 @@ static int setup_smack( _cleanup_free_ char *exec_label = NULL; r = mac_smack_read_fd(executable_fd, SMACK_ATTR_EXEC, &exec_label); - if (r < 0 && !IN_SET(r, -ENODATA, -EOPNOTSUPP)) + if (r < 0 && !ERRNO_IS_XATTR_ABSENT(r)) return r; r = mac_smack_apply_pid(0, exec_label ? : manager->default_smack_process_label); diff --git a/src/home/homework-luks.c b/src/home/homework-luks.c index 858d9dda194..d0fb2d91af6 100644 --- a/src/home/homework-luks.c +++ b/src/home/homework-luks.c @@ -96,7 +96,7 @@ int run_mark_dirty(int fd, bool b) { return log_debug_errno(r, "Failed to synchronize image before marking it clean: %m"); ret = fremovexattr(fd, "user.home-dirty"); - if (ret < 0 && errno != ENODATA) + if (ret < 0 && !ERRNO_IS_XATTR_ABSENT(errno)) return log_debug_errno(errno, "Could not mark home directory as clean: %m"); } diff --git a/src/home/user-record-util.c b/src/home/user-record-util.c index 9d85f2abfa5..08f1764d118 100644 --- a/src/home/user-record-util.c +++ b/src/home/user-record-util.c @@ -501,7 +501,7 @@ int user_record_test_image_path(UserRecord *h) { n = getxattr(ip, "user.home-dirty", x, sizeof(x)); if (n < 0) { - if (errno != ENODATA) + if (!ERRNO_IS_XATTR_ABSENT(errno)) log_debug_errno(errno, "Unable to read dirty xattr off image file, ignoring: %m"); } else if (n == 1 && x[0] == '1') diff --git a/src/oom/oomd-util.c b/src/oom/oomd-util.c index d31d5ca6235..1fc81d18434 100644 --- a/src/oom/oomd-util.c +++ b/src/oom/oomd-util.c @@ -3,6 +3,7 @@ #include #include +#include "errno-util.h" #include "fd-util.h" #include "fileio.h" #include "format-util.h" @@ -39,7 +40,7 @@ static int increment_oomd_xattr(const char *path, const char *xattr, uint64_t nu assert(xattr); r = cg_get_xattr_malloc(SYSTEMD_CGROUP_CONTROLLER, path, xattr, &value); - if (r < 0 && r != -ENODATA) + if (r < 0 && !ERRNO_IS_XATTR_ABSENT(r)) return r; if (!isempty(value)) { @@ -169,14 +170,14 @@ int oomd_fetch_cgroup_oom_preference(OomdCGroupContext *ctx, const char *prefix) r = cg_get_xattr_bool(SYSTEMD_CGROUP_CONTROLLER, ctx->path, "user.oomd_avoid"); if (r == -ENOMEM) return log_oom_debug(); - if (r < 0 && r != -ENODATA) + if (r < 0 && !ERRNO_IS_XATTR_ABSENT(r)) log_debug_errno(r, "Failed to get xattr user.oomd_avoid, ignoring: %m"); ctx->preference = r > 0 ? MANAGED_OOM_PREFERENCE_AVOID : ctx->preference; r = cg_get_xattr_bool(SYSTEMD_CGROUP_CONTROLLER, ctx->path, "user.oomd_omit"); if (r == -ENOMEM) return log_oom_debug(); - if (r < 0 && r != -ENODATA) + if (r < 0 && !ERRNO_IS_XATTR_ABSENT(r)) log_debug_errno(r, "Failed to get xattr user.oomd_omit, ignoring: %m"); ctx->preference = r > 0 ? MANAGED_OOM_PREFERENCE_OMIT : ctx->preference; } else diff --git a/src/portable/portable.c b/src/portable/portable.c index 202442903f3..7172701ca29 100644 --- a/src/portable/portable.c +++ b/src/portable/portable.c @@ -278,7 +278,7 @@ static int extract_now( * we have to preserve it. Copy it out so that it can be applied later. */ r = fgetfilecon_raw(fd, &con); - if (r < 0 && errno != ENODATA) + if (r < 0 && !ERRNO_IS_XATTR_ABSENT(errno)) log_debug_errno(errno, "Failed to get SELinux file context from '%s', ignoring: %m", de->d_name); #endif diff --git a/src/random-seed/random-seed.c b/src/random-seed/random-seed.c index dedbdb2667b..82c29d0d7ff 100644 --- a/src/random-seed/random-seed.c +++ b/src/random-seed/random-seed.c @@ -66,7 +66,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); if (r < 0) { - if (IN_SET(r, -ENODATA, -ENOSYS, -EOPNOTSUPP)) + if (ERRNO_IS_XATTR_ABSENT(r)) log_debug_errno(r, "Seed file is not marked as creditable, not crediting."); else log_warning_errno(r, "Failed to read extended attribute, ignoring: %m"); @@ -235,7 +235,7 @@ static int run(int argc, char *argv[]) { * it. */ if (fremovexattr(seed_fd, "user.random-seed-creditable") < 0) { - if (!IN_SET(errno, ENODATA, ENOSYS, EOPNOTSUPP)) + if (!ERRNO_IS_XATTR_ABSENT(errno)) log_warning_errno(errno, "Failed to remove extended attribute, ignoring: %m"); /* Otherwise, there was no creditable flag set, which is OK. */ diff --git a/src/shared/cgroup-show.c b/src/shared/cgroup-show.c index ca96e198f31..e34a68ef869 100644 --- a/src/shared/cgroup-show.c +++ b/src/shared/cgroup-show.c @@ -135,12 +135,12 @@ static int is_delegated(int cgfd, const char *path) { assert(cgfd >= 0 || path); r = getxattr_malloc(cgfd < 0 ? path : FORMAT_PROC_FD_PATH(cgfd), "trusted.delegate", &b); - if (r == -ENODATA) { + if (r < 0 && ERRNO_IS_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 = getxattr_malloc(cgfd < 0 ? path : FORMAT_PROC_FD_PATH(cgfd), "user.delegate", &b); - if (r == -ENODATA) + if (r < 0 && ERRNO_IS_XATTR_ABSENT(r)) return false; } if (r < 0) diff --git a/src/shared/chown-recursive.c b/src/shared/chown-recursive.c index 05a7a10ce41..bbc270d34b2 100644 --- a/src/shared/chown-recursive.c +++ b/src/shared/chown-recursive.c @@ -32,7 +32,7 @@ static int chown_one( /* Drop any ACL if there is one */ FOREACH_STRING(n, "system.posix_acl_access", "system.posix_acl_default") if (removexattr(FORMAT_PROC_FD_PATH(fd), n) < 0) - if (!IN_SET(errno, ENODATA, EOPNOTSUPP, ENOSYS, ENOTTY)) + if (!ERRNO_IS_XATTR_ABSENT(errno)) return -errno; r = fchmod_and_chown(fd, st->st_mode & mask, uid, gid); diff --git a/src/shared/dissect-image.c b/src/shared/dissect-image.c index ed58b9d0ab3..bea29b8ccff 100644 --- a/src/shared/dissect-image.c +++ b/src/shared/dissect-image.c @@ -2379,7 +2379,7 @@ int verity_settings_load( if (r < 0) { _cleanup_free_ char *p = NULL; - if (!IN_SET(r, -ENODATA, -ENOENT) && !ERRNO_IS_NOT_SUPPORTED(r)) + if (r != -ENOENT && !ERRNO_IS_XATTR_ABSENT(r)) return r; p = build_auxiliary_path(image, ".roothash"); @@ -2408,7 +2408,7 @@ int verity_settings_load( if (r < 0) { _cleanup_free_ char *p = NULL; - if (!IN_SET(r, -ENODATA, -ENOENT) && !ERRNO_IS_NOT_SUPPORTED(r)) + if (r != -ENOENT && !ERRNO_IS_XATTR_ABSENT(r)) return r; p = build_auxiliary_path(image, ".usrhash"); diff --git a/src/test/test-chown-rec.c b/src/test/test-chown-rec.c index 97711f58b0d..801b49f7b73 100644 --- a/src/test/test-chown-rec.c +++ b/src/test/test-chown-rec.c @@ -32,10 +32,8 @@ static const uint8_t default_acl[] = { static bool has_xattr(const char *p) { char buffer[sizeof(acl) * 4]; - if (lgetxattr(p, "system.posix_acl_access", buffer, sizeof(buffer)) < 0) { - if (IN_SET(errno, EOPNOTSUPP, ENOTTY, ENODATA, ENOSYS)) - return false; - } + if (lgetxattr(p, "system.posix_acl_access", buffer, sizeof(buffer)) < 0) + return !ERRNO_IS_XATTR_ABSENT(errno); return true; } diff --git a/src/test/test-xattr-util.c b/src/test/test-xattr-util.c index 2ddb4b4b843..02fba3d6ff3 100644 --- a/src/test/test-xattr-util.c +++ b/src/test/test-xattr-util.c @@ -46,7 +46,7 @@ TEST(getxattr_at_malloc) { fd = open("/", O_RDONLY|O_DIRECTORY|O_CLOEXEC|O_NOCTTY); assert_se(fd >= 0); r = getxattr_at_malloc(fd, "usr", "user.idontexist", 0, &value); - assert_se(r == -ENODATA || ERRNO_IS_NOT_SUPPORTED(r)); + assert_se(r < 0 && ERRNO_IS_XATTR_ABSENT(r)); safe_close(fd); fd = open(x, O_PATH|O_CLOEXEC); diff --git a/src/udev/udevd.c b/src/udev/udevd.c index 3e0c02893e4..2c9de63da6e 100644 --- a/src/udev/udevd.c +++ b/src/udev/udevd.c @@ -1808,7 +1808,7 @@ static int create_subcgroup(char **ret) { } r = cg_get_xattr_bool(SYSTEMD_CGROUP_CONTROLLER, cgroup, "trusted.delegate"); - if (IN_SET(r, 0, -ENODATA)) + if (r == 0 || (r < 0 && ERRNO_IS_XATTR_ABSENT(r))) return log_debug_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "The cgroup %s is not delegated to us.", cgroup); if (r < 0) return log_debug_errno(r, "Failed to read trusted.delegate attribute: %m"); -- 2.39.2