Driver crash with cardbus & auto-configuration
Dorr H. Clark
dclark at engr.scu.edu
Wed Oct 8 06:17:21 UTC 2008
Driver crash with cardbus & auto-configuration:
This situation was encountered when trying to use a laptop with
cardbus CIS for the COEN284 "UNIX Kernel Internals" class at SCU.
The corruption was discovered after applying a patch to allow
the cardbus CIS to be parsed (see BUG #115623 ). After a reboot of
the laptop (DELL latitude CPx), the auto-configuration process of
the cardbus XIRCOM RBEM56G provoked a crash.
The root cause of the crash is the corruption of the malloc storage
itself. The corruption happened in the auto-configuration process.
As the kernel is probing various possible devices, one call
corrupts memory, & it was found that bce_probe() is the culprit.
The code causing the crash in the 'bce' driver is only to allow
a debug printf, and therefore can be safely removed.
The explanation of the corruption is as follows: while
probing for child, we normally allocate and deallocate the
softc structure of the corresponding driver. In this
auto-configuration case, the 'sio' driver was probed prior
to the 'bce' driver and the sio driver was allocating the original
'softc' memory. The softc is set with size of 812 bytes
(the sio softc data struct), and the dev->flags is set with
DF_EXTERNALSOFTC. This flag makes sure that the softc is not
deallocated, and the following probe re-uses the same softc.
However, when the bce_probe gets executed, it re-interprets
the softc data structure into a 'struct bce_softc' of size 8852
and then scribbles beyond the end of the original allocation
corrupting memory.
While we encountered this issue with 7.0, it appears that this
is an issue in the latest version and also could be a problem in
the 6.3 release.
A recommended patch for this problem is offered below.
Charles Bransi
Engineer
Dorr H. Clark
Advisor
Graduate School of Engineering
Santa Clara University
Santa Clara, CA
http://www.cse.scu.edu/~dclark/coen_284_FreeBSD/driver_crash.txt
The change is the following:
--- if_bce_orig.c 2008-07-30 21:47:15.000000000 -0700
+++ if_bce.c 2008-08-01 21:02:52.000000000 -0700
@@ -394,27 +394,17 @@
bce_probe(device_t dev)
{
struct bce_type *t;
- struct bce_softc *sc;
char *descbuf;
u16 vid = 0, did = 0, svid = 0, sdid = 0;
t = bce_devs;
- sc = device_get_softc(dev);
- bzero(sc, sizeof(struct bce_softc));
- sc->bce_unit = device_get_unit(dev);
- sc->bce_dev = dev;
-
/* Get the data for the device to be probed. */
vid = pci_get_vendor(dev);
did = pci_get_device(dev);
svid = pci_get_subvendor(dev);
sdid = pci_get_subdevice(dev);
- DBPRINT(sc, BCE_VERBOSE_LOAD,
- "%s(); VID = 0x%04X, DID = 0x%04X, SVID = 0x%04X, "
- "SDID = 0x%04X\n", __FUNCTION__, vid, did, svid, sdid);
-
/* Look through the list of known devices for a match. */
while(t->bce_name != NULL) {
More information about the freebsd-bugs
mailing list