Skip to content

Conversation

benzea
Copy link

@benzea benzea commented Mar 20, 2025

Doing that can cause weird issues with permissions. One example is fprintd trying to open the fingerprint reader but selinux has not yet been tagged and it is not allowed to do so. Other scenarios can also be possible as it is not uncommon to change the user/group of devices using udev.

This should fix it, unfortunately the umockdev testing is not really optimal …

EDIT: Downstream bug report is https://bugzilla.redhat.com/show_bug.cgi?id=2346771

@@ -409,6 +409,8 @@ test_fixture_add_canon(UMockdevTestbedFixture * fixture)
"E: DRIVER=usb\n"
"E: BUSNUM=001\n"
"E: DEVNUM=001\n"
"E: MAJOR=189\n"
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just FYI, this is the correct thing here and it is needed because the is_initialized check in the enumerator is special and considers any device without a device number always as initialized (udev_device_get_is_initialized behaves differently there).

@mcuee
Copy link
Member

mcuee commented Apr 4, 2025

Looks like the intention of this PR is good. But I am not able to review the implementation properly.

@benzea
Copy link
Author

benzea commented May 2, 2025

Looks like the intention of this PR is good. But I am not able to review the implementation properly.

I don't think it is that complicated. Most of the PR is adjusting the tests, but maybe you can ignore that? Either way, please ping me if you need someone else to look over it. I think that it would be nice if this makes it into the next release.

@tormodvolden
Copy link
Contributor

This sounds like something we want, and I think I have heard about issues caused by such "half-ready" devices. It seems from the downstream report this have had minimal to none testing though. Have you patched libusb in RedHat with this already?

BTW, you're saying the device will now be detected later on the udev "add" event. So the enumerator will (originally) also return devices for which there has been no udev add event signaled yet? And the add event coincides with "initialized" becoming true?

And I am fine with bumping umockdev requirements to the 3 year old 17.7 (available in the oldest supported Ubuntu LTS release as one data point).

@benzea
Copy link
Author

benzea commented May 4, 2025

This sounds like something we want, and I think I have heard about issues caused by such "half-ready" devices. It seems from the downstream report this have had minimal to none testing though. Have you patched libusb in RedHat with this already?

I am not with Red Hat anymore. I suppose I could submit a PR for the Fedora libusb package and try getting it in there.

BTW, you're saying the device will now be detected later on the udev "add" event. So the enumerator will (originally) also return devices for which there has been no udev add event signaled yet? And the add event coincides with "initialized" becoming true?

Yup, exactly. The enumerator looks at sysfs, so it sees all devices known to the kernel. However, once udev is done, it writes a file into /run/udev/data/ and fires the "add" event to notify all processes.

What the change effectively does is to check whether the file in /run/udev/data/ has already been written. If it does not exist, then we know that an "add" signal will arrive in the future.

benzea added 2 commits August 11, 2025 18:19
umockdev 0.17.7 is old enough to rely on it for testing. Remove the
workaround as it might not be compatible with the follow up changes.

Signed-off-by: Benjamin Berg <[email protected]>
The udev enumerator can return devices for which udev has not finished
processing its rules. As udev has not finished handling its rules, the
application may not yet be permitted to open the device.

For these devices a hotplug event will happen later on when udev sends
the "add" event.

Change the enumerator to only return initialized devices when udev is
running. There is no nice API to check whether this is the case, so just
do the same access() call that udev_queue_get_udev_is_active() would
also do.

Also add a umockdev test for this specific corner case. Note that other
tests need to be updated to work around poor umockdev emulation of the
udev behaviour. umockdev never writes udev database entries to its
/run/udev/data, which means that devices are only considered initialized
when an event has been received.

Signed-off-by: Benjamin Berg <[email protected]>
@benzea
Copy link
Author

benzea commented Aug 28, 2025

So, the bugfix seems to work well. However, we have a bug in libmtp which runs from inside a udev rule and then fails to open the device and detect it as an MTP device.

A workaround might be to inspect the environment variables (udev exports all device properties there, see PROGRAM section in man page). Then we can explicitly include this device in the enumeration list (and log a warning) even though udev is not yet done with it.

The proper fix is for all programs run from udev rules to use libusb_wrap_sys_device.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants