chiark / gitweb /
nspawn: finish user namespace support
authorLennart Poettering <lennart@poettering.net>
Thu, 21 May 2015 14:30:58 +0000 (16:30 +0200)
committerSven Eden <yamakuzure@gmx.net>
Tue, 14 Mar 2017 08:57:27 +0000 (09:57 +0100)
src/shared/base-filesystem.c
src/shared/base-filesystem.h
src/shared/dev-setup.c
src/shared/dev-setup.h
src/shared/switch-root.c

index 11e0947..ab6fc17 100644 (file)
@@ -41,13 +41,16 @@ static const BaseFilesystem table[] = {
         { "lib",      0, "usr/lib\0",                  NULL },
         { "root",  0755, NULL,                         NULL },
         { "sbin",     0, "usr/sbin\0",                 NULL },
+        { "usr",   0755, NULL,                         NULL },
+        { "var",   0755, NULL,                         NULL },
+        { "etc",   0755, NULL,                         NULL },
 #if defined(__i386__) || defined(__x86_64__)
         { "lib64",    0, "usr/lib/x86_64-linux-gnu\0"
                          "usr/lib64\0",                "ld-linux-x86-64.so.2" },
 #endif
 };
 
-int base_filesystem_create(const char *root) {
+int base_filesystem_create(const char *root, uid_t uid, gid_t gid) {
         _cleanup_close_ int fd = -1;
         unsigned i;
         int r = 0;
@@ -90,6 +93,12 @@ int base_filesystem_create(const char *root) {
                         r = symlinkat(target, fd, table[i].dir);
                         if (r < 0 && errno != EEXIST)
                                 return log_error_errno(errno, "Failed to create symlink at %s/%s: %m", root, table[i].dir);
+
+                        if (uid != UID_INVALID || gid != UID_INVALID) {
+                                if (fchownat(fd, table[i].dir, uid, gid, AT_SYMLINK_NOFOLLOW) < 0)
+                                        return log_error_errno(errno, "Failed to chown symlink at %s/%s: %m", root, table[i].dir);
+                        }
+
                         continue;
                 }
 
@@ -97,6 +106,11 @@ int base_filesystem_create(const char *root) {
                         r = mkdirat(fd, table[i].dir, table[i].mode);
                 if (r < 0 && errno != EEXIST)
                         return log_error_errno(errno, "Failed to create directory at %s/%s: %m", root, table[i].dir);
+
+                if (uid != UID_INVALID || gid != UID_INVALID) {
+                        if (fchownat(fd, table[i].dir, uid, gid, AT_SYMLINK_NOFOLLOW) < 0)
+                                return log_error_errno(errno, "Failed to chown directory at %s/%s: %m", root, table[i].dir);
+                }
         }
 
         return 0;
index 03201f7..39a4960 100644 (file)
@@ -21,4 +21,6 @@
   along with systemd; If not, see <http://www.gnu.org/licenses/>.
 ***/
 
-int base_filesystem_create(const char *root);
+#include <sys/types.h>
+
+int base_filesystem_create(const char *root, uid_t uid, gid_t gid);
index cb15da8..25ad918 100644 (file)
 #include <stdlib.h>
 #include <unistd.h>
 
-#include "dev-setup.h"
 #include "util.h"
 #include "label.h"
+#include "path-util.h"
+#include "dev-setup.h"
 
-int dev_setup(const char *prefix) {
-        const char *j, *k;
-
+int dev_setup(const char *prefix, uid_t uid, gid_t gid) {
         static const char symlinks[] =
                 "-/proc/kcore\0"     "/dev/core\0"
                 "/proc/self/fd\0"    "/dev/fd\0"
@@ -37,7 +36,13 @@ int dev_setup(const char *prefix) {
                 "/proc/self/fd/1\0"  "/dev/stdout\0"
                 "/proc/self/fd/2\0"  "/dev/stderr\0";
 
+        const char *j, *k;
+        int r;
+
         NULSTR_FOREACH_PAIR(j, k, symlinks) {
+                _cleanup_free_ char *link_name = NULL;
+                const char *n;
+
                 if (j[0] == '-') {
                         j++;
 
@@ -46,15 +51,21 @@ int dev_setup(const char *prefix) {
                 }
 
                 if (prefix) {
-                        _cleanup_free_ char *link_name = NULL;
-
-                        link_name = strjoin(prefix, "/", k, NULL);
+                        link_name = prefix_root(prefix, k);
                         if (!link_name)
                                 return -ENOMEM;
 
-                        symlink_label(j, link_name);
+                        n = link_name;
                 } else
-                        symlink_label(j, k);
+                        n = k;
+
+                r = symlink_label(j, n);
+                if (r < 0)
+                        log_debug_errno(r, "Failed to symlink %s to %s: %m", j, n);
+
+                if (uid != UID_INVALID || gid != GID_INVALID)
+                        if (lchown(n, uid, gid) < 0)
+                                log_debug_errno(errno, "Failed to chown %s: %m", n);
         }
 
         return 0;
index d41b6ee..ab2748d 100644 (file)
@@ -21,4 +21,6 @@
   along with systemd; If not, see <http://www.gnu.org/licenses/>.
 ***/
 
-int dev_setup(const char *pathprefix);
+#include <sys/types.h>
+
+int dev_setup(const char *prefix, uid_t uid, gid_t gid);
index ae3839d..b12189c 100644 (file)
@@ -105,7 +105,7 @@ int switch_root(const char *new_root, const char *oldroot, bool detach_oldroot,
          * to look like. They might even boot, if they are RO and
          * don't have the FS layout. Just ignore the error and
          * switch_root() nevertheless. */
-        (void) base_filesystem_create(new_root);
+        (void) base_filesystem_create(new_root, UID_INVALID, GID_INVALID);
 
         if (chdir(new_root) < 0)
                 return log_error_errno(errno, "Failed to change directory to %s: %m", new_root);