Fix dangling dev->driver pointer when unloading a driver with probed-but-not-attached devices#2208
Open
MegaManSec wants to merge 1 commit into
Open
Fix dangling dev->driver pointer when unloading a driver with probed-but-not-attached devices#2208MegaManSec wants to merge 1 commit into
MegaManSec wants to merge 1 commit into
Conversation
|
Thank you for taking the time to contribute to FreeBSD! All issues resolved. |
Contributor
Author
|
This resolves https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=280714. |
9d41756 to
2866a32
Compare
bsdimp
reviewed
May 18, 2026
bsdimp
reviewed
May 18, 2026
| * it cannot dangle into the unloaded module. | ||
| */ | ||
| if (dev->driver == driver) | ||
| (void)device_set_driver(dev, NULL); |
Member
There was a problem hiding this comment.
I don't think you need the (void) cast here.
Contributor
Author
There was a problem hiding this comment.
device_set_driver() is cast to void everywhere else in this file
Member
|
Generally I like it, but had a few suggestions to make it better. |
19de0a4 to
14a598b
Compare
…load device_detach() is a no-op when dev->state != DS_ATTACHED, so if a driver was matched during probe but attach was never reached (e.g. the device is disabled via hints), dev->driver is left pointing into the module's data segment after the module is unloaded. devclass_driver_deleted() already iterates devices whose driver pointer matches the driver being removed. After calling device_detach(), check whether the pointer is still set and call device_set_driver(dev, NULL) to release it. This prevents sysctl_devices() from dereferencing a dangling pointer into freed module memory when enumerating hw.bus.devices. Signed-off-by: Joshua Rogers <Joshua@Joshua.Hu>
14a598b to
447b17e
Compare
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.
Problem
When a driver module is unloaded,
devclass_driver_deleted()callsdevice_detach()for each device using that driver. However,device_detach()is a no-op if the device is not inDS_ATTACHEDstate — it returns 0 immediately without clearingdev->driver.This occurs whenever a device was successfully probed (setting
dev->driverinto module memory and transitioning toDS_ALIVE) but attach was never reached — most commonly becausedevice_attach()returned early on aresource_disabled()hint check. Afterkldunload,dev->driveris a dangling pointer into freed module pages.A subsequent
sysctl hw.bus.devicesquery (e.g. fromdevmatch) callssysctl_devices(), which dereferencesdev->driver->name— triggering a page fault and kernel panic.This affects any loadable driver whose probe succeeds but whose attach is blocked by hints. The entire HID leaf driver family (
hms,hkbd,hcons,hmt,hpen,hgame,hidraw,bcm5974,appleir,hconf,hsctrl,ietp,ps4dshock,u2f,wmt,xb360gp) is in this category, as none perform their ownresource_disabled()check in probe.Fix
After
device_detach()returns indevclass_driver_deleted(), check whetherdev->driverstill points at the departing driver and calldevice_set_driver(dev, NULL)to release it before the module is freed.Reproducer
Boot, then
kldunload hms(or wait fordevmatchto run). Kernel panics insysctl_devices()with a page fault at the address wherehms.kowas mapped.