systemd icon indicating copy to clipboard operation
systemd copied to clipboard

Allow regular users and groups own device nodes

Open dimich-dmb opened this issue 3 months ago • 28 comments

systemd version the issue has been seen with

258

Used distribution

Arch

Linux kernel version used

6.16.8-arch1-1

CPU architectures issue was seen on

None

Component

systemd-udevd

Expected behaviour you didn't see

Nodes in /dev/ are owned by users and groups as set in udev rules with OWNER and GROUP keys.

Unexpected behaviour you saw

systemd-udevd[509]: /etc/udev/rules.d/99-usbasp.rules:1 User 'dimich' is not a system user, ignoring.

and many more.

Steps to reproduce the problem

Create udev rule to set device node ownership, for example /etc/udev/rules.d/99-usbasp.rules :

SUBSYSTEMS=="usb", ACTION=="add|change", ATTRS{idVendor}=="16c0", ATTRS{idProduct}=="05dc", OWNER="dimich"

Reload udev rules and plug in the device.

Additional program output to the terminal or log subsystem illustrating the issue

Please, revert f5cdf9515aceca2e91f9a33b74267e0cf5a5b7e8. It breaks working setups.

dimich-dmb avatar Sep 21 '25 01:09 dimich-dmb

~~Seeing this issue for Argyl-rules and cd-sensors.rules. They both try to make color instruments accessible to members of the colord group using the lines~~

~~ENV{COLOR_MEASUREMENT_DEVICE}=="*?", MODE="660", GROUP="colord" and ENV{COLORD_SENSOR_KIND}=="*?", GROUP="colord" respectively~~

~~Error message: systemd-udevd: /usr/lib/udev/rules.d/55-Argyll.rules:161 Group 'colord' is not a system group, ignoring. systemd-udevd: /usr/lib/udev/rules.d/69-cd-sensors.rules:105 Group 'colord' is not a system group, ignoring.~~

This was something different. Colord was not a system group as @poettering suggested. Don't know why that never created an issue before

srahman53171618 avatar Sep 21 '25 03:09 srahman53171618

systemd-udevd: /usr/lib/udev/rules.d/55-Argyll.rules:161 Group 'colord' is not a system group, ignoring. systemd-udevd: /usr/lib/udev/rules.d/69-cd-sensors.rules:105 Group 'colord' is not a system group, ignoring.

that looks like a bug in "colord". If it's a system service it should be allocating a system group, not a regular one?

poettering avatar Sep 22 '25 13:09 poettering

@poettering You are correct. Changed colord to a system group.

srahman53171618 avatar Sep 22 '25 18:09 srahman53171618

This ticket is not about colord. Udev had ability to set device node permissions to a particular user or group. In 258 it is broken.

dimich-dmb avatar Sep 22 '25 19:09 dimich-dmb

f5cdf9515aceca2e91f9a33b74267e0cf5a5b7e8 states:

Let's avoid accidentally devices being owned by non-system user/group.

...which completely ignores the cases where devices are purposely owned by a non-system user/group, which are now broken.

cfillion avatar Sep 23 '25 03:09 cfillion

It's fine to add ACLs to device nodes that reference non-system users/groups. But device nodes should really never be owned by regular users, that's just super weird and broken.

I can accept that this is a compat breakage, so it might make sense to turn this into a loud warning, and in a later release forbid this, and make it overridable via env var

poettering avatar Sep 23 '25 08:09 poettering

This is an intentional change. I do not think we should revert or postpone the change.

I recommend to use uaccess tag, or create a system group for the device and join regular users who want to use the device to the system group. If these do not work, then that should be a problem in designing system. Even in such case, people can manually change owner, group, or ACL in RUN= or PROGRAM= by chown or setfacl.

I can accept that this is a compat breakage, so it might make sense to turn this into a loud warning, and in a later release forbid this, and make it overridable via env var

I think that's too late. v258 is already released.

yuwata avatar Sep 23 '25 17:09 yuwata

But device nodes should really never be owned by regular users

Why? What standard / specification / convention states such requirement? Simple use case: allow direct access to a USB device for different users depending on physical port location. Create system group for each user? We need more system users and groups.

dimich-dmb avatar Sep 24 '25 02:09 dimich-dmb

I recommend to use uaccess tag,

Uaccess doesn't work for devices plugged before user logged in. Uaccess sets ownership for any user, not to particular one. There are issues with uaccess in remote access setup. Not the solution.

or create a system group for the device and join regular users who want to use the device to the system group.

More system groups, more probability of conflicts with upstream in the future.

If these do not work, then that should be a problem in designing system. Even in such case, people can manually change owner, group, or ACL in RUN= or PROGRAM= by chown or setfacl.

This is the only ugly workaround left. Spawn chmod and chown subprocesses, set permissions twice.

dimich-dmb avatar Sep 24 '25 02:09 dimich-dmb

Why? What standard / specification / convention states such requirement?

ownership of inodes implies the ability to change the permissions on it, modify ACLs and so on, and that is not desirable for device access. Device access control should not be delegated to unpriv code here, only the access itself shall be permitted. That's what ACLs/uaccess give you, but ownership just gives too much.

Uaccess doesn't work for devices plugged before user logged in. Uaccess sets ownership for any user, not to particular one. There are issues with uaccess in remote access setup. Not the solution.

hmm? why should a user get access to a device node while they aren't logged in? that makes no sense to me? it's entirely sufficient if they get access once they log in, which uaccess guarantees.

poettering avatar Sep 24 '25 07:09 poettering

ownership of inodes implies the ability to change the permissions on it, modify ACLs and so on,

Like for any other file. If a user with permissions enough to create/edit udev rules (root) wants to delegate some permissions to another user, it should not be a problem.

and that is not desirable for device access. Device access control should not be delegated to unpriv code here, only the access itself shall be permitted.

Let owner of particular system to decide, what is permitted in their system and what is not.

hmm? why should a user get access to a device node while they aren't logged in? that makes no sense to me? it's entirely sufficient if they get access once they log in, which uaccess guarantees.

There may be multiple users logged in, not all of them should have access to a device. Access may be required for users logged in remotely. Machines running Linux aren't limited to casual desktops and servers. I don't want to debate why uaccess sucks in some use cases. OWNER and GROUP keys in udev rules did their job flawlessly until v258, now this functionality is broken groundlessly, making things overcomplicated.

dimich-dmb avatar Sep 24 '25 09:09 dimich-dmb

I recommend to use uaccess tag, or create a system group for the device and join regular users who want to use the device to the system group. If these do not work, then that should be a problem in designing system

This new limitation seems arbitrary. It's unclear why udev suddenly needs to be limited to GIDs that happen to be in the system range with all groups being otherwise equal.

Just because some installs might happen to have a pre-existing clock user/group doesn't sound like a solid motivation to cripple every udev rules using non-system users/groups out there.

Perhaps the is_system check could be limited to only this new standard clock group? Maybe via a new SYSGROUP= key that 50-udev-default.rules could use for this purpose without impacting the regular GROUP=? Or avoid the issue altogether by naming it systemd-clock?

(I generally prefer to create my custom groups in the GID_MIN-GID_MAX range rather than intrude in the much more limited system range, which I leave alone for the system to use...)

(Giving access to whichever user is logged in using uaccess doesn't apply to my use case, I need to give access only to specific users/members of a group.)

cfillion avatar Sep 24 '25 10:09 cfillion

Unrelated to principal questions about whether or not device nodes should™ only be owned by system groups: Would it not rather be necessary to clean up the clock group to being with?

If there's a collision, you'll either be changing the clock GID, risking to leave random files w/ now bogus GIDs and this way casually breaking unrelated parts of the system, no? Or you leave the group alone, meaning the new udev limitation will affect that (old, non-system) group as well? Is there a third path?

On top of that, if the clock GID has actually been changed and since device nodes are transient, isn't the entire collision sought to be addressed by this change gone after a reboot anyway? Ie. is the restriction applied for the offshoot chance that there's a present device owned by the old clock group when udev restarts before the next reboot?

I frankly don't see how the change can solve the concerned conflict at all and in any event it rather seems like burning down the house because there might be a monster under the bed.

luebking avatar Sep 24 '25 15:09 luebking

I confirm this issue. This particular behavior breaks well-established development process when multiple external devices are connected to the host. There is no rationale behind this decision, at least no adversary model.

why should a user get access to a device node while they aren't logged in?

As it was pointed out by the other person, we use a normal UNIX file system and "Let owner of particular system to decide, what is permitted in their system and what is not." If I need a fine-grained access control, I will use SELinux or other MAC infrastructure.

locutus3009 avatar Sep 30 '25 09:09 locutus3009

This is an intentional change. I do not think we should revert or postpone the change.

care to elaborate? if admin of the system tells udev with an explicit rule: "this user will own this device" you are not in the position to say otherwise, especially when it's just your opinion. you have no context, you can only speculate about the security of the system and its configuration.

in your own words: "Let's avoid accidentally devices being owned by non-system user/group."

explicit rule is not an accident, it's intentional and you are preventing it.

this change will trigger creative workarounds which will probably cause more security risks than you think you are preventing.

(...) Even in such case, people can manually change owner, group, or ACL in RUN= or PROGRAM= by chown or setfacl.

i don't think this is a very constructive suggestion.

filipmnowak avatar Oct 02 '25 22:10 filipmnowak

I recommend to use uaccess tag, or create a system group for the device and join regular users who want to use the device to the system group.

uaccess won't work in my case too because I intend to allow access to my group only. Creating a system group would work but it defeats my intention to create a dedicate group for myself.

lilydjwg avatar Oct 05 '25 08:10 lilydjwg

This issue has caused a significant problem in our company, and I’ve been hoping to find a viable solution. Our setup relies on systemd-udevd in combination with Google LDAP-defined groups to manage user access to USB drives and other devices.

However, Google-defined groups use GIDs greater than 500, which prevents them from being recognized as system groups. Because of this restriction, we are no longer able to use systemd-udevd for group-based device access control.

This limitation has led to numerous operational issues across the company, and at this point, I haven’t found any workaround or alternative approach to address it.

On top of that, it’s creating additional security concerns, since we’re being forced to experiment with risky ideas just to make things work.

banafshehft avatar Oct 10 '25 18:10 banafshehft

I haven’t found any workaround or alternative approach to address it.

@banafshehft As a workaround you can use something like RUN+="/usr/bin/setfacl -m g:<group>:rw %N" or even RUN+="/usr/bin/chgrp <group> %N", RUN+="/usr/bin/chmod g+rw %N". However, these keys should be set before other RUN keys which may use a node, if any.

dimich-dmb avatar Oct 10 '25 23:10 dimich-dmb

I haven’t found any workaround or alternative approach to address it.

@banafshehft As a workaround you can use something like RUN+="/usr/bin/setfacl -m g:<group>:rw %N" or even RUN+="/usr/bin/chgrp <group> %N", RUN+="/usr/bin/chmod g+rw %N". However, these keys should be set before other RUN keys which may use a node, if any.

Well, no — I’m talking about a company environment, not just one system. People use multiple USB devices throughout the day, and they don’t have sudo access on those systems. I can’t go one by one and change the permissions every time someone removes or inserts a USB device.

banafshehft avatar Oct 14 '25 15:10 banafshehft

Patch out the at this point beyond questionable commit? Holding 257 will become a problem if you're also using gnome because it now somehow hard-depends on 258 userdbd 🙄

luebking avatar Oct 14 '25 18:10 luebking

Well, no — I’m talking about a company environment, not just one system. People use multiple USB devices throughout the day, and they don’t have sudo access on those systems. I can’t go one by one and change the permissions every time someone removes or inserts a USB device.

I mean change GROUP=... to RUN+=... with setfactl or chgrp/chmod in existing udev rules on systems in your company environment. I assume rules with GROUP=... already exist on that systems somehow. Unless they are autogenerated by some third-party software. I'm not justifying this terrible issue, just pointing out that workaround exists.

dimich-dmb avatar Oct 14 '25 19:10 dimich-dmb

The distinction between "system" and "non-system" groups realistically only exists for a few programs (adduser and some desktop user choosers), and they aren't even configured in the same place. The concept is broken and causes needless headaches when you start delegating to subuids/subgids, containers, nsswitch, etc. This change is needlessly heavy-handed.

dlitz avatar Nov 29 '25 05:11 dlitz

This also just makes it harder for developers, users, and maintainers to reason about what a particular set of udev rules will do.

The correct way to do this is to put this "system groups only" logic into a tool e.g. /usr/lib/udev/systemd-udev-chown and invoke it using RUN, not to foist this policy onto every single user and use-case of udev.

dlitz avatar Nov 29 '25 18:11 dlitz

I just hit this today after updating to NixOS 25.11.

I have various LVM partitions for use with different VMs and I was using udev rules to make each partition be owned by the user who logically owns that partition, as suggested at https://unix.stackexchange.com/questions/23955/permanently-changing-the-ownership-or-group-of-lvm-volume (currently, I'm the only user owning VM partitions, but that may change later).

@yuwata wrote:

I recommend to use uaccess tag, or create a system group for the device and join regular users who want to use the device to the system group.

uaccess seems to be undocumented (https://github.com/systemd/systemd/issues/4288), but it looks like it would give any logged-in user access to the virtual disks, which is not what I want. Making the disks world-writeable would also be bad, as unprivileged programs would gain access to them, and adding VM users to the disks group risks them corrupting the non-VM disks too.

So if I understand correctly, the best solution is to create one system group (a group with an ID under SYS_GID_MAX) corresponding to each normal user who owns a device, then change the udev rules to set the group of the device, then add each user to their corresponding system group?

talex5 avatar Dec 01 '25 12:12 talex5

Hi @poettering I was surprised by this change as everyone else on this thread. My permission model is about assigning groups not users. In unix/posix, changing the owning group does not infer additional privileges (your claim is only about owning user). In fact, changing the group is already established way to do simple ACLs. Secondly, you suggest to use ACLs instead, but udev does not provide any way of doing so. The old GROUP= is useless and you rejected ACL= in #37241 . So that leaves us with RUN+= ... and i can just as easily chown to my group (thus get the old behaviour back) using RUN. So given that the change and brouhaha generated feels kinda pointless. It just makes sysadmins sed their udev rules from one way to another while uttering some bad words.

du291 avatar Dec 07 '25 14:12 du291

I have a similar issue. I use systemd-nspawn 'unprivileged' containers and with this change I am now unable to give access to a usb device (in my case a tty device for a zigbee controller) to a service running inside the container. I use an unprivileged container because of security.

jsimonetti avatar Dec 07 '25 16:12 jsimonetti

This is a breaking change that messes up a lot of normal users systems that will now have to search far and wide for alternatives. The amount of frustration for normal users your little theoretical improvement has brought is immeasurable. The knock-on effects of this will seriously harm linux as a viable operating system for normal users, seeing as an update broke their working system without a warning, grace period, or even proper documentation to guide them. The amount of time it took me, a developer, to arrive at a suitable fix is ridiculous. This kind of change SHOULD have resulted in visible warnings, e.g. in dmesg, for months or years before the breaking change was made. Instead, even now, I did not see ANY warnings why my USB devices did not work anymore. For previously mentioned reasons, I will have to switch to system groups, and frankly, I do not feel I have enough information to decide whether that is an acceptable security model. But I do not feel comfortable with the amount of information I have about uaccess either, both regarding it's security implications and whether it works on non-systemd systems. This should have been part of a drawn-out grace period, and instead, we got chaos.

Seneral avatar Dec 10 '25 15:12 Seneral

Due to lack of info on migration for users, here's some instructions. I'll also start the use of the sysplugdev system group to not conflict with existing systems having plugdev as a non-system group, and encourage you to do the same.

So if you're looking to fix your udev rules to behave like they did before, in a way compatible with non-systemd systems, do this:

  1. Create and join the sysplugdev group to replace the plugdev group: sudo groupadd --system sysplugdev sudo usermod -a -G sysplugdev $USER Restart your computer and ensure you are part of sysplugdev with groups
  2. Edit your udev rules in /etc/udev/rules.d to use sysplugdev instead, then reload: sudo sed -i 's/GROUP="plugdev"/GROUP="sysplugdev"/' /etc/udev/rules.d/*.rules sudo udevadm control --reload-rules && sudo udevadm trigger

Use these steps at your own risk, you can also edit the rules manually.

Seneral avatar Dec 10 '25 15:12 Seneral