False 0xC4 alarm from Driver Verifier?

I suspect that I have landed on a problem in Driver Verifier. I think it is giving me a false alarm of a memory overrun. I hope someone can confirm that this indeed can happen, or even better, prove that I am wrong and convince me that the bug is in our driver :slight_smile:

Bug Check:

DRIVER_VERIFIER_DETECTED_VIOLATION (c4)

Arguments:
Arg1: 00000054, freeing memory where the caller has written past the end of the
allocation, overwriting our stored virtual address.
Arg2: a4ca6fc8, base address of the allocation,
Arg3: 00000020, pool hash size,
Arg4: 000000c9, listindex.

Environment: Windows 2000 Professional SP4

(Full WinDbg output at the end of the message.)

This bug check occurred once. I haven't been able to reproduce it yet but I have a full memory dump. The stack trace shows that this bug check is triggered when the driver frees a paged pool allocation by calling ExFreePool. In this case, the requested allocation size was 0x34 bytes.

Clearly, the bug check suggests that the driver has written past the end of the allocation. But this does not make sense since Driver Verifier is running with Special Pool enabled. It should catch memory overruns at the time they occur, not when the driver is freeing the memory. (I am using the default "Verify End" mode.)

Examining the memory contents of this buffer further confirm that Special Pool is indeed in effect here. The buffer has been allocated at the very end of a page and the next page has been marked "no access". Therefore, if the driver had really written past the end of the buffer, it should have caused a bug check at that time, not later when the buffer is freed.

Memory contents around the buffer:

a4ca5000 - a4ca5ffff NO ACCESS

a4ca6000 34 c0 00 af 4d 43 46 50 c9 00 00 00 88 ff f6 f8 4...MCFP........
a4ca6010 af af af af af af af af af af af af af af af af ................

a4ca6020 - a4ca6fb0 REPEATS THE "af" PATTERN

a4ca6fb0 af af af af af af af af af af af af af af af af ................
a4ca6fc0 af af af af af af af af 5c 00 4e 00 6f 00 74 00 .........N.o.t.
a4ca6fd0 69 00 66 00 69 00 6b 00 61 00 61 00 74 00 69 00 i.f.i.k.a.a.t.i.
a4ca6fe0 6f 00 74 00 5c 00 64 00 65 00 73 00 6b 00 74 00 o.t..d.e.s.k.t.
a4ca6ff0 6f 00 70 00 2e 00 69 00 6e 00 69 00 af af af af o.p...i.n.i.....

a4ca7000 - a4ca7ffff NO ACCESS

The actual buffer begins at a4ca6fc8. To me, the buffer itself and the memory around it seems to be perfectly OK, and the special no-access pages precede and follow the actual page as expected.

So, how is it possible that I am getting bug check 0xC4 for this buffer? Bug check 0xC4 refers to "Memory Pool tracking", which is a less accurate method for detecting memory overruns.

A related article in the NTFSD group suggests an explanation that would apply to my situation as well: I am running two independent builds of the same driver, meaning that two drivers with the same name are loaded. Driver Verifier has been enabled for the name only, I have not specified absolute paths to the drivers. Thus, Driver Verifier should be monitoring both instances of this driver. (Article: http://www.osronline.com/lists_archive/ntfsd/thread1122.html)

Is it a known problem that Driver Verifier can fail in this scenario (two or more identically named drivers loaded and monitored)?

Any help is greatly appreciated!

Antti Nivala
Motive Systems


Full WinDbg output:

1: kd> !analyze -v
*******************************************************************************
* *
* Bugcheck Analysis *
* *
*******************************************************************************

DRIVER_VERIFIER_DETECTED_VIOLATION (c4)
A device driver attempting to corrupt the system has been caught. This is
because the driver was specified in the registry as being suspect (by the
administrator) and the kernel has enabled substantial checking of this driver.
If the driver attempts to corrupt the system, bugchecks 0xC4, 0xC1 and 0xA will
be among the most commonly seen crashes.
Parameter 1 = 0x1000 .. 0x1020 - deadlock verifier error codes.
Typically the code is 0x1001 (deadlock detected) and you can
issue a '!deadlock' KD command to get more information.
Arguments:
Arg1: 00000054, freeing memory where the caller has written past the end of the
allocation, overwriting our stored virtual address.
Arg2: a4ca6fc8, base address of the allocation,
Arg3: 00000020, pool hash size,
Arg4: 000000c9, listindex.

Debugging Details:

BUGCHECK_STR: 0xc4_54

WRITE_ADDRESS: a4ca6fc8 Special pool

DEFAULT_BUCKET_ID: DRIVER_FAULT

LAST_CONTROL_TRANSFER: from 80530179 to 8052fcde

STACK_TEXT:
f3089bdc 80530179 f8f6ff88 a4ca6fc8 000000c9 nt!ViReleasePoolAllocation+0x44
f3089c00 80536d5b a4ca6fc8 00000000 00000001 nt!VerifierFreeTrackedPool+0xb1
f3089c40 8046cdb2 a4ca6fc8 00000000 00000000 nt!MmFreeSpecialPool+0x1c1
f3089c6c 8053022d a4ca6fc8 00000000 f3089cc4 nt!ExFreePoolWithTag+0x22
f3089c7c 8053020b a4ca6fc8 00000000 f2f4d73b nt!VerifierFreePoolWithTag+0x1f
f3089c88 f2f4d73b a4ca6fc8 00000000 00000000 nt!VerifierFreePool+0x1f
f3089cc4 f2f3fd45 a545efe0 00000000 00000000 mffsd!MFFSDDestroyCCB+0x123
f3089d14 f2f43c00 afc94cf0 00000000 00000000 mffsd!MFFSDCloseCommon+0x56f
f3089d58 f2f62015 af670ff0 00000000 00000000 mffsd!MFFSDProcessDelayedRequest+0x154
f3089da8 8045643c ac81efd8 00000000 00000000 mffsd!MFFSDThreadProcWorkerThread+0x1c8
f3089ddc 8046b4d6 f2f61e4d ac81efd8 00000000 nt!PspSystemThreadStartup+0x54
00000000 00000000 00000000 00000000 00000000 nt!KiThreadStartup+0x16

FOLLOWUP_IP:
mffsd!MFFSDDestroyCCB+123
f2f4d73b 8b4508 mov eax,[ebp+0x8]

FOLLOWUP_NAME: MachineOwner

SYMBOL_NAME: mffsd!MFFSDDestroyCCB+123

MODULE_NAME: mffsd

IMAGE_NAME: mffsd.sys

DEBUG_FLR_IMAGE_TIMESTAMP: 41763559

STACK_COMMAND: kb

BUCKET_ID: 0xc4_54_W_mffsd!MFFSDDestroyCCB+123

Followup: MachineOwner