Package: udev Followup-For: Bug #1140336 Control: tags 1140336 + patch
Hi Benjamin, I ran into the same issue with sbuild --unshare and /dev/kvm bind-mounted. The failure is caused by dh_installtmpfiles in debhelper 14 removing the '|| true' fallback from the udev.postinst snippet. When setting permissions on static device nodes in unprivileged namespaces, fchownat() returns EPERM and systemd-tmpfiles aborts with exit code 73. Attached is a patch that: 1. Treats ERRNO_IS_PRIVILEGE (EPERM, EACCES) as non-fatal debug in fd_set_perms() on character and block devices. 2. Changes the action prefix from 'z' to 'z-' in static-nodes-permissions.conf.in so permission errors are tolerated on static device nodes. Also tracked in Ubuntu LP: #2160036: https://bugs.launchpad.net/ubuntu/+source/systemd/+bug/2160036 -- Viktor Pashaiev <[email protected]>
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 <[email protected]> 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 -

