]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
nspawn: don't try to patch UIDs/GIDs of procfs and suchlike
authorLennart Poettering <lennart@poettering.net>
Fri, 22 Apr 2016 16:10:16 +0000 (18:10 +0200)
committerLennart Poettering <lennart@poettering.net>
Mon, 25 Apr 2016 10:50:06 +0000 (12:50 +0200)
src/basic/missing.h
src/nspawn/nspawn-patch-uid.c

index 6616f0b7205f9115ebae11e186f20f6ec8ccbdc1..b389e94cf7155a1f26ee837b3e05b0a682ea8eba 100644 (file)
@@ -445,6 +445,10 @@ struct btrfs_ioctl_quota_ctl_args {
 #define TMPFS_MAGIC 0x01021994
 #endif
 
+#ifndef MQUEUE_MAGIC
+#define MQUEUE_MAGIC 0x19800202
+#endif
+
 #ifndef MS_MOVE
 #define MS_MOVE 8192
 #endif
index f53164fbbf600fcbf8b7685455caa30b7a66a80e..429c45a3a77f32ead13883aa30096be128da44ca 100644 (file)
 ***/
 
 #include <fcntl.h>
+#include <linux/magic.h>
 #ifdef HAVE_ACL
 #include <sys/acl.h>
 #endif
 #include <sys/stat.h>
+#include <sys/vfs.h>
 #include <unistd.h>
 
 #include "acl-util.h"
 #include "dirent-util.h"
 #include "fd-util.h"
+#include "missing.h"
 #include "nspawn-patch-uid.h"
+#include "stat-util.h"
 #include "stdio-util.h"
 #include "string-util.h"
 #include "strv.h"
@@ -276,12 +280,46 @@ static int patch_fd(int fd, const char *name, const struct stat *st, uid_t shift
         return r > 0 || changed;
 }
 
+static int is_procfs_sysfs_or_suchlike(int fd) {
+        struct statfs sfs;
+
+        assert(fd >= 0);
+
+        if (fstatfs(fd, &sfs) < 0)
+                return -errno;
+
+        return F_TYPE_EQUAL(sfs.f_type, BINFMTFS_MAGIC) ||
+               F_TYPE_EQUAL(sfs.f_type, CGROUP_SUPER_MAGIC) ||
+               F_TYPE_EQUAL(sfs.f_type, CGROUP2_SUPER_MAGIC) ||
+               F_TYPE_EQUAL(sfs.f_type, DEBUGFS_MAGIC) ||
+               F_TYPE_EQUAL(sfs.f_type, DEVPTS_SUPER_MAGIC) ||
+               F_TYPE_EQUAL(sfs.f_type, EFIVARFS_MAGIC) ||
+               F_TYPE_EQUAL(sfs.f_type, HUGETLBFS_MAGIC) ||
+               F_TYPE_EQUAL(sfs.f_type, MQUEUE_MAGIC) ||
+               F_TYPE_EQUAL(sfs.f_type, PROC_SUPER_MAGIC) ||
+               F_TYPE_EQUAL(sfs.f_type, PSTOREFS_MAGIC) ||
+               F_TYPE_EQUAL(sfs.f_type, SELINUX_MAGIC) ||
+               F_TYPE_EQUAL(sfs.f_type, SMACK_MAGIC) ||
+               F_TYPE_EQUAL(sfs.f_type, SYSFS_MAGIC);
+}
+
 static int recurse_fd(int fd, bool donate_fd, const struct stat *st, uid_t shift) {
         bool changed = false;
         int r;
 
         assert(fd >= 0);
 
+        /* We generally want to permit crossing of mount boundaries when patching the UIDs/GIDs. However, we
+         * probably shouldn't do this for /proc and /sys if that is already mounted into place. Hence, let's
+         * stop the recursion when we hit a procfs or sysfs file system. */
+        r = is_procfs_sysfs_or_suchlike(fd);
+        if (r < 0)
+                goto finish;
+        if (r > 0) {
+                r = 0; /* don't recurse */
+                goto finish;
+        }
+
         r = patch_fd(fd, NULL, st, shift);
         if (r < 0)
                 goto finish;
@@ -294,8 +332,10 @@ static int recurse_fd(int fd, bool donate_fd, const struct stat *st, uid_t shift
                         int copy;
 
                         copy = fcntl(fd, F_DUPFD_CLOEXEC, 3);
-                        if (copy < 0)
-                                return -errno;
+                        if (copy < 0) {
+                                r = -errno;
+                                goto finish;
+                        }
 
                         fd = copy;
                         donate_fd = true;