chiark / gitweb /
nspawn: mount /selinux if needed
[elogind.git] / src / nspawn.c
index fa70e86c469a96da81868f2a6726e5e9c272cac7..a053a4d5553f466e75c09e881ca5f92de9fb2add 100644 (file)
@@ -36,6 +36,7 @@
 
 #include "log.h"
 #include "util.h"
+#include "missing.h"
 
 static char *arg_directory = NULL;
 
@@ -103,13 +104,16 @@ static int mount_all(const char *dest) {
         } MountPoint;
 
         static const MountPoint mount_table[] = {
-                { "proc",      "/proc",     "proc",   NULL,        MS_NOSUID|MS_NOEXEC|MS_NODEV },
-                { "/proc/sys", "/proc/sys", "bind",   NULL,        MS_BIND },                      /* Bind mount first */
-                { "/proc/sys", "/proc/sys", "bind",   NULL,        MS_BIND|MS_RDONLY|MS_REMOUNT }, /* Then, make it r/o */
-                { "sysfs",     "/sys",      "sysfs",  NULL,        MS_NOSUID|MS_NOEXEC|MS_NODEV|MS_RDONLY },
-                { "tmpfs",     "/dev",      "tmpfs",  "mode=755",  MS_NOSUID },
-                { "/dev/pts",  "/dev/pts",  "bind",   NULL,        MS_BIND },
-                { "tmpfs",     "/dev/.run", "tmpfs",  "mode=755",  MS_NOSUID|MS_NOEXEC|MS_NODEV },
+                { "proc",      "/proc",     "proc",      NULL,        MS_NOSUID|MS_NOEXEC|MS_NODEV },
+                { "/proc/sys", "/proc/sys", "bind",      NULL,        MS_BIND },                      /* Bind mount first */
+                { "/proc/sys", "/proc/sys", "bind",      NULL,        MS_BIND|MS_RDONLY|MS_REMOUNT }, /* Then, make it r/o */
+                { "sysfs",     "/sys",      "sysfs",     NULL,        MS_NOSUID|MS_NOEXEC|MS_NODEV|MS_RDONLY },
+                { "tmpfs",     "/dev",      "tmpfs",     "mode=755",  MS_NOSUID },
+                { "/dev/pts",  "/dev/pts",  "bind",      NULL,        MS_BIND },
+                { "tmpfs",     "/dev/.run", "tmpfs",     "mode=755",  MS_NOSUID|MS_NOEXEC|MS_NODEV },
+#ifdef HAVE_SELINUX
+                { "selinux",   "/selinux",  "selinuxfs", NULL,        MS_NOSUID|MS_NOEXEC|MS_NODEV|MS_RDONLY },
+#endif
         };
 
         unsigned k;
@@ -175,6 +179,9 @@ static int copy_devnodes(const char *dest) {
         int r = 0, k;
         char *tty = NULL;
         dev_t tty_devnum;
+        mode_t u;
+
+        u = umask(0000);
 
         NULSTR_FOREACH(d, devnodes) {
                 char *from = NULL, *to = NULL;
@@ -250,7 +257,7 @@ static int copy_devnodes(const char *dest) {
                                         r = -errno;
                         }
 
-                        if (mount(from, to, "bind", MS_BIND, NULL) < 0) {
+                        if (mount(from, to, "bind", MS_BIND|MS_RDONLY, NULL) < 0) {
                                 log_error("bind mount for /dev/console failed: %m");
 
                                 if (r == 0)
@@ -264,6 +271,8 @@ static int copy_devnodes(const char *dest) {
 
         free(tty);
 
+        umask(u);
+
         return r;
 }
 
@@ -377,13 +386,18 @@ int main(int argc, char *argv[]) {
 
         log_info("Spawning namespace container on %s.", arg_directory);
 
-        if ((pid = syscall(__NR_clone, SIGCHLD|CLONE_NEWIPC|CLONE_NEWNS|CLONE_NEWPID|CLONE_NEWUTS|CLONE_NEWNET, NULL)) < 0) {
+        if ((pid = syscall(__NR_clone, SIGCHLD|CLONE_NEWIPC|CLONE_NEWNS|CLONE_NEWPID|CLONE_NEWUTS, NULL)) < 0) {
                 log_error("clone() failed: %m");
                 goto finish;
         }
 
         if (pid == 0) {
                 const char *hn;
+                const char *envp[] = {
+                        "HOME=/root",
+                        "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
+                        NULL
+                };
 
                 /* child */
 
@@ -419,9 +433,11 @@ int main(int argc, char *argv[]) {
                         sethostname(hn, strlen(hn));
 
                 if (argc > optind)
-                        execvp(argv[optind], argv + optind);
-                else
-                        execl("/bin/bash", "/bin/bash", NULL);
+                        execvpe(argv[optind], argv + optind, (char**) envp);
+                else {
+                        chdir("/root");
+                        execle("/bin/bash", "-bash", NULL, (char**) envp);
+                }
 
                 log_error("execv() failed: %m");