summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/core/execute.c2
-rw-r--r--src/core/namespace.c6
-rw-r--r--src/shared/label.c23
-rw-r--r--src/shared/label.h5
-rw-r--r--src/shared/mkdir-label.c2
-rw-r--r--src/shared/selinux-util.c106
-rw-r--r--src/shared/selinux-util.h10
-rw-r--r--src/shared/smack-util.c98
-rw-r--r--src/shared/smack-util.h6
-rw-r--r--src/tmpfiles/tmpfiles.c2
-rw-r--r--src/udev/udev-node.c2
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);
}