Date: Wed, 3 Mar 2004 16:17:14 -0800 (PST) From: Bill Paul <wpaul@FreeBSD.org> To: src-committers@FreeBSD.org, cvs-src@FreeBSD.org, cvs-all@FreeBSD.org Subject: cvs commit: src/sys/compat/ndis subr_ndis.c subr_ntoskrnl.c Message-ID: <200403040017.i240HE4Q026154@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
wpaul 2004/03/03 16:17:14 PST FreeBSD src repository Modified files: sys/compat/ndis subr_ndis.c subr_ntoskrnl.c Log: Add sanity checks to the ndis_packet and ndis_buffer pool handling routines to guard against problems caused by (possibly) buggy drivers. The RealTek 8180 wireless driver calls NdisFreeBuffer() to release some of its buffers _after_ it's already called NdisFreeBufferPool() to destroy the pool to which the buffers belong. In our implementation, this error causes NdisFreeBuffer() to touch stale heap memory. If you are running a release kernel, and hence have INVARIANTS et al turned off, it turns out nothing happens. But if you're using a development kernel config with INVARIANTS on, the malloc()/free() sanity checks will scribble over the pool memory with 0xdeadc0de once it's released so that any attempts to touch it will cause a trap, and indeed this is what happens. It happens that I run 5.2-RELEASE on my laptop, so when I tested the rtl8180.sys driver, it worked fine for me, but people trying to run it with development systems checked out or cvsupped from -current would get a page fault on driver load. I can't find any reason why the NDISulator would cause the RealTek driver to do the NdisFreeBufferPool() prematurely, and the same driver obviously works with Windows -- or at least, it doesn't cause a crash: the Microsoft documentation for NdisFreeBufferPool() says that failing to return all buffers to the pool before calling NdisFreeBufferPool() causes a memory leak. I've written to my contacts at RealTek asking them to check if this is indeed a bug in their driver. In the meantime, these new sanity checks will catch this problem and issue a warning rather than causing a trap. The trick is to keep a count of outstanding buffers for each buffer pool, and if the driver tries to call NdisFreeBufferPool() while there are still buffers outstanding, we mark the pool for deletion and then defer destroying it until after the last buffer has been reclaimed. Revision Changes Path 1.49 +76 -2 src/sys/compat/ndis/subr_ndis.c 1.25 +12 -0 src/sys/compat/ndis/subr_ntoskrnl.c
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200403040017.i240HE4Q026154>