Fix handling of BUS_PROBE_NOWILDCARD in 'device_probe_child()'.

Device probe value of BUS_PROBE_NOWILDCARD should be treated specially only
if the device has a fixed devclass. Otherwise it should be interpreted just
as if the driver doesn't want to claim the device.

Prior to this change a device that was not claimed explicitly by its driver
would remain "attached" to the driver that returned BUS_PROBE_NOWILDCARD.
This would bump up the reference on 'driver->refs' and its 'dev->ops' would
point to the 'driver->ops'. When the driver is subsequently unloaded the
'dev->ops->cls' is left pointing to freed memory.

This fixes an easily reproducible #GP fault caused by loading and unloading
vmm.ko multiple times.

Differential Revision:	https://reviews.freebsd.org/D2294
Reviewed by:	imp, jhb
Discussed with:	rstone
Reported by:	Leon Dang (ldang@nahannisys.com)
MFC after:	2 weeks
This commit is contained in:
Neel Natu 2015-04-15 16:22:05 +00:00
parent 6332e4cc38
commit 1a688aa53e

View File

@ -2112,6 +2112,16 @@ device_probe_child(device_t dev, device_t child)
break;
}
/*
* Probes that return BUS_PROBE_NOWILDCARD or lower
* only match on devices whose driver was explicitly
* specified.
*/
if (result <= BUS_PROBE_NOWILDCARD &&
!(child->flags & DF_FIXEDCLASS)) {
result = ENXIO;
}
/*
* The driver returned an error so it
* certainly doesn't match.
@ -2127,14 +2137,6 @@ device_probe_child(device_t dev, device_t child)
* of pri for the first match.
*/
if (best == NULL || result > pri) {
/*
* Probes that return BUS_PROBE_NOWILDCARD
* or lower only match on devices whose
* driver was explicitly specified.
*/
if (result <= BUS_PROBE_NOWILDCARD &&
!(child->flags & DF_FIXEDCLASS))
continue;
best = dl;
pri = result;
continue;