]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
nspawn: move the accessibility check for device nodes into copy_devnode_one() 36407/head
authorYu Watanabe <watanabe.yu+github@gmail.com>
Tue, 18 Feb 2025 14:35:13 +0000 (23:35 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Tue, 18 Feb 2025 14:35:13 +0000 (23:35 +0900)
src/nspawn/nspawn.c

index d73f83f3fbdc70bfa712c287b934858516fff477..bcf0baaf7fb5289a7d83cc3aff6c9ed058f784f6 100644 (file)
@@ -2189,7 +2189,7 @@ static int bind_mount_devnode(const char *from, const char *to) {
         return 0;
 }
 
-static int copy_devnode_one(const char *dest, const char *node) {
+static int copy_devnode_one(const char *dest, const char *node, bool check) {
         int r;
 
         assert(dest);
@@ -2201,6 +2201,19 @@ static int copy_devnode_one(const char *dest, const char *node) {
         if (!from)
                 return log_oom();
 
+        if (check) {
+                /* If 'check' is true, create /dev/fuse only when it is accessible. The check is necessary,
+                 * as some custom service units that invoke systemd-nspawn may enable DevicePolicy= without
+                 * DeviceAllow= for the device node. */
+                _cleanup_close_ int fd = open(from, O_CLOEXEC|O_RDWR);
+                if (fd < 0) {
+                        log_debug_errno(errno,
+                                        "Failed to open %s, skipping creation of the device node in the container, ignoring: %m",
+                                        from);
+                        return 0;
+                }
+        }
+
         _cleanup_free_ char *to = path_join(dest, from);
         if (!to)
                 return log_oom();
@@ -2284,25 +2297,16 @@ static int copy_devnodes(const char *dest) {
 
         assert(dest);
 
+        /* Required basic device nodes. */
         FOREACH_STRING(node, "null", "zero", "full", "random", "urandom", "tty") {
-                r = copy_devnode_one(dest, node);
-                if (r < 0)
-                        return r;
-        }
-
-        /* Create /dev/fuse only when it is accessible. The check is necessary, as some custom service
-         * units that invoke nspawn may enable DevicePolicy= without DeviceAllow= for the device node. */
-        _cleanup_close_ int fuse_fd = open("/dev/fuse", O_CLOEXEC|O_RDWR);
-        if (fuse_fd >= 0) {
-                r = copy_devnode_one(dest, "fuse");
+                r = copy_devnode_one(dest, node, /* check = */ false);
                 if (r < 0)
                         return r;
         }
 
-        /* Similarly, create /dev/net/tun only when it is accessible. */
-        _cleanup_close_ int tun_fd = open("/dev/net/tun", O_CLOEXEC|O_RDWR);
-        if (tun_fd >= 0) {
-                r = copy_devnode_one(dest, "net/tun");
+        /* Optional device nodes. */
+        FOREACH_STRING(node, "fuse", "net/tun") {
+                r = copy_devnode_one(dest, node, /* check = */ true);
                 if (r < 0)
                         return r;
         }