evdev: create sysctl entries before cdev to close userspace race#386
Open
ericbsd wants to merge 1 commit into
Open
evdev: create sysctl entries before cdev to close userspace race#386ericbsd wants to merge 1 commit into
ericbsd wants to merge 1 commit into
Conversation
evdev_register_common() was creating the character device before
registering the kern.evdev.input.N.* sysctl entries. The moment
the cdev appears, devd fires a CREATE event for /dev/input/eventN,
and userspace libraries (e.g. libudev-devd) immediately call
sysctlbyname("kern.evdev.input.N.name") to enumerate device
capabilities. With the old ordering, that call could arrive before
the sysctl tree was populated, causing it to fail. The result was
that the device was not recognised by the input stack, leaving
keyboards and other HID devices non-functional after plug-in or
resume from suspend.
Fix the race by calling evdev_sysctl_create() before
evdev_cdev_create(). On cdev failure, free the already-registered
sysctl context with sysctl_ctx_free() to avoid leaking it.
Reviewer's guide (collapsed on small PRs)Reviewer's GuideAdjusts evdev device registration order so sysctl entries are created before the character device node, closing a userspace race, and ensures sysctl context is freed on cdev creation failure. Sequence diagram for updated evdev device registration and userspace sysctl accesssequenceDiagram
participant KernelEvdev
participant Sysctl
participant Cdev
participant UserspaceLib
KernelEvdev->>KernelEvdev: evdev_register_common
KernelEvdev->>Sysctl: evdev_sysctl_create
KernelEvdev->>Cdev: evdev_cdev_create
UserspaceLib->>KernelEvdev: sysctlbyname
KernelEvdev-->>UserspaceLib: sysctl values from kern.evdev.input.N.*
Flow diagram for evdev_register_common error handling with sysctl_ctx_freeflowchart TD
A[evdev_register_common] --> B[evdev_sysctl_create]
B --> C[evdev_cdev_create]
C --> D{ret == 0?}
D -- Yes --> E[Success]
D -- No --> F["sysctl_ctx_free(ev_sysctl_ctx)"]
F --> G[bail_out / return error]
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
|
Thank you for taking the time to contribute to FreeBSD!
Please review CONTRIBUTING.md, then update and push your branch again. |
There was a problem hiding this comment.
Hey - I've left some high level feedback:
- Now that sysctls are created before the cdev, consider ensuring
sysctl_ctx_free(&evdev->ev_sysctl_ctx)is called on all subsequent failure paths inevdev_register_common()(not just theevdev_cdev_create()error case) to avoid leaking the sysctl context when later steps fail. - If feasible, it may be safer for
evdev_sysctl_create()to return an error code on failure instead ofvoid, allowingevdev_register_common()to bail out early and cleanly roll back the partially initialized sysctl context.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- Now that sysctls are created before the cdev, consider ensuring `sysctl_ctx_free(&evdev->ev_sysctl_ctx)` is called on all subsequent failure paths in `evdev_register_common()` (not just the `evdev_cdev_create()` error case) to avoid leaking the sysctl context when later steps fail.
- If feasible, it may be safer for `evdev_sysctl_create()` to return an error code on failure instead of `void`, allowing `evdev_register_common()` to bail out early and cleanly roll back the partially initialized sysctl context.Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
Contributor
Author
|
@emaste I would like your opinion on this patch when you have time to look at it. |
Contributor
Author
|
I need to think more about it. I just found an issue. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
evdev_register_common() was creating the character device before registering the kern.evdev.input.N.* sysctl entries. The moment the cdev appears, devd fires a CREATE event for /dev/input/eventN, and userspace libraries (e.g. libudev-devd) immediately call sysctlbyname("kern.evdev.input.N.name") to enumerate device capabilities. With the old ordering, that call could arrive before the sysctl tree was populated, causing it to fail. The result was that the device was not recognised by the input stack, leaving keyboards and other HID devices non-functional after plug-in or resume from suspend.
Fix the race by calling evdev_sysctl_create() before evdev_cdev_create(). On cdev failure, free the already-registered sysctl context with sysctl_ctx_free() to avoid leaking it.
Summary by Sourcery
Fix evdev device registration ordering to avoid userspace races when probing new input devices.
Bug Fixes:
Enhancements: