diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/core/execute.c | 2 | ||||
-rw-r--r-- | src/core/namespace.c | 6 | ||||
-rw-r--r-- | src/shared/label.c | 23 | ||||
-rw-r--r-- | src/shared/label.h | 5 | ||||
-rw-r--r-- | src/shared/mkdir-label.c | 2 | ||||
-rw-r--r-- | src/shared/selinux-util.c | 106 | ||||
-rw-r--r-- | src/shared/selinux-util.h | 10 | ||||
-rw-r--r-- | src/shared/smack-util.c | 98 | ||||
-rw-r--r-- | src/shared/smack-util.h | 6 | ||||
-rw-r--r-- | src/tmpfiles/tmpfiles.c | 2 | ||||
-rw-r--r-- | src/udev/udev-node.c | 2 |
11 files changed, 137 insertions, 125 deletions
diff --git a/src/core/execute.c b/src/core/execute.c index 962edc1eee..3be219fe1c 100644 --- a/src/core/execute.c +++ b/src/core/execute.c @@ -3081,7 +3081,7 @@ static int setup_credentials_internal( assert(!must_mount || workspace_mounted > 0); where = workspace_mounted ? workspace : final; - (void) label_fix_container(where, final, 0); + (void) label_fix_full(AT_FDCWD, where, final, 0); r = acquire_credentials(context, params, unit, where, uid, workspace_mounted); if (r < 0) diff --git a/src/core/namespace.c b/src/core/namespace.c index 0bc10cd335..41457ea816 100644 --- a/src/core/namespace.c +++ b/src/core/namespace.c @@ -928,7 +928,7 @@ static int mount_private_dev(MountEntry *m) { if (r < 0) goto fail; - r = label_fix_container(dev, "/dev", 0); + r = label_fix_full(AT_FDCWD, dev, "/dev", 0); if (r < 0) { log_debug_errno(r, "Failed to fix label of '%s' as /dev: %m", dev); goto fail; @@ -1158,7 +1158,7 @@ static int mount_tmpfs(const MountEntry *m) { if (r < 0) return r; - r = label_fix_container(entry_path, inner_path, 0); + r = label_fix_full(AT_FDCWD, entry_path, inner_path, 0); if (r < 0) return log_debug_errno(r, "Failed to fix label of '%s' as '%s': %m", entry_path, inner_path); @@ -2758,7 +2758,7 @@ static int setup_one_tmp_dir(const char *id, const char *prefix, char **path, ch if (mkdir(y, 0777 | S_ISVTX) < 0) return -errno; - r = label_fix_container(y, prefix, 0); + r = label_fix_full(AT_FDCWD, y, prefix, 0); if (r < 0) return r; diff --git a/src/shared/label.c b/src/shared/label.c index dea15871f6..dde93e1dde 100644 --- a/src/shared/label.c +++ b/src/shared/label.c @@ -11,12 +11,29 @@ #include "selinux-util.h" #include "smack-util.h" -int label_fix_container(const char *path, const char *inside_path, LabelFixFlags flags) { +int label_fix_full( + int atfd, + const char *inode_path, /* path of inode to apply label to */ + const char *label_path, /* path to use as database lookup key in label database (typically same as inode_path, but not always) */ + LabelFixFlags flags) { + int r, q; - r = mac_selinux_fix_container(path, inside_path, flags); - q = mac_smack_fix_container(path, inside_path, flags); + if (atfd < 0 && atfd != AT_FDCWD) + return -EBADF; + + if (!inode_path && atfd < 0) /* We need at least one of atfd and an inode path */ + return -EINVAL; + + /* If both atfd and inode_path are specified, we take the specified path relative to atfd which must be an fd to a dir. + * + * If only atfd is specified (and inode_path is NULL), we'll operated on the inode the atfd refers to. + * + * If atfd is AT_FDCWD then we'll operate on the inode the path refers to. + */ + r = mac_selinux_fix_full(atfd, inode_path, label_path, flags); + q = mac_smack_fix_full(atfd, inode_path, label_path, flags); if (r < 0) return r; if (q < 0) diff --git a/src/shared/label.h b/src/shared/label.h index ec5160284d..88aa47b7b8 100644 --- a/src/shared/label.h +++ b/src/shared/label.h @@ -10,9 +10,10 @@ typedef enum LabelFixFlags { LABEL_IGNORE_EROFS = 1 << 1, } LabelFixFlags; -int label_fix_container(const char *path, const char *inside_path, LabelFixFlags flags); +int label_fix_full(int atfd, const char *inode_path, const char *label_path, LabelFixFlags flags); + static inline int label_fix(const char *path, LabelFixFlags flags) { - return label_fix_container(path, path, flags); + return label_fix_full(AT_FDCWD, path, path, flags); } int symlink_label(const char *old_path, const char *new_path); diff --git a/src/shared/mkdir-label.c b/src/shared/mkdir-label.c index 60673614c3..926d1faeeb 100644 --- a/src/shared/mkdir-label.c +++ b/src/shared/mkdir-label.c @@ -22,7 +22,7 @@ int mkdirat_label(int dirfd, const char *path, mode_t mode) { if (r < 0) return r; - return mac_smack_fix_at(dirfd, path, 0); + return mac_smack_fix_full(dirfd, path, NULL, 0); } int mkdir_safe_label(const char *path, mode_t mode, uid_t uid, gid_t gid, MkdirFlags flags) { diff --git a/src/shared/selinux-util.c b/src/shared/selinux-util.c index 67ea858142..57f330f8bc 100644 --- a/src/shared/selinux-util.c +++ b/src/shared/selinux-util.c @@ -233,46 +233,19 @@ static int mac_selinux_reload(int seqno) { } #endif -int mac_selinux_fix_container(const char *path, const char *inside_path, LabelFixFlags flags) { - - assert(path); - assert(inside_path); - #if HAVE_SELINUX - _cleanup_close_ int fd = -1; - - /* if mac_selinux_init() wasn't called before we are a NOOP */ - if (!label_hnd) - return 0; - - /* Open the file as O_PATH, to pin it while we determine and adjust the label */ - fd = open(path, O_NOFOLLOW|O_CLOEXEC|O_PATH); - if (fd < 0) { - if ((flags & LABEL_IGNORE_ENOENT) && errno == ENOENT) - return 0; - - return -errno; - } - - return mac_selinux_fix_container_fd(fd, path, inside_path, flags); -#endif - - return 0; -} - -int mac_selinux_fix_container_fd(int fd, const char *path, const char *inside_path, LabelFixFlags flags) { - - assert(fd >= 0); - assert(inside_path); +static int selinux_fix_fd( + int fd, + const char *label_path, + LabelFixFlags flags) { -#if HAVE_SELINUX _cleanup_freecon_ char* fcon = NULL; struct stat st; int r; - /* if mac_selinux_init() wasn't called before we are a NOOP */ - if (!label_hnd) - return 0; + assert(fd >= 0); + assert(label_path); + assert(path_is_absolute(label_path)); if (fstat(fd, &st) < 0) return -errno; @@ -282,42 +255,85 @@ int mac_selinux_fix_container_fd(int fd, const char *path, const char *inside_pa if (!label_hnd) return 0; - if (selabel_lookup_raw(label_hnd, &fcon, inside_path, st.st_mode) < 0) { + if (selabel_lookup_raw(label_hnd, &fcon, label_path, st.st_mode) < 0) { /* If there's no label to set, then exit without warning */ if (errno == ENOENT) return 0; - r = -errno; - goto fail; + return log_enforcing_errno(errno, "Unable to lookup intended SELinux security context of %s: %m", label_path); } if (setfilecon_raw(FORMAT_PROC_FD_PATH(fd), fcon) < 0) { _cleanup_freecon_ char *oldcon = NULL; + r = -errno; + /* If the FS doesn't support labels, then exit without warning */ - if (ERRNO_IS_NOT_SUPPORTED(errno)) + if (ERRNO_IS_NOT_SUPPORTED(r)) return 0; /* It the FS is read-only and we were told to ignore failures caused by that, suppress error */ - if (errno == EROFS && (flags & LABEL_IGNORE_EROFS)) + if (r == -EROFS && (flags & LABEL_IGNORE_EROFS)) return 0; - r = -errno; - /* If the old label is identical to the new one, suppress any kind of error */ if (getfilecon_raw(FORMAT_PROC_FD_PATH(fd), &oldcon) >= 0 && streq(fcon, oldcon)) return 0; - goto fail; + return log_enforcing_errno(r, "Unable to fix SELinux security context of %s: %m", label_path); } return 0; - -fail: - return log_enforcing_errno(r, "Unable to fix SELinux security context of %s (%s): %m", strna(path), strna(inside_path)); +} #endif +int mac_selinux_fix_full( + int atfd, + const char *inode_path, + const char *label_path, + LabelFixFlags flags) { + + assert(atfd >= 0 || atfd == AT_FDCWD); + assert(atfd >= 0 || inode_path); + +#if HAVE_SELINUX + _cleanup_close_ int opened_fd = -1; + _cleanup_free_ char *p = NULL; + int inode_fd, r; + + /* if mac_selinux_init() wasn't called before we are a NOOP */ + if (!label_hnd) + return 0; + + 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 selinux_fix_fd(inode_fd, label_path, flags); +#else return 0; +#endif } int mac_selinux_apply(const char *path, const char *label) { diff --git a/src/shared/selinux-util.h b/src/shared/selinux-util.h index a9ddbfc653..e9771a28fe 100644 --- a/src/shared/selinux-util.h +++ b/src/shared/selinux-util.h @@ -24,15 +24,7 @@ int mac_selinux_init(void); void mac_selinux_maybe_reload(void); void mac_selinux_finish(void); -int mac_selinux_fix_container(const char *path, const char *inside_path, LabelFixFlags flags); -static inline int mac_selinux_fix(const char *path, LabelFixFlags flags) { - return mac_selinux_fix_container(path, path, flags); -} - -int mac_selinux_fix_container_fd(int fd, const char *path, const char *inside_path, LabelFixFlags flags); -static inline int mac_selinux_fix_fd(int fd, const char *path, LabelFixFlags flags) { - return mac_selinux_fix_container_fd(fd, path, path, flags); -} +int mac_selinux_fix_full(int atfd, const char *inode_path, const char *label_path, LabelFixFlags flags); int mac_selinux_apply(const char *path, const char *label); int mac_selinux_apply_fd(int fd, const char *path, const char *label); 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) { diff --git a/src/shared/smack-util.h b/src/shared/smack-util.h index df91c89e01..da8be5e6f0 100644 --- a/src/shared/smack-util.h +++ b/src/shared/smack-util.h @@ -29,13 +29,11 @@ typedef enum SmackAttr { bool mac_smack_use(void); -int mac_smack_fix_container(const char *path, const char *inside_path, LabelFixFlags flags); +int mac_smack_fix_full(int atfd, const char *inode_path, const char *label_path, LabelFixFlags flags); static inline int mac_smack_fix(const char *path, LabelFixFlags flags) { - return mac_smack_fix_container(path, path, flags); + return mac_smack_fix_full(AT_FDCWD, path, path, flags); } -int mac_smack_fix_at(int dirfd, const char *path, LabelFixFlags flags); - const char* smack_attr_to_string(SmackAttr i) _const_; SmackAttr smack_attr_from_string(const char *s) _pure_; int mac_smack_read(const char *path, SmackAttr attr, char **label); diff --git a/src/tmpfiles/tmpfiles.c b/src/tmpfiles/tmpfiles.c index 6406a64237..0e389d3a31 100644 --- a/src/tmpfiles/tmpfiles.c +++ b/src/tmpfiles/tmpfiles.c @@ -923,7 +923,7 @@ static int fd_set_perms(Item *i, int fd, const char *path, const struct stat *st } shortcut: - return label_fix(path, 0); + return label_fix_full(fd, /* inode_path= */ NULL, /* label_path= */ path, 0); } static int path_open_parent_safe(const char *path) { diff --git a/src/udev/udev-node.c b/src/udev/udev-node.c index c9f58e8c29..bb34977d97 100644 --- a/src/udev/udev-node.c +++ b/src/udev/udev-node.c @@ -677,7 +677,7 @@ static int udev_node_apply_permissions_impl( /* set the defaults */ if (!selinux) - (void) mac_selinux_fix_fd(node_fd, devnode, LABEL_IGNORE_ENOENT); + (void) mac_selinux_fix_full(node_fd, NULL, devnode, LABEL_IGNORE_ENOENT); if (!smack) (void) mac_smack_apply_fd(node_fd, SMACK_ATTR_ACCESS, NULL); } |