Description: tmpfiles: ignore privilege errors on device nodes
 In unprivileged containers or namespaces with bind-mounted device nodes,
 adjusting ownership or permissions on device nodes returns EPERM.
 Ignore privilege errors on device nodes in fd_set_perms() and mark
 static-nodes-permissions.conf entries with z- so failure is tolerated.
Author: Viktor Pashaiev <w.paszajew@gmail.com>
Bug-Debian: https://bugs.debian.org/1140336
Bug-Ubuntu: https://bugs.launchpad.net/ubuntu/+source/systemd/+bug/2160036
Forwarded: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1140336
Last-Update: 2026-10-07

Index: systemd-261.3/src/tmpfiles/tmpfiles.c
===================================================================
--- systemd-261.3.orig/src/tmpfiles/tmpfiles.c
+++ systemd-261.3/src/tmpfiles/tmpfiles.c
@@ -1017,8 +1017,14 @@ static int fd_set_perms(
                                            "%s \"%s\" to mode %o", path, m);
                                 if (!arg_dry_run) {
                                         r = fchmod_opath(fd, m);
-                                        if (r < 0)
-                                                return log_error_errno(r, "fchmod() of %s failed: %m", path);
+                                        if (r < 0) {
+                                                if ((S_ISCHR(st->st_mode) || S_ISBLK(st->st_mode)) && ERRNO_IS_PRIVILEGE(r))
+                                                        log_debug_errno(r, "Lacking privilege to temporarily chmod device node %s, skipping: %m", path);
+                                                else if (i->allow_failure)
+                                                        log_debug_errno(r, "fchmod() of %s failed, ignoring: %m", path);
+                                                else
+                                                        return log_error_errno(r, "fchmod() of %s failed: %m", path);
+                                        }
                                 }
                         }
                 }
@@ -1032,8 +1038,14 @@ static int fd_set_perms(
                     fchownat(fd, "",
                              new_uid != st->st_uid ? new_uid : UID_INVALID,
                              new_gid != st->st_gid ? new_gid : GID_INVALID,
-                             AT_EMPTY_PATH) < 0)
-                        return log_error_errno(errno, "fchownat() of %s failed: %m", path);
+                             AT_EMPTY_PATH) < 0) {
+                        if ((S_ISCHR(st->st_mode) || S_ISBLK(st->st_mode)) && ERRNO_IS_PRIVILEGE(errno))
+                                log_debug_errno(errno, "Lacking privilege to chown device node %s, skipping: %m", path);
+                        else if (i->allow_failure)
+                                log_debug_errno(errno, "fchownat() of %s failed, ignoring: %m", path);
+                        else
+                                return log_error_errno(errno, "fchownat() of %s failed: %m", path);
+                }
         }
 
         /* Now, apply the final mode. We do this in two cases: when the user set a mode explicitly, or after a
@@ -1045,8 +1057,14 @@ static int fd_set_perms(
                         log_action("Would change", "Changing", "%s \"%s\" to mode %o", path, new_mode);
                         if (!arg_dry_run) {
                                 r = fchmod_opath(fd, new_mode);
-                                if (r < 0)
-                                        return log_error_errno(r, "fchmod() of %s failed: %m", path);
+                                if (r < 0) {
+                                        if ((S_ISCHR(st->st_mode) || S_ISBLK(st->st_mode)) && ERRNO_IS_PRIVILEGE(r))
+                                                log_debug_errno(r, "Lacking privilege to chmod device node %s, skipping: %m", path);
+                                        else if (i->allow_failure)
+                                                log_debug_errno(r, "fchmod() of %s failed, ignoring: %m", path);
+                                        else
+                                                return log_error_errno(r, "fchmod() of %s failed: %m", path);
+                                }
                         }
                 }
         }
Index: systemd-261.3/tmpfiles.d/static-nodes-permissions.conf.in
===================================================================
--- systemd-261.3.orig/tmpfiles.d/static-nodes-permissions.conf.in
+++ systemd-261.3/tmpfiles.d/static-nodes-permissions.conf.in
@@ -9,12 +9,12 @@
 # kmod-static-nodes.service. Rules specified here should match the
 # permissions specified for udev in 50-udev-default.rules.
 
-z /dev/snd/seq      0660 - audio -
-z /dev/snd/timer    0660 - audio -
-z /dev/loop-control 0660 - disk  -
-z /dev/net/tun      0666 - -     -
-z /dev/fuse         0666 - -     -
-z /dev/vfio/vfio    0666 - -     -
-z /dev/kvm          {{DEV_KVM_MODE}} - kvm -
-z /dev/vhost-net    {{DEV_KVM_MODE}} - kvm -
-z /dev/vhost-vsock  {{DEV_KVM_MODE}} - kvm -
+z- /dev/snd/seq      0660 - audio -
+z- /dev/snd/timer    0660 - audio -
+z- /dev/loop-control 0660 - disk  -
+z- /dev/net/tun      0666 - -     -
+z- /dev/fuse         0666 - -     -
+z- /dev/vfio/vfio    0666 - -     -
+z- /dev/kvm          {{DEV_KVM_MODE}} - kvm -
+z- /dev/vhost-net    {{DEV_KVM_MODE}} - kvm -
+z- /dev/vhost-vsock  {{DEV_KVM_MODE}} - kvm -
