Date: Tue, 7 Oct 2008 23:17:18 -0700 (PDT) From: "Dorr H. Clark" <dclark@engr.scu.edu> To: freebsd-drivers@freebsd.org Cc: freebsd-bugs@freebsd.org Subject: Driver crash with cardbus & auto-configuration Message-ID: <Pine.GSO.4.21.0810072312220.4889-100000@nova41.dc.engr.scu.edu>
next in thread | raw e-mail | index | archive | help
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) {
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?Pine.GSO.4.21.0810072312220.4889-100000>