Driver crash with cardbus & auto-configuration

Dorr H. Clark dclark at
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

Dorr H. Clark

Graduate School of Engineering
Santa Clara University
Santa Clara, CA

    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);
-		"%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