]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
namespace: fix MAC labels of /dev when PrivateDevices=yes
authorTopi Miettinen <toiwoton@gmail.com>
Tue, 18 Feb 2020 11:18:39 +0000 (13:18 +0200)
committerTopi Miettinen <topimiettinen@users.noreply.github.com>
Fri, 28 Feb 2020 14:17:48 +0000 (14:17 +0000)
Without changing the SELinux label for private /dev of a service, it will take
a generic file system label:
system_u:object_r:tmpfs_t:s0

After this change it is the same as without `PrivateDevices=yes`:
system_u:object_r:device_t:s0

This helps writing SELinux policies, as the same rules for `/dev` will apply
despite any `PrivateDevices=yes` setting.

src/basic/label.c
src/basic/label.h
src/basic/selinux-util.c
src/basic/selinux-util.h
src/basic/smack-util.c
src/basic/smack-util.h
src/core/namespace.c

index 12a7fb0945e21c326c612bd68c10a5a24bdc6582..1fce7718d4bad9d39b7f3323762a48395b7ad299 100644 (file)
 #include "selinux-util.h"
 #include "smack-util.h"
 
-int label_fix(const char *path, LabelFixFlags flags) {
+int label_fix_container(const char *path, const char *inside_path, LabelFixFlags flags) {
         int r, q;
 
-        r = mac_selinux_fix(path, flags);
-        q = mac_smack_fix(path, flags);
+        r = mac_selinux_fix_container(path, inside_path, flags);
+        q = mac_smack_fix_container(path, inside_path, flags);
 
         if (r < 0)
                 return r;
index 594fd65974c1e3981270c874dcfcffea7c4c21f6..a6f9074b2814f52d8d194e8eda637f6b96d906e1 100644 (file)
@@ -9,7 +9,10 @@ typedef enum LabelFixFlags {
         LABEL_IGNORE_EROFS  = 1 << 1,
 } LabelFixFlags;
 
-int label_fix(const char *path, LabelFixFlags flags);
+int label_fix_container(const char *path, const char *inside_path, LabelFixFlags flags);
+static inline int label_fix(const char *path, LabelFixFlags flags) {
+        return label_fix_container(path, path, flags);
+}
 
 int mkdir_label(const char *path, mode_t mode);
 int mkdirat_label(int dirfd, const char *path, mode_t mode);
index 90bb93ed0b8a6d3d4aaced31828d763836a9a5bc..fd78ce200ed7f1e85a968bb8f23b9feae78d31f0 100644 (file)
@@ -124,7 +124,7 @@ void mac_selinux_reload(void) {
 #endif
 }
 
-int mac_selinux_fix(const char *path, LabelFixFlags flags) {
+int mac_selinux_fix_container(const char *path, const char *inside_path, LabelFixFlags flags) {
 
 #if HAVE_SELINUX
         char procfs_path[STRLEN("/proc/self/fd/") + DECIMAL_STR_MAX(int)];
@@ -151,7 +151,7 @@ int mac_selinux_fix(const char *path, LabelFixFlags flags) {
         if (fstat(fd, &st) < 0)
                 return -errno;
 
-        if (selabel_lookup_raw(label_hnd, &fcon, path, st.st_mode) < 0) {
+        if (selabel_lookup_raw(label_hnd, &fcon, inside_path, st.st_mode) < 0) {
                 r = -errno;
 
                 /* If there's no label to set, then exit without warning */
@@ -185,7 +185,7 @@ int mac_selinux_fix(const char *path, LabelFixFlags flags) {
         return 0;
 
 fail:
-        log_enforcing_errno(r, "Unable to fix SELinux security context of %s: %m", path);
+        log_enforcing_errno(r, "Unable to fix SELinux security context of %s (%s): %m", path, inside_path);
         if (security_getenforce() == 1)
                 return r;
 #endif
index b73b7c50e07414e3cba0e0037a5610d6fbf1fb65..6d9e050781c23090e83b6d6f4fd49e7368a4eff5 100644 (file)
@@ -22,7 +22,11 @@ int mac_selinux_init(void);
 void mac_selinux_finish(void);
 void mac_selinux_reload(void);
 
-int mac_selinux_fix(const char *path, LabelFixFlags flags);
+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_apply(const char *path, const char *label);
 
 int mac_selinux_get_create_label_from_exe(const char *exe, char **label);
index da9a2139d31a2d3b3c6f23da5b6e7054ea69d38d..8043a97c3594b01ffc0d2b1423ae2ab1d299be69 100644 (file)
@@ -206,7 +206,7 @@ int mac_smack_fix_at(int dirfd, const char *path, LabelFixFlags flags) {
         return smack_fix_fd(fd, path, flags);
 }
 
-int mac_smack_fix(const char *path, LabelFixFlags flags) {
+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;
@@ -228,7 +228,7 @@ int mac_smack_fix(const char *path, LabelFixFlags flags) {
                 return -errno;
         }
 
-        return smack_fix_fd(fd, abspath, flags);
+        return smack_fix_fd(fd, inside_path, flags);
 }
 
 int mac_smack_copy(const char *dest, const char *src) {
@@ -274,7 +274,7 @@ int mac_smack_apply_pid(pid_t pid, const char *label) {
         return 0;
 }
 
-int mac_smack_fix(const char *path, LabelFixFlags flags) {
+int mac_smack_fix_container(const char *path, const char *inside_path, LabelFixFlags flags) {
         return 0;
 }
 
index 395ec07b57c7aa462e537201e705b38602bd6778..df2ce370716910741110adab5495b700868ae12a 100644 (file)
@@ -29,7 +29,11 @@ typedef enum SmackAttr {
 
 bool mac_smack_use(void);
 
-int mac_smack_fix(const char *path, LabelFixFlags flags);
+int mac_smack_fix_container(const char *path, const char *inside_path, LabelFixFlags flags);
+static inline int mac_smack_fix(const char *path, LabelFixFlags flags) {
+        return mac_smack_fix_container(path, path, flags);
+}
+
 int mac_smack_fix_at(int dirfd, const char *path, LabelFixFlags flags);
 
 const char* smack_attr_to_string(SmackAttr i) _const_;
index 07c9ac2b515c8c0b62868b43711238515bd1994f..df9bbdb7b4377dabec70aea8673ec617f95ef911 100644 (file)
@@ -34,6 +34,7 @@
 #include "tmpfile-util.h"
 #include "umask-util.h"
 #include "user-util.h"
+#include "virt.h"
 
 #define DEV_MOUNT_OPTIONS (MS_NOSUID|MS_STRICTATIME|MS_NOEXEC)
 
@@ -690,6 +691,22 @@ static int mount_private_dev(MountEntry *m) {
                 r = log_debug_errno(errno, "Failed to mount tmpfs on '%s': %m", dev);
                 goto fail;
         }
+#if HAVE_SELINUX || ENABLE_SMACK
+        if (detect_container() <= 0) {
+                /* these could fail if inside container */
+                r = mac_selinux_init();
+                if (r < 0) {
+                        log_debug("Failed to reinitialize SELinux policy");
+                        goto fail;
+                }
+                r = label_fix_container(dev, "/dev", 0);
+                if (r < 0) {
+                        log_debug_errno(errno, "Failed to fix label of '%s' as /dev: %m", dev);
+                        goto fail;
+                }
+                mac_selinux_finish();
+        }
+#endif
 
         devpts = strjoina(temporary_mount, "/dev/pts");
         (void) mkdir(devpts, 0755);