Skip to content

udev-dev: Enumerate evdev devices via kern.evdev.input sysctls#12

Merged
wulf7 merged 1 commit into
wulf7:masterfrom
Defenso-QTH:evdev-sysctl-enumerate
Jun 14, 2026
Merged

udev-dev: Enumerate evdev devices via kern.evdev.input sysctls#12
wulf7 merged 1 commit into
wulf7:masterfrom
Defenso-QTH:evdev-sysctl-enumerate

Conversation

@Defenso-QTH

Copy link
Copy Markdown
Contributor

When /dev/input/ is not visible to the calling process (for example, a FreeBSD jail without the corresponding devfs ruleset), the existing scandir-based enumeration in udev_dev_enumerate() cannot discover any input devices, even though the kern.evdev.input.* sysctls remain readable and the per-device property handlers already populate from those sysctls.

Add a sysctl tree-walk fallback that runs after the scandir pass. The walk uses CTL_SYSCTL_NEXT to discover the actual children of kern.evdev.input without a fixed upper bound, then resolves each unit's name via CTL_SYSCTL_NAME to extract the unit number for the /dev/input/eventN syspath. Devices already discovered by scandir are deduplicated by udev_list_insert.

This lets libinput (and other libudev consumers) enumerate input devices in environments where the evdev sysctls are accessible but the devnodes are not.

Test setup:

Comment thread udev-dev.c Outdated
if (ret != 0)
return (ret);
#ifdef HAVE_SYSCTLBYNAME
ret = udev_dev_enumerate_evdev_sysctl(ue);

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

That results in duplicate entries for input/event devices. Check for /dev/input existence before falling back to sysctls

@Defenso-QTH Defenso-QTH May 28, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Thanks for looking at this! My understanding of how entries are added to the udev list is that duplicates are automatically removed on insert:

libudev-devd/udev-list.c

Lines 53 to 71 in 0f2c177

int
udev_list_insert(struct udev_list *ul, char const *name, char const *value)
{
struct udev_list_entry *ule, *old_ule;
ule = udev_list_entry_alloc(name, value);
if (!ule)
return (-1);
ule->list = ul;
old_ule = RB_FIND(udev_list, ul, ule);
if (old_ule != NULL) {
RB_REMOVE(udev_list, ul, old_ule);
udev_list_entry_free(old_ule);
}
RB_INSERT(udev_list, ul, ule);
return (0);
}

Am I not reading that correctly?

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

I do not see reasons to do extra device scan pass. Actually you may read security.jail.jailed sysctl value and do extra enumeration attempt if it is not zero.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

You're right that's enough for my use case. I added that check in 7432dbf.

@Defenso-QTH Defenso-QTH force-pushed the evdev-sysctl-enumerate branch from bc83206 to 7432dbf Compare May 28, 2026 14:08
Comment thread udev-dev.c
When /dev/input/ is not visible to the calling process (for example, a
FreeBSD jail without the corresponding devfs ruleset), the existing
scandir-based enumeration in udev_dev_enumerate() cannot discover any
input devices, even though the kern.evdev.input.* sysctls remain
readable and the per-device property handlers already populate from
those sysctls.

Add a sysctl tree-walk fallback that runs after the scandir pass when
running in a jail. The walk uses CTL_SYSCTL_NEXT to discover the
actual children of kern.evdev.input without a fixed upper bound, then
resolves each unit's name via CTL_SYSCTL_NAME to extract the unit
number for the /dev/input/eventN syspath. Devices already discovered by
scandir are deduplicated by udev_list_insert.

This lets libinput (and other libudev consumers) enumerate input
devices in jails where the evdev sysctls are accessible but the
devnodes are not.

Signed-off-by: Quentin Thebault <quentin.thebault@defenso.fr>
Sponsored-by: Defenso
@Defenso-QTH Defenso-QTH force-pushed the evdev-sysctl-enumerate branch from 7432dbf to 5fee3dd Compare May 29, 2026 09:49
@wulf7 wulf7 merged commit 67875bc into wulf7:master Jun 14, 2026
@wulf7

wulf7 commented Jun 14, 2026

Copy link
Copy Markdown
Owner

Merged. Thank you!

@Defenso-QTH Defenso-QTH deleted the evdev-sysctl-enumerate branch June 14, 2026 22:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants