strange minifilter unload hang

Hi,

In rare cases (1 out of 50-100), one of my filters hangs on unload, AFTER successfully:

  • executes FltUnregisterFilter
  • releases all memory structures, variables, handles etc
  • successfully passes Driver Verifier tests
  • exits the unload routine (I have a KdPrint() as a last line)

After this I see on ‘sc query’ that the driver is NOT running anymore, however when I do a ‘lm’ in WinDbg I see that the image of the driver is still mapped. After this, if I try to restart the driver, fails with various error messages (like file lock conflict).

Any ideas, hints? It is plausible (does it make sense?) that somebody (FLTMGR, SC, WINDOWS etc) holds a pointer on the section object of the image of the driver? How can I find that section object?

thank you very much,

Sandor

I think that if someone is leaking a reference to the DRIVER_OBJECT then it
will not be torn down until that reference goes away and you would see
pretty much exactly what you’re seeing right now…

One more thing I would try on top of the Verifier tests (congrats on passing
those btw!) is to run with a checked filter manager (just copy fltmgr.sys
from the checked windows build corresponding to your image). Also, make sure
to do this on Win7 and verifier and filter manager verifier have both been
improved significantly for win7.

Did you try a !search on the address of your DRIVER_OBJECT ?

Thanks,
Alex.

Hi,

Successfully passes Verifier tests on Win7 + checked build FLTMGR.

However, we are ‘on-track’ with your hints :-).

I inserted a breakpoint right before the driver unload routine exits, and I check there the PointerCount of the DRIVER_OBJECT, then I check it again right after the driver unloads. In successful cases, on the last line of driver unload the PointerCount is 3, and right after the unload is 0 - that is, the DRIVER_OBJECT is released. When the driver hangs, at the last line the PointerCount is 4, and right after the unload is 1 - that is, the DRIVER_OBJECT remains!

Now, I tried to figure out with !search the blocks that refer to DRIVER_OBJECT, but there is a pretty big list and I can’t handle it :-|. Can I share with you? Could you point out some hints?

thank you very much,

Sandor

Hi,

I include also the details with a hanged driver:

0: kd> !object 0xfffffa8002985060
Object: fffffa8002985060 Type: (fffffa800180e080) Driver
ObjectHeader: fffffa8002985030 (new version)
HandleCount: 0 PointerCount: 1
Directory Object: 00000000 Name: XXXXXXXX

0: kd> !search fffffa8002985060
Searching PFNs in range 0000000000000001 - 000000000007BECF for [FFFFFA8002985060 - FFFFFA8002985060]

Pfn Offset Hit Va Pte


0000000000000107 00000520 FFFFFA8002985060 FFFFFFFFFFD0D520 FFFFF6FFFFFFE868
00000000000006D3 000001D8 FFFFFA8002985060 FFFFF980122405D8 FFFFF6FCC0091202
fffff98012240000: Unable to get contents of special pool block
00000000000006D3 00000278 FFFFFA8002985060 FFFFF98012240678 FFFFF6FCC0091202
fffff98012240000: Unable to get contents of special pool block
00000000000006D3 00000438 FFFFFA8002985060 FFFFF98012240838 FFFFF6FCC0091202
fffff98012240000: Unable to get contents of special pool block
0000000000002C20 00000430 FFFFFA8002985060 FFFFF80002C20430 FFFFF6FC00016100
0000000000002C20 00000438 FFFFFA8002985060 FFFFF80002C20438 FFFFF6FC00016100

many more such lines as above

00000000000228F9 00000AE8 FFFFFA8002885060 FFFFF8A005A30AE8 FFFFF6FC5002D180
fffff8a005a30a90+0x58 : FIcs – FileInfo FS-filter Stream Context

00000000000325A0 00000778 FFFFFA8002985070 FFFFF8A0022DA778 FFFFF6FC500116D0
fffff8a0022da770+0x8 : ViMm – Video memory manager

00000000000435E3 00000A50 FFFFFA8002985060 FFFFF8A0075CEA50 FFFFF6FC5003AE70
fffff8a0075cea10+0x40 : PnpC (Free) – PNPMGR target device notify
000000000004448A 00000B00 FFFFFA8002985060 FFFFF8A00758AB00 FFFFF6FC5003AC50
fffff8a00758aac0+0x40 : PnpC – PNPMGR target device notify

– could here (above) be a problem?

0000000000044E7B 00000510 FFFFFA8002985060 FFFFF8A001E14510 FFFFF6FC5000F0A0
fffff8a001e144d0+0x40 : PnpC (Free) – PNPMGR target device notify

000000000004ECA7 00000550 FFFFFA8002985060 FFFFF8A0061BA550 FFFFF6FC50030DD0
fffff8a0061ba510+0x40 : PnpC (Free) – PNPMGR target device notify

000000000005835C 000002F0 FFFFFA8002985060 FFFFF8A008EBD2F0 FFFFF6FC500475E8
fffff8a008ebd2b0+0x40 : PnpC (Free) – PNPMGR target device notify

000000000007A805 00000038 FFFFFA8002905060 FFFFFA8002C05038 FFFFF6FD40016028
fffffa8002bc3000+0x42038 : NV (LargePool) – nVidia video driver
000000000007A817 00000B48 FFFFFA8002905060 FFFFFA8002C17B48 FFFFF6FD400160B8
fffffa8002bc3000+0x54b48 : NV (LargePool) – nVidia video driver
000000000007A824 00000D48 FFFFFA8002905060 FFFFFA8002C24D48 FFFFF6FD40016120
fffffa8002bc3000+0x61d48 : NV (LargePool) – nVidia video driver
000000000007A987 00000D00 FFFFFA8002D85060 FFFFFA8002D87D00 FFFFF6FD40016C38
fffffa8002d87cc0+0x40 : AmdK : No pool tag description
000000000007A987 00000D08 FFFFFA8002D85060 FFFFFA8002D87D08 FFFFF6FD40016C38
fffffa8002d87cc0+0x48 : AmdK : No pool tag description
000000000007AC5C 00000E40 FFFFFA8002985860 FFFFFA800285CE40 FFFFF6FD400142E0
fffffa800285ce30+0x10 : MiSc : No pool tag description
000000000007AC5C 00000E48 FFFFFA8002985860 FFFFFA800285CE48 FFFFF6FD400142E0
fffffa800285ce30+0x18 : MiSc : No pool tag description
000000000007AD85 000001B0 FFFFFA8002985060 FFFFFA80029851B0 FFFFF6FD40014C28
fffffa8002985000+0x1b0 : Driv (Protected) – Driver objects
000000000007B1BB 00000780 FFFFFA8002985060 FFFFFA80025BB780 FFFFF6FD40012DD8
fffffa80025bb720+0x60 : FMfl (Free) – FLT_FILTER structure

any hints?

thank you very much,

Sandor

Hi Sandor,

I’m not sure about this but indeed it does look like PNP somehow got a hold of a pointer to your driver. Perhaps you could do the same search when your driver unloads (when the refcount gets to 0) and compare them (see if PNP still has it). Perhaps PNP has some structures it’s not scrubbing after use and they have a copy of the data but no reference ?..

Hi,

I have found and fixed the issue :slight_smile: It was a race condition, and sometimes I have called IoRegisterPlugPlayNotification() twice for a given volume, and called IoUnregisterPlugPlayNotification() only once :expressionless:

As a hint to MS: I think it could be very easily added to Driver Verifier to check how many PNP notifications does a driver register vs. unregister, and to block unload if there are any callbacks still hanging around.

thank you very much,

Sandor