chiark / gitweb /
selinux: mount /sys, /proc, /dev before we load the SELinux policy
authorLennart Poettering <lennart@poettering.net>
Thu, 28 Jul 2011 23:48:18 +0000 (01:48 +0200)
committerLennart Poettering <lennart@poettering.net>
Thu, 28 Jul 2011 23:49:46 +0000 (01:49 +0200)
src/label.c
src/mount-setup.c
src/mount-setup.h
src/selinux-setup.c

index b34ee2d..a599462 100644 (file)
 static struct selabel_handle *label_hnd = NULL;
 
 static inline bool use_selinux(void) {
-        static int use_selinux_ind = -1;
+        static int use_selinux_cached = -1;
 
-        if (use_selinux_ind < 0)
-                use_selinux_ind = is_selinux_enabled() > 0;
+        if (use_selinux_cached < 0)
+                use_selinux_cached = is_selinux_enabled() > 0;
 
-        return use_selinux_ind;
+        return use_selinux_cached;
 }
 
 #endif
index 2906989..ec4184d 100644 (file)
@@ -48,6 +48,10 @@ typedef struct MountPoint {
         bool fatal;
 } MountPoint;
 
+/* The first three entries we might need before SELinux is up. The
+ * other ones we can delay until SELinux is loaded. */
+#define N_EARLY_MOUNT 3
+
 static const MountPoint mount_table[] = {
         { "proc",     "/proc",                  "proc",     NULL,                MS_NOSUID|MS_NOEXEC|MS_NODEV, true },
         { "sysfs",    "/sys",                   "sysfs",    NULL,                MS_NOSUID|MS_NOEXEC|MS_NODEV, true },
@@ -91,13 +95,14 @@ bool mount_point_ignore(const char *path) {
         return false;
 }
 
-static int mount_one(const MountPoint *p) {
+static int mount_one(const MountPoint *p, bool relabel) {
         int r;
 
         assert(p);
 
         /* Relabel first, just in case */
-        label_fix(p->where, true);
+        if (relabel)
+                label_fix(p->where, true);
 
         if ((r = path_is_mount_point(p->where)) < 0)
                 return r;
@@ -125,11 +130,31 @@ static int mount_one(const MountPoint *p) {
         }
 
         /* Relabel again, since we now mounted something fresh here */
-        label_fix(p->where, false);
+        if (relabel)
+                label_fix(p->where, false);
 
         return 0;
 }
 
+int mount_setup_early(void) {
+        unsigned i;
+        int r = 0;
+
+        assert_cc(N_EARLY_MOUNT <= ELEMENTSOF(mount_table));
+
+        /* Do a minimal mount of /proc and friends to enable the most
+         * basic stuff, such as SELinux */
+        for (i = 0; i < N_EARLY_MOUNT; i ++)  {
+                int j;
+
+                j = mount_one(mount_table + i, false);
+                if (r == 0)
+                        r = j;
+        }
+
+        return r;
+}
+
 static int mount_cgroup_controllers(void) {
         int r;
         FILE *f;
@@ -179,7 +204,7 @@ static int mount_cgroup_controllers(void) {
                 p.flags = MS_NOSUID|MS_NOEXEC|MS_NODEV;
                 p.fatal = false;
 
-                r = mount_one(&p);
+                r = mount_one(&p, true);
                 free(controller);
                 free(where);
 
@@ -239,9 +264,12 @@ int mount_setup(bool loaded_policy) {
         unsigned i;
         const char *j, *k;
 
-        for (i = 0; i < ELEMENTSOF(mount_table); i ++)
-                if ((r = mount_one(mount_table+i)) < 0)
+        for (i = 0; i < ELEMENTSOF(mount_table); i ++) {
+                r = mount_one(mount_table + i, true);
+
+                if (r < 0)
                         return r;
+        }
 
         /* Nodes in devtmpfs and /run need to be manually updated for
          * the appropriate labels, after mounting. The other virtual
index f05ee31..9311cac 100644 (file)
@@ -24,6 +24,8 @@
 
 #include <stdbool.h>
 
+int mount_setup_early(void);
+
 int mount_setup(bool loaded_policy);
 
 bool mount_point_is_api(const char *path);
index fdc3160..dc101b1 100644 (file)
@@ -30,6 +30,7 @@
 #endif
 
 #include "selinux-setup.h"
+#include "mount-setup.h"
 #include "macro.h"
 #include "util.h"
 #include "log.h"
@@ -45,6 +46,9 @@ int selinux_setup(bool *loaded_policy) {
 
        assert(loaded_policy);
 
+       /* Make sure getcon() works, which needs /proc and /sys */
+       mount_setup_early();
+
        /* Already initialized by somebody else? */
        r = getcon_raw(&con);
        if (r == 0) {
@@ -71,7 +75,7 @@ int selinux_setup(bool *loaded_policy) {
 
                /* Transition to the new context */
                r = label_get_create_label_from_exe(SYSTEMD_BINARY_PATH, &label);
-               if (r < 0) {
+               if (r < 0 || label == NULL) {
                        log_open();
                        log_error("Failed to compute init label, ignoring.");
                } else {