nspawn: refuse to bind mount device node from host when --private-users= is specified
authorYu Watanabe <watanabe.yu+github@gmail.com>
Thu, 5 Sep 2024 06:05:32 +0000 (15:05 +0900)
committerDaan De Meyer <daan.j.demeyer@gmail.com>
Tue, 10 Sep 2024 12:56:05 +0000 (14:56 +0200)
Also do not chown if a device node is bind-mounted.

Fixes #34243.

(cherry picked from commit efedb6b0f3cff37950112fd37cb750c16d599bc7)

src/nspawn/nspawn.c

index 7d87116c1c4545e4cf1056f47557e02c8078e6a1..c6ce36b086aa2c7f26e9d6c84a7936e044d7a7a4 100644 (file)
@@ -2207,7 +2207,7 @@ static int copy_devnodes(const char *dest) {
                                 /* Explicitly warn the user when /dev is already populated. */
                                 if (errno == EEXIST)
                                         log_notice("%s/dev/ is pre-mounted and pre-populated. If a pre-mounted /dev/ is provided it needs to be an unpopulated file system.", dest);
-                                if (errno != EPERM)
+                                if (!ERRNO_IS_PRIVILEGE(errno) || arg_uid_shift != 0)
                                         return log_error_errno(errno, "mknod(%s) failed: %m", to);
 
                                 /* Some systems abusively restrict mknod but allow bind mounts. */
@@ -2217,12 +2217,12 @@ static int copy_devnodes(const char *dest) {
                                 r = mount_nofollow_verbose(LOG_DEBUG, from, to, NULL, MS_BIND, NULL);
                                 if (r < 0)
                                         return log_error_errno(r, "Both mknod and bind mount (%s) failed: %m", to);
+                        } else {
+                                r = userns_lchown(to, 0, 0);
+                                if (r < 0)
+                                        return log_error_errno(r, "chown() of device node %s failed: %m", to);
                         }
 
-                        r = userns_lchown(to, 0, 0);
-                        if (r < 0)
-                                return log_error_errno(r, "chown() of device node %s failed: %m", to);
-
                         dn = path_join("/dev", S_ISCHR(st.st_mode) ? "char" : "block");
                         if (!dn)
                                 return log_oom();