diff options
author | Lennart Poettering <lennart@poettering.net> | 2022-07-08 10:05:57 +0200 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2022-07-08 17:43:49 +0200 |
commit | 03bc11d1c491d6b8fed1e43c2929790d004d7367 (patch) | |
tree | 5021f0a3c79c7cfa44c174ab0dbaf947bbbd96e6 /src/shared/smack-util.c | |
parent | 05c4affe04b5592c5786e5313e3edd1f36b1aca8 (diff) | |
download | systemd-03bc11d1c491d6b8fed1e43c2929790d004d7367.tar.gz |
mac: rework labelling code to be simpler, and less racy
This merges the various labelling calls into a single label_fix_full(),
which can operate on paths, on inode fds, and in a dirfd/fname style
(i.e. like openat()). It also systematically separates the path to look
up in the db from the path we actually use to reference the inode to
relabel.
This then ports tmpfiles over to labelling by fd. This should make the
code a bit less racy, as we'll try hard to always operate on the very
same inode, pinning it via an fd.
User-visibly the behaviour should not change.
Diffstat (limited to 'src/shared/smack-util.c')
-rw-r--r-- | src/shared/smack-util.c | 98 |
1 files changed, 43 insertions, 55 deletions
diff --git a/src/shared/smack-util.c b/src/shared/smack-util.c index 8f90a2096d..f0a0f5f315 100644 --- a/src/shared/smack-util.c +++ b/src/shared/smack-util.c @@ -122,17 +122,22 @@ int mac_smack_apply_pid(pid_t pid, const char *label) { return r; } -static int smack_fix_fd(int fd, const char *abspath, LabelFixFlags flags) { +static int smack_fix_fd( + int fd, + const char *label_path, + LabelFixFlags flags) { + const char *label; struct stat st; int r; /* The caller should have done the sanity checks. */ - assert(abspath); - assert(path_is_absolute(abspath)); + assert(fd >= 0); + assert(label_path); + assert(path_is_absolute(label_path)); /* Path must be in /dev. */ - if (!path_startswith(abspath, "/dev")) + if (!path_startswith(label_path, "/dev")) return 0; if (fstat(fd, &st) < 0) @@ -171,70 +176,53 @@ static int smack_fix_fd(int fd, const char *abspath, LabelFixFlags flags) { streq(old_label, label)) return 0; - return log_debug_errno(r, "Unable to fix SMACK label of %s: %m", abspath); + return log_debug_errno(r, "Unable to fix SMACK label of %s: %m", label_path); } return 0; } -int mac_smack_fix_at(int dir_fd, const char *path, LabelFixFlags flags) { - _cleanup_free_ char *p = NULL; - _cleanup_close_ int fd = -1; - int r; - - assert(path); - - if (!mac_smack_use()) - return 0; - - if (dir_fd < 0) { - if (dir_fd != AT_FDCWD) - return -EBADF; - - return mac_smack_fix(path, flags); - } - - fd = openat(dir_fd, path, O_NOFOLLOW|O_CLOEXEC|O_PATH); - if (fd < 0) { - if ((flags & LABEL_IGNORE_ENOENT) && errno == ENOENT) - return 0; +int mac_smack_fix_full( + int atfd, + const char *inode_path, + const char *label_path, + LabelFixFlags flags) { - return -errno; - } - - if (!path_is_absolute(path)) { - r = fd_get_path(fd, &p); - if (r < 0) - return r; - path = p; - } - - return smack_fix_fd(fd, path, flags); -} + _cleanup_close_ int opened_fd = -1; + _cleanup_free_ char *p = NULL; + int r, inode_fd; -int mac_smack_fix_container(const char *path, const char *inside_path, LabelFixFlags flags) { - _cleanup_free_ char *abspath = NULL; - _cleanup_close_ int fd = -1; - int r; - - assert(path); + assert(atfd >= 0 || atfd == AT_FDCWD); + assert(atfd >= 0 || inode_path); if (!mac_smack_use()) return 0; - r = path_make_absolute_cwd(path, &abspath); - if (r < 0) - return r; - - fd = open(abspath, O_NOFOLLOW|O_CLOEXEC|O_PATH); - if (fd < 0) { - if ((flags & LABEL_IGNORE_ENOENT) && errno == ENOENT) - return 0; - - return -errno; + if (inode_path) { + opened_fd = openat(atfd, inode_path, O_NOFOLLOW|O_CLOEXEC|O_PATH); + if (opened_fd < 0) { + if ((flags & LABEL_IGNORE_ENOENT) && errno == ENOENT) + return 0; + + return -errno; + } + inode_fd = opened_fd; + } else + inode_fd = atfd; + + if (!label_path) { + if (path_is_absolute(inode_path)) + label_path = inode_path; + else { + r = fd_get_path(inode_fd, &p); + if (r < 0) + return r; + + label_path = p; + } } - return smack_fix_fd(fd, inside_path, flags); + return smack_fix_fd(inode_fd, label_path, flags); } int mac_smack_copy(const char *dest, const char *src) { |