chiark / gitweb /
hwdb: Update database of Bluetooth company identifiers
[elogind.git] / src / core / namespace.c
index b6deab7081166a023424511676f0b2a93df96dea..d1513ce2ddea54da93b4a556cdca11e22f14081b 100644 (file)
@@ -42,6 +42,7 @@
 #include "mkdir.h"
 #include "dev-setup.h"
 #include "def.h"
+#include "label.h"
 
 typedef enum MountMode {
         /* This is ordered by priority! */
@@ -223,7 +224,10 @@ static int mount_dev(BindMount *m) {
                         goto fail;
                 }
 
+                label_context_set(d, st.st_mode);
                 r = mknod(dn, st.st_mode, st.st_rdev);
+                label_context_clear();
+
                 if (r < 0) {
                         r = -errno;
                         goto fail;
@@ -280,17 +284,21 @@ static int apply_mount(
 
         switch (m->mode) {
 
-        case PRIVATE_DEV:
-                return mount_dev(m);
-
         case INACCESSIBLE:
+
+                /* First, get rid of everything that is below if there
+                 * is anything... Then, overmount it with an
+                 * inaccessible directory. */
+                umount_recursive(m->path, 0);
+
                 what = "/run/systemd/inaccessible";
                 break;
 
         case READONLY:
         case READWRITE:
-                what = m->path;
-                break;
+                /* Nothing to mount here, we just later toggle the
+                 * MS_RDONLY bit for the mount point */
+                return 0;
 
         case PRIVATE_TMP:
                 what = tmp_dir;
@@ -300,6 +308,9 @@ static int apply_mount(
                 what = var_tmp_dir;
                 break;
 
+        case PRIVATE_DEV:
+                return mount_dev(m);
+
         default:
                 assert_not_reached("Unknown mode");
         }
@@ -310,7 +321,7 @@ static int apply_mount(
         if (r >= 0)
                 log_debug("Successfully mounted %s to %s", what, m->path);
         else if (m->ignore && errno == ENOENT)
-                r = 0;
+                return 0;
 
         return r;
 }
@@ -320,14 +331,17 @@ static int make_read_only(BindMount *m) {
 
         assert(m);
 
-        if (m->mode != INACCESSIBLE && m->mode != READONLY)
-                return 0;
+        if (IN_SET(m->mode, INACCESSIBLE, READONLY))
+                r = bind_remount_recursive(m->path, true);
+        else if (m->mode == READWRITE)
+                r = bind_remount_recursive(m->path, false);
+        else
+                r = 0;
 
-        r = mount(NULL, m->path, NULL, MS_BIND|MS_REMOUNT|MS_RDONLY|MS_REC, NULL);
-        if (r < 0 && !(m->ignore && errno == ENOENT))
-                return -errno;
+        if (m->ignore && r == -ENOENT)
+                return 0;
 
-        return 0;
+        return r;
 }
 
 int setup_namespace(
@@ -356,8 +370,8 @@ int setup_namespace(
                 strv_length(read_only_dirs) +
                 strv_length(inaccessible_dirs) +
                 private_dev +
-                (protect_home != PROTECT_HOME_NO ? 2 : 0) +
-                (protect_system != PROTECT_SYSTEM_NO ? 1 : 0) +
+                (protect_home != PROTECT_HOME_NO ? 3 : 0) +
+                (protect_system != PROTECT_SYSTEM_NO ? 2 : 0) +
                 (protect_system == PROTECT_SYSTEM_FULL ? 1 : 0);
 
         if (n > 0) {
@@ -393,13 +407,13 @@ int setup_namespace(
                 }
 
                 if (protect_home != PROTECT_HOME_NO) {
-                        r = append_mounts(&m, STRV_MAKE("-/home", "-/run/user"), protect_home == PROTECT_HOME_READ_ONLY ? READONLY : INACCESSIBLE);
+                        r = append_mounts(&m, STRV_MAKE("-/home", "-/run/user", "-/root"), protect_home == PROTECT_HOME_READ_ONLY ? READONLY : INACCESSIBLE);
                         if (r < 0)
                                 return r;
                 }
 
                 if (protect_system != PROTECT_SYSTEM_NO) {
-                        r = append_mounts(&m, protect_system == PROTECT_SYSTEM_FULL ? STRV_MAKE("/usr", "/etc") : STRV_MAKE("/usr"), READONLY);
+                        r = append_mounts(&m, protect_system == PROTECT_SYSTEM_FULL ? STRV_MAKE("/usr", "-/boot", "/etc") : STRV_MAKE("/usr", "-/boot"), READONLY);
                         if (r < 0)
                                 return r;
                 }