Double Free BugCheck c2

Hi,
In my legacy filter driver, I maintain FILE_INFO structure for each file
in lookaside list in NonPaged Memory. This structure has reference count
which is incremented and decremented using Interlock functions. All this
code is protected by FAST_MUTEX. So here is the sequence of operation:

  1. Acquire FAST_MUTEX
  2. Decrement Reference Counter using InterlockedDecrement()
  3. If counter is zero, call ExFreeToNPagedLookasideList().

From the documentation of ExFreeToNPagedLookasideList, the memory is added
to the list if within the limit or memory is freed by call to ExFreePool().

Occasionally, we see Bugcheck c2 which indicates that it is double free. I
verified with !pool command and it says that memory is “free”.

Is there any loop hole in the above logic which can cause memory to be freed
two times?

We only free when counter is 0 and counter is decremented and checked under
protection of FAST_MUTEX. I have checked my code for direct ExFreePool() on
the structure but could not find anything. So we are manipulating structure
using lookaside function calls.

Thanks for help!
Ash

For debugging purposes, I’d swap the lookaside list for direct alloc/free
calls as this might help you catch the issue earlier.

Is this on Vista and later? If so you can try the pool alloc/free log to
find the original free, which is really what matters in this case. The
WinDBG command is “!verifier 80 address”, though your use of the lookaside
list might cause your allocations to not go into the log (which would be
another reason to switch to calling ExAllocatePool/ExFreePool directly).

Lastly, while unrelated to your issue, it’s not necessary to use both a fast
mutex and interlocked operations. If you’re wrapping each
increment/decrement in an acquire of the fast mutex then the mutex is
protecting the count and the interlocked is just wasted overhead.

-scott


Scott Noone
Consulting Associate
OSR Open Systems Resources, Inc.
http://www.osronline.com

“Ashish Goyal” wrote in message
news:xxxxx@ntfsd…
Hi,
In my legacy filter driver, I maintain FILE_INFO structure for each file
in lookaside list in NonPaged Memory. This structure has reference count
which is incremented and decremented using Interlock functions. All this
code is protected by FAST_MUTEX. So here is the sequence of operation:

1) Acquire FAST_MUTEX
2) Decrement Reference Counter using InterlockedDecrement()
3) If counter is zero, call ExFreeToNPagedLookasideList().

From the documentation of ExFreeToNPagedLookasideList, the memory is added
to the list if within the limit or memory is freed by call to ExFreePool().

Occasionally, we see Bugcheck c2 which indicates that it is double free. I
verified with !pool command and it says that memory is “free”.

Is there any loop hole in the above logic which can cause memory to be freed
two times?

We only free when counter is 0 and counter is decremented and checked under
protection of FAST_MUTEX. I have checked my code for direct ExFreePool() on
the structure but could not find anything. So we are manipulating structure
using lookaside function calls.

Thanks for help!
Ash