cvs commit: src/sys/compat/ndis subr_ndis.c subr_ntoskrnl.c

Bill Paul wpaul at FreeBSD.org
Wed Mar 3 16:17:14 PST 2004


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


More information about the cvs-src mailing list