Detecting recursive spinlock acquisition with Driver Verifier in Windows 8.1 Preview

Hi,

I'm trying to experiment with Driver Verifier's DDI compliance checking and additional compliance checking rules. The docs [1] [2] explain that in Windows 8.1 Preview, Driver Verifier should be able to catch a recursive spinlock acquisition as a violation of DDI compliance rules.

I've modified the Notmyfault application (and driver) with an additional option that causes a deadlock by recursively acquiring a spinlock:

VOID
SpinlockDeadlock(
VOID
)
{
KIRQL OldIrql;
static KSPIN_LOCK SpinLock;

KeInitializeSpinLock( &SpinLock );

// Attemps to acquire a spinlock twice. This is guaranteed to cause
// a deadlock immediately.
KeAcquireSpinLock( &SpinLock, &OldIrql );
KeAcquireSpinLock (&SpinLock, &OldIrql );

KeReleaseSpinLock (&SpinLock, OldIrql );
}

Driver Verifier is enabled for the myfault.sys driver with both DDI compliance checking and additional DDI compliance checking:

kd> !verifier
Verify Level a0000 ... enabled options are:
DDI compliance checking enabled

Also, I can see the load message when myfault.sys is loaded, telling me that the DV rules are in effect.

Nonetheless, DV does not detect the recursive spinlock acquisition and the system just hangs. Here is the call stack from the kernel debugger at the point of the hang (you can see DV's injected frames 08, 09, 0a):

kd> kn
*** Stack trace for last set context - .thread/.cxr resets it

Child-SP RetAddr Call Site

00 fffff8008639bc88 fffff80084997940 nt!DbgBreakPointWithStatus
01 fffff8008639bc90 fffff8008489c9ee nt! ?? ::FNODOBFM::string'+0x23300 02 fffff8008639bd20 fffff80084faaf1f nt!KeClockInterruptNotify+0x73e 03 fffff8008639bf40 fffff800848f5cc2 hal!HalpTimerClockInterrupt+0x4f 04 fffff8008639bf70 fffff8008496522a nt!KiCallInterruptServiceRoutine+0x122 05 fffff8008639bfb0 fffff8008496560f nt!KiInterruptSubDispatchNoLockNoEtw+0xea 06 ffffd0002116f730 fffff800848f5ee0 nt!KiInterruptDispatchLBControl+0x11f 07 ffffd0002116f8c0 fffff800848f5ea2 nt!KxWaitForSpinLockAndAcquire+0x20 08 ffffd0002116f8f0 fffff800002e9559 nt!KeAcquireSpinLockRaiseToDpc+0x32 09 ffffd0002116f920 fffff80084e959cb VerifierExt!KeAcquireSpinLockRaiseToDpc_wrapper+0x129 0a ffffd0002116f970 fffff800025f2385 nt!VerifierKeAcquireSpinLockRaiseToDpc+0x5f 0b ffffd0002116f9b0 fffff800025f24ff myfault!MyfaultDeviceControl+0x351 0c ffffd0002116fb10 fffff80084e825a8 myfault!MyfaultDispatch+0xb7 0d ffffd0002116fb70 fffff80084becbb3 nt!IovCallDriver+0xb4 0e ffffd0002116fbc0 fffff80084beddaa nt!IopXxxControlFile+0x8c3 0f ffffd0002116fd60 fffff8008496f6b3 nt!NtDeviceIoControlFile+0x56 10 ffffd0002116fdd0 00007fff4f53b12a nt!KiSystemServiceCopyEnd+0x13 11 000000000050ef48 00007fff4c962f83 ntdll!NtDeviceIoControlFile+0xa 12 000000000050ef50 00007fff4f3614f0 KERNELBASE!DeviceIoControl+0x73 13 000000000050efc0 00007ff7da59275b KERNEL32!DeviceIoControlImplementation+0x74 14 000000000050f010 00007fff4edd182e NotMyfault!HangDialogProc+0x93 15 000000000050f090 00007fff4edd160c USER32!UserCallDlgProcCheckWow+0x112 16 000000000050f160 00007fff4ee23111 USER32!DefDlgProcWorker+0xb4 17 000000000050f220 00007fff4edc27a4 USER32!DefDlgProcA+0x39 18 000000000050f260 00007fff4edc4372 USER32!UserCallWinProcCheckWow+0x140 19 000000000050f320 00007fff4edc443d USER32!DispatchClientMessage+0xa2 1a 000000000050f380 00007fff4f53cecf USER32!_fnDWORD+0x2d 1b 000000000050f3e0 00007fff4edc1fca ntdll!KiUserCallbackDispatcherContinue 1c 000000000050f468 00007fff4edc50c3 USER32!NtUserMessageCall+0xa 1d 000000000050f470 00007fff4edc5201 USER32!SendMessageWorker+0xfb 1e 000000000050f500 00007fff4ae59fa4 USER32!SendMessageW+0x105 1f 000000000050f560 00007fff4ae59f7f COMCTL32!Button_ReleaseCapture+0xd0 20 000000000050f5a0 00007fff4edc27a4 COMCTL32!Button_WndProc+0x8d3 21 000000000050f6c0 00007fff4edc2257 USER32!UserCallWinProcCheckWow+0x140 22 000000000050f780 00007fff4eddd831 USER32!DispatchMessageWorker+0x1a7 23 000000000050f800 00007fff4ae6919e USER32!IsDialogMessageW+0x127 24 000000000050f860 00007fff4ae69129 COMCTL32!Prop_IsDialogMessage+0x4a 25 000000000050f890 00007fff4ae68e71 COMCTL32!_RealPropertySheet+0x28b 26 000000000050f960 00007fff4aeda157 COMCTL32!_PropertySheet+0x49 27 000000000050f990 00007ff7da592c2c COMCTL32!PropertySheetA+0x53 28 000000000050fa30 00007ff7da592e26 NotMyfault!WinMain+0x248 29 000000000050fc40 00007fff4f361331 NotMyfault!__mainCRTStartup+0x18e 2a 000000000050fd00 00007fff4f508cd5 KERNEL32!BaseThreadInitThunk+0xd 2b 000000000050fd30 00000000`00000000 ntdll!RtlUserThreadStart+0x1d

Am I doing something wrong here? Am I wrong in reading the documentation that DV should be able to catch this simple violation?

Thanks in advance,
Sasha

[1] SpinLock Rule (WDM) - Windows drivers | Microsoft Learn
[2] DDI Compliance Checking - Windows drivers | Microsoft Learn

Did you enable deadlock detection?

Hi Sasha,

We were not able to repro the issue using your code, i.e., the DDI compliance rules are able to bugcheck as expected. If you can share your sample, we will be able to look more.

Thanks,
Juncao

-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of xxxxx@gmail.com
Sent: Thursday, August 1, 2013 1:46 AM
To: Windows System Software Devs Interest List
Subject: [ntdev] Detecting recursive spinlock acquisition with Driver Verifier in Windows 8.1 Preview

Hi,

I'm trying to experiment with Driver Verifier's DDI compliance checking and additional compliance checking rules. The docs [1] [2] explain that in Windows 8.1 Preview, Driver Verifier should be able to catch a recursive spinlock acquisition as a violation of DDI compliance rules.

I've modified the Notmyfault application (and driver) with an additional option that causes a deadlock by recursively acquiring a spinlock:

VOID
SpinlockDeadlock(
VOID
)
{
KIRQL OldIrql;
static KSPIN_LOCK SpinLock;

KeInitializeSpinLock( &SpinLock );

// Attemps to acquire a spinlock twice. This is guaranteed to cause
// a deadlock immediately.
KeAcquireSpinLock( &SpinLock, &OldIrql );
KeAcquireSpinLock (&SpinLock, &OldIrql );

KeReleaseSpinLock (&SpinLock, OldIrql ); }

Driver Verifier is enabled for the myfault.sys driver with both DDI compliance checking and additional DDI compliance checking:

kd> !verifier
Verify Level a0000 ... enabled options are:
DDI compliance checking enabled

Also, I can see the load message when myfault.sys is loaded, telling me that the DV rules are in effect.

Nonetheless, DV does not detect the recursive spinlock acquisition and the system just hangs. Here is the call stack from the kernel debugger at the point of the hang (you can see DV's injected frames 08, 09, 0a):

kd> kn
*** Stack trace for last set context - .thread/.cxr resets it

Child-SP RetAddr Call Site

00 fffff8008639bc88 fffff80084997940 nt!DbgBreakPointWithStatus
01 fffff8008639bc90 fffff8008489c9ee nt! ?? ::FNODOBFM::string'+0x23300 02 fffff8008639bd20 fffff80084faaf1f nt!KeClockInterruptNotify+0x73e 03 fffff8008639bf40 fffff800848f5cc2 hal!HalpTimerClockInterrupt+0x4f 04 fffff8008639bf70 fffff8008496522a nt!KiCallInterruptServiceRoutine+0x122 05 fffff8008639bfb0 fffff8008496560f nt!KiInterruptSubDispatchNoLockNoEtw+0xea 06 ffffd0002116f730 fffff800848f5ee0 nt!KiInterruptDispatchLBControl+0x11f 07 ffffd0002116f8c0 fffff800848f5ea2 nt!KxWaitForSpinLockAndAcquire+0x20 08 ffffd0002116f8f0 fffff800002e9559 nt!KeAcquireSpinLockRaiseToDpc+0x32 09 ffffd0002116f920 fffff80084e959cb VerifierExt!KeAcquireSpinLockRaiseToDpc_wrapper+0x129 0a ffffd0002116f970 fffff800025f2385 nt!VerifierKeAcquireSpinLockRaiseToDpc+0x5f 0b ffffd0002116f9b0 fffff800025f24ff myfault!MyfaultDeviceControl+0x351 0c ffffd0002116fb10 fffff80084e825a8 myfault!MyfaultDispatch+0xb7 0d ffffd0002116fb70 fffff80084becbb3 nt!IovCallDriver+0xb4 0e ffffd0002116fbc0 fffff80084beddaa nt!IopXxxControlFile+0x8c3 0f ffffd0002116fd60 fffff8008496f6b3 nt!NtDeviceIoControlFile+0x56 10 ffffd0002116fdd0 00007fff4f53b12a nt!KiSystemServiceCopyEnd+0x13 11 000000000050ef48 00007fff4c962f83 ntdll!NtDeviceIoControlFile+0xa 12 000000000050ef50 00007fff4f3614f0 KERNELBASE!DeviceIoControl+0x73 13 000000000050efc0 00007ff7da59275b KERNEL32!DeviceIoControlImplementation+0x74 14 000000000050f010 00007fff4edd182e NotMyfault!HangDialogProc+0x93 15 000000000050f090 00007fff4edd160c USER32!UserCallDlgProcCheckWow+0x112 16 000000000050f160 00007fff4ee23111 USER32!DefDlgProcWorker+0xb4 17 000000000050f220 00007fff4edc27a4 USER32!DefDlgProcA+0x39 18 000000000050f260 00007fff4edc4372 USER32!UserCallWinProcCheckWow+0x140 19 000000000050f320 00007fff4edc443d USER32!DispatchClientMessage+0xa2 1a 000000000050f380 00007fff4f53cecf USER32!_fnDWORD+0x2d 1b 000000000050f3e0 00007fff4edc1fca ntdll!KiUserCallbackDispatcherContinue 1c 000000000050f468 00007fff4edc50c3 USER32!NtUserMessageCall+0xa 1d 000000000050f470 00007fff4edc5201 USER32!SendMessageWorker+0xfb 1e 000000000050f500 00007fff4ae59fa4 USER32!SendMessageW+0x105 1f 000000000050f560 00007fff4ae59f7f COMCTL32!Button_ReleaseCapture+0xd0 20 000000000050f5a0 00007fff4edc27a4 COMCTL32!Button_WndProc+0x8d3 21 000000000050f6c0 00007fff4edc2257 USER32!UserCallWinProcCheckWow+0x140 22 000000000050f780 00007fff4eddd831 USER32!DispatchMessageWorker+0x1a7 23 000000000050f800 00007fff4ae6919e USER32!IsDialogMessageW+0x127 24 000000000050f860 00007fff4ae69129 COMCTL32!Prop_IsDialogMessage+0x4a 25 000000000050f890 00007fff4ae68e71 COMCTL32!_RealPropertySheet+0x28b 26 000000000050f960 00007fff4aeda157 COMCTL32!_PropertySheet+0x49 27 000000000050f990 00007ff7da592c2c COMCTL32!PropertySheetA+0x53 28 000000000050fa30 00007ff7da592e26 NotMyfault!WinMain+0x248 29 000000000050fc40 00007fff4f361331 NotMyfault!__mainCRTStartup+0x18e 2a 000000000050fd00 00007fff4f508cd5 KERNEL32!BaseThreadInitThunk+0xd 2b 000000000050fd30 00000000`00000000 ntdll!RtlUserThreadStart+0x1d

Am I doing something wrong here? Am I wrong in reading the documentation that DV should be able to catch this simple violation?

Thanks in advance,
Sasha

[1] SpinLock Rule (WDM) - Windows drivers | Microsoft Learn
[2] DDI Compliance Checking - Windows drivers | Microsoft Learn


NTDEV is sponsored by OSR

Visit the list at: http://www.osronline.com/showlists.cfm?list=ntdev

OSR is HIRING!! See Careers – OSR

For our schedule of WDF, WDM, debugging and other seminars visit:

To unsubscribe, visit the List Server section of OSR Online at ListServer/Forum

> The docs [1] [2] explain that in Windows 8.1 Preview, Driver Verifier should be able to

catch a recursive spinlock acquisition as a violation of DDI compliance rules.

Why do you think you need a Verifier here, in the first place???

Verifier is good for catching random bugs like page faults at elevated IRQL, i.e.the ones that may or may not
result in BSOD on any particular occasion, depending on the situation. Verifier ensures that bugs like that
result in BSOD unconditionally (in this particular example, by paging out pageable memory).

However, recursive spinlock acquisition is not a random bug and will result in a deadlock unconditionally.
Therefore, you don’t seem to need any tools to detect it, right…

Anton Bassov

Anton:

  1. This is for demonstration purposes. DV has this feature, so I wanted to
    make sure I can demonstrate that it works (in a training course).

  2. A crash induced by DV is better than a random system hang. Also, I would
    expect DV to specify that the cause is a recursive spinlock acquisition.
    When you just inspect the hang, you see a processor waiting for a spinlock

  • you don’t really know why it’s not being released and by whom.

On Fri, Aug 2, 2013 at 6:06 AM, wrote:

> > The docs [1] [2] explain that in Windows 8.1 Preview, Driver Verifier
> should be able to
> > catch a recursive spinlock acquisition as a violation of DDI compliance
> rules.
>
> Why do you think you need a Verifier here, in the first place???
>
>
> Verifier is good for catching random bugs like page faults at elevated
> IRQL, i.e.the ones that may or may not
> result in BSOD on any particular occasion, depending on the situation.
> Verifier ensures that bugs like that
> result in BSOD unconditionally (in this particular example, by paging out
> pageable memory).
>
>
> However, recursive spinlock acquisition is not a random bug and will
> result in a deadlock unconditionally.
> Therefore, you don’t seem to need any tools to detect it, right…
>
>
>
> Anton Bassov
>
> —
> NTDEV is sponsored by OSR
>
> Visit the list at: http://www.osronline.com/showlists.cfm?list=ntdev
>
> OSR is HIRING!! See http://www.osr.com/careers
>
> For our schedule of WDF, WDM, debugging and other seminars visit:
> http://www.osr.com/seminars
>
> To unsubscribe, visit the List Server section of OSR Online at
> http://www.osronline.com/page.cfm?name=ListServer
>


Sasha Goldshtein | CTO, Sela Group | Microsoft C# MVP | blog.sashag.net |
@goldshtn http:</http:>

DV’s deadlock detection does not detect this (the docs are unclear on this,
but I tried and it didn’t). On the other hand, DDI compliance checking
should, as per the docs.

On Thu, Aug 1, 2013 at 9:58 PM, wrote:

> Did you enable deadlock detection?
>
> —
> NTDEV is sponsored by OSR
>
> Visit the list at: http://www.osronline.com/showlists.cfm?list=ntdev
>
> OSR is HIRING!! See http://www.osr.com/careers
>
> For our schedule of WDF, WDM, debugging and other seminars visit:
> http://www.osr.com/seminars
>
> To unsubscribe, visit the List Server section of OSR Online at
> http://www.osronline.com/page.cfm?name=ListServer
>


Sasha Goldshtein | CTO, Sela Group | Microsoft C# MVP | blog.sashag.net |
@goldshtn http:</http:>

Juncao, thank you for your attention to this. Generally this is the
modified Notmyfault sample by Sysinternals. You can find the sources here:
https://dl.dropboxusercontent.com/u/11349479/Notmyfault2_sources.zip

The SpinlockDeadlock function in the driver induces the deadlock. In the
GUI, the “Hang with Spinlock” option on the Hang tab invokes the driver.

On Thu, Aug 1, 2013 at 11:52 PM, Juncao Li wrote:

> Hi Sasha,
>
> We were not able to repro the issue using your code, i.e., the DDI
> compliance rules are able to bugcheck as expected. If you can share your
> sample, we will be able to look more.
>
> Thanks,
> Juncao
>
> -----Original Message-----
> From: xxxxx@lists.osr.com [mailto:
> xxxxx@lists.osr.com] On Behalf Of xxxxx@gmail.com
> Sent: Thursday, August 1, 2013 1:46 AM
> To: Windows System Software Devs Interest List
> Subject: [ntdev] Detecting recursive spinlock acquisition with Driver
> Verifier in Windows 8.1 Preview
>
> Hi,
>
> I’m trying to experiment with Driver Verifier’s DDI compliance checking
> and additional compliance checking rules. The docs [1] [2] explain that in
> Windows 8.1 Preview, Driver Verifier should be able to catch a recursive
> spinlock acquisition as a violation of DDI compliance rules.
>
> I’ve modified the Notmyfault application (and driver) with an additional
> option that causes a deadlock by recursively acquiring a spinlock:
>
> VOID
> SpinlockDeadlock(
> VOID
> )
> {
> KIRQL OldIrql;
> static KSPIN_LOCK SpinLock;
>
> KeInitializeSpinLock( &SpinLock );
>
> // Attemps to acquire a spinlock twice. This is guaranteed to cause
> // a deadlock immediately.
> KeAcquireSpinLock( &SpinLock, &OldIrql );
> KeAcquireSpinLock (&SpinLock, &OldIrql );
>
> KeReleaseSpinLock (&SpinLock, OldIrql ); }
>
> Driver Verifier is enabled for the myfault.sys driver with both DDI
> compliance checking and additional DDI compliance checking:
>
> kd> !verifier
> Verify Level a0000 … enabled options are:
> DDI compliance checking enabled
>
> Also, I can see the load message when myfault.sys is loaded, telling me
> that the DV rules are in effect.
>
> Nonetheless, DV does not detect the recursive spinlock acquisition and the
> system just hangs. Here is the call stack from the kernel debugger at the
> point of the hang (you can see DV’s injected frames 08, 09, 0a):
>
> kd> kn
> *** Stack trace for last set context - .thread/.cxr resets it
> # Child-SP RetAddr Call Site
> 00 fffff8008639bc88 fffff80084997940 nt!DbgBreakPointWithStatus
> 01 fffff8008639bc90 fffff8008489c9ee nt! ?? ::FNODOBFM::string'+0x23300<br>&gt; 02 fffff8008639bd20 fffff80084faaf1f nt!KeClockInterruptNotify+0x73e<br>&gt; 03 fffff8008639bf40 fffff800848f5cc2 hal!HalpTimerClockInterrupt+0x4f<br>&gt; 04 fffff8008639bf70 fffff8008496522a<br>&gt; nt!KiCallInterruptServiceRoutine+0x122<br>&gt; 05 fffff8008639bfb0 fffff8008496560f<br>&gt; nt!KiInterruptSubDispatchNoLockNoEtw+0xea<br>&gt; 06 ffffd0002116f730 fffff800848f5ee0<br>&gt; nt!KiInterruptDispatchLBControl+0x11f<br>&gt; 07 ffffd0002116f8c0 fffff800848f5ea2 nt!KxWaitForSpinLockAndAcquire+0x20<br>&gt; 08 ffffd0002116f8f0 fffff800002e9559 nt!KeAcquireSpinLockRaiseToDpc+0x32<br>&gt; 09 ffffd0002116f920 fffff80084e959cb<br>&gt; VerifierExt!KeAcquireSpinLockRaiseToDpc_wrapper+0x129<br>&gt; 0a ffffd0002116f970 fffff800025f2385<br>&gt; nt!VerifierKeAcquireSpinLockRaiseToDpc+0x5f<br>&gt; 0b ffffd0002116f9b0 fffff800025f24ff myfault!MyfaultDeviceControl+0x351<br>&gt; 0c ffffd0002116fb10 fffff80084e825a8 myfault!MyfaultDispatch+0xb7 0d<br>&gt; ffffd0002116fb70 fffff80084becbb3 nt!IovCallDriver+0xb4 0e<br>&gt; ffffd0002116fbc0 fffff80084beddaa nt!IopXxxControlFile+0x8c3 0f<br>&gt; ffffd0002116fd60 fffff8008496f6b3 nt!NtDeviceIoControlFile+0x56<br>&gt; 10 ffffd0002116fdd0 00007fff4f53b12a nt!KiSystemServiceCopyEnd+0x13<br>&gt; 11 000000000050ef48 00007fff4c962f83 ntdll!NtDeviceIoControlFile+0xa<br>&gt; 12 000000000050ef50 00007fff4f3614f0 KERNELBASE!DeviceIoControl+0x73<br>&gt; 13 000000000050efc0 00007ff7da59275b<br>&gt; KERNEL32!DeviceIoControlImplementation+0x74<br>&gt; 14 000000000050f010 00007fff4edd182e NotMyfault!HangDialogProc+0x93<br>&gt; 15 000000000050f090 00007fff4edd160c USER32!UserCallDlgProcCheckWow+0x112<br>&gt; 16 000000000050f160 00007fff4ee23111 USER32!DefDlgProcWorker+0xb4<br>&gt; 17 000000000050f220 00007fff4edc27a4 USER32!DefDlgProcA+0x39<br>&gt; 18 000000000050f260 00007fff4edc4372 USER32!UserCallWinProcCheckWow+0x140<br>&gt; 19 000000000050f320 00007fff4edc443d USER32!DispatchClientMessage+0xa2<br>&gt; 1a 000000000050f380 00007fff4f53cecf USER32!_fnDWORD+0x2d 1b<br>&gt; 000000000050f3e0 00007fff4edc1fca ntdll!KiUserCallbackDispatcherContinue<br>&gt; 1c 000000000050f468 00007fff4edc50c3 USER32!NtUserMessageCall+0xa 1d<br>&gt; 000000000050f470 00007fff4edc5201 USER32!SendMessageWorker+0xfb 1e<br>&gt; 000000000050f500 00007fff4ae59fa4 USER32!SendMessageW+0x105 1f<br>&gt; 000000000050f560 00007fff4ae59f7f COMCTL32!Button_ReleaseCapture+0xd0<br>&gt; 20 000000000050f5a0 00007fff4edc27a4 COMCTL32!Button_WndProc+0x8d3<br>&gt; 21 000000000050f6c0 00007fff4edc2257 USER32!UserCallWinProcCheckWow+0x140<br>&gt; 22 000000000050f780 00007fff4eddd831 USER32!DispatchMessageWorker+0x1a7<br>&gt; 23 000000000050f800 00007fff4ae6919e USER32!IsDialogMessageW+0x127<br>&gt; 24 000000000050f860 00007fff4ae69129 COMCTL32!Prop_IsDialogMessage+0x4a<br>&gt; 25 000000000050f890 00007fff4ae68e71 COMCTL32!_RealPropertySheet+0x28b<br>&gt; 26 000000000050f960 00007fff4aeda157 COMCTL32!_PropertySheet+0x49<br>&gt; 27 000000000050f990 00007ff7da592c2c COMCTL32!PropertySheetA+0x53<br>&gt; 28 000000000050fa30 00007ff7da592e26 NotMyfault!WinMain+0x248<br>&gt; 29 000000000050fc40 00007fff4f361331 NotMyfault!__mainCRTStartup+0x18e<br>&gt; 2a 000000000050fd00 00007fff4f508cd5 KERNEL32!BaseThreadInitThunk+0xd 2b<br>&gt; 000000000050fd30 00000000`00000000 ntdll!RtlUserThreadStart+0x1d
>
> Am I doing something wrong here? Am I wrong in reading the documentation
> that DV should be able to catch this simple violation?
>
> Thanks in advance,
> Sasha
>
> [1]
> http://msdn.microsoft.com/en-us/library/windows/hardware/ff551861(v=vs.85).aspx
> [2]
> http://msdn.microsoft.com/en-us/library/windows/hardware/hh454208(v=vs.85).aspx
>
> —
> NTDEV is sponsored by OSR
>
> Visit the list at: http://www.osronline.com/showlists.cfm?list=ntdev
>
> OSR is HIRING!! See http://www.osr.com/careers
>
> For our schedule of WDF, WDM, debugging and other seminars visit:
> http://www.osr.com/seminars
>
> To unsubscribe, visit the List Server section of OSR Online at
> http://www.osronline.com/page.cfm?name=ListServer
>
>
>
> —
> NTDEV is sponsored by OSR
>
> Visit the list at: http://www.osronline.com/showlists.cfm?list=ntdev
>
> OSR is HIRING!! See http://www.osr.com/careers
>
> For our schedule of WDF, WDM, debugging and other seminars visit:
> http://www.osr.com/seminars
>
> To unsubscribe, visit the List Server section of OSR Online at
> http://www.osronline.com/page.cfm?name=ListServer
>


Sasha Goldshtein | CTO, Sela Group | Microsoft C# MVP | blog.sashag.net |
@goldshtn http:</http:>

>

> The docs [1] [2] explain that in Windows 8.1 Preview, Driver Verifier should
be able to
> catch a recursive spinlock acquisition as a violation of DDI compliance rules.

Why do you think you need a Verifier here, in the first place???

Verifier is good for catching random bugs like page faults at elevated IRQL,
i.e.the ones that may or may not
result in BSOD on any particular occasion, depending on the situation. Verifier
ensures that bugs like that
result in BSOD unconditionally (in this particular example, by paging out
pageable memory).

However, recursive spinlock acquisition is not a random bug and will result in
a deadlock unconditionally.
Therefore, you don’t seem to need any tools to detect it, right…

Isn’t the outcome of a recursive spinlock acquire on machine not running the verifier a frozen machine? A BSoD + crash dump seems a much better outcome to me.

James

> Isn’t the outcome of a recursive spinlock acquire on machine not running the verifier a frozen machine?

It is, but, unlike nasty random bugs that reveal themselves only once in a while under some specific circumstances, this scenario is unconditional and 100% reproducible. Therefore, there is simply no need
to simulate these circumstances the way Verifier does - the machine will hang whenever you load your driver…

A BSoD + crash dump seems a much better outcome to me.

Agreed…

Anton Bassov

Hi Sasha,

This sample reveals an issue in DV’s dispatch routine interception model. We will fix it.

To unblock you, you can move the yellow code before the call to IoCreateDevice(…).

NTSTATUS

DriverEntry(

IN PDRIVER_OBJECT DriverObject,

IN PUNICODE_STRING RegistryPath

)

{

NTSTATUS status;

WCHAR deviceNameBuffer = L"\Device\Myfault<file:>“;

UNICODE_STRING deviceNameUnicodeString;

WCHAR deviceLinkBuffer = L”\DosDevices\Myfault<file:>";

UNICODE_STRING deviceLinkUnicodeString;

PDEVICE_OBJECT interfaceDevice = NULL;

ULONG startType, demandStart;

RTL_QUERY_REGISTRY_TABLE paramTable[2];

UNICODE_STRING registryPath;

LARGE_INTEGER crashTime;

//

// Create a named device object

//

RtlInitUnicodeString (&deviceNameUnicodeString,

deviceNameBuffer );

status = IoCreateDevice ( DriverObject,

0,

&deviceNameUnicodeString,

FILE_DEVICE_MYFAULT,

0,

TRUE,

&interfaceDevice );

if (NT_SUCCESS(status)) {

//

// Create a symbolic link that the GUI can specify to gain access

// to this driver/device

//

RtlInitUnicodeString (&deviceLinkUnicodeString,

deviceLinkBuffer );

status = IoCreateSymbolicLink (&deviceLinkUnicodeString,

&deviceNameUnicodeString );

//

// Create dispatch points for all routines that must be Myfaultd

//

DriverObject->MajorFunction[IRP_MJ_CREATE] =

DriverObject->MajorFunction[IRP_MJ_CLOSE] =

DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = MyfaultDispatch;

DriverObject->DriverUnload = MyfaultUnload;

}

if (!NT_SUCCESS(status)) {

//

// Something went wrong, so clean up

//

if( interfaceDevice ) {

IoDeleteDevice( interfaceDevice );

}

}

}

Thanks,
Juncao

From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of Sasha Goldshtein
Sent: Thursday, August 1, 2013 9:36 PM
To: Windows System Software Devs Interest List
Cc: Nancy Wu
Subject: Re: [ntdev] Detecting recursive spinlock acquisition with Driver Verifier in Windows 8.1 Preview

Juncao, thank you for your attention to this. Generally this is the modified Notmyfault sample by Sysinternals. You can find the sources here: https://dl.dropboxusercontent.com/u/11349479/Notmyfault2_sources.zip

The SpinlockDeadlock function in the driver induces the deadlock. In the GUI, the “Hang with Spinlock” option on the Hang tab invokes the driver.

On Thu, Aug 1, 2013 at 11:52 PM, Juncao Li > wrote:
Hi Sasha,

We were not able to repro the issue using your code, i.e., the DDI compliance rules are able to bugcheck as expected. If you can share your sample, we will be able to look more.

Thanks,
Juncao

-----Original Message-----
From: xxxxx@lists.osr.commailto:xxxxx [mailto:xxxxx@lists.osr.commailto:xxxxx] On Behalf Of xxxxx@gmail.commailto:xxxxx
Sent: Thursday, August 1, 2013 1:46 AM
To: Windows System Software Devs Interest List
Subject: [ntdev] Detecting recursive spinlock acquisition with Driver Verifier in Windows 8.1 Preview

Hi,

I’m trying to experiment with Driver Verifier’s DDI compliance checking and additional compliance checking rules. The docs [1] [2] explain that in Windows 8.1 Preview, Driver Verifier should be able to catch a recursive spinlock acquisition as a violation of DDI compliance rules.

I’ve modified the Notmyfault application (and driver) with an additional option that causes a deadlock by recursively acquiring a spinlock:

VOID
SpinlockDeadlock(
VOID
)
{
KIRQL OldIrql;
static KSPIN_LOCK SpinLock;

KeInitializeSpinLock( &SpinLock );

// Attemps to acquire a spinlock twice. This is guaranteed to cause
// a deadlock immediately.
KeAcquireSpinLock( &SpinLock, &OldIrql );
KeAcquireSpinLock (&SpinLock, &OldIrql );

KeReleaseSpinLock (&SpinLock, OldIrql ); }

Driver Verifier is enabled for the myfault.sys driver with both DDI compliance checking and additional DDI compliance checking:

kd> !verifier
Verify Level a0000 … enabled options are:
DDI compliance checking enabled

Also, I can see the load message when myfault.sys is loaded, telling me that the DV rules are in effect.

Nonetheless, DV does not detect the recursive spinlock acquisition and the system just hangs. Here is the call stack from the kernel debugger at the point of the hang (you can see DV’s injected frames 08, 09, 0a):

kd> kn
*** Stack trace for last set context - .thread/.cxr resets it
# Child-SP RetAddr Call Site
00 fffff8008639bc88 fffff80084997940 nt!DbgBreakPointWithStatus
01 fffff8008639bc90 fffff8008489c9ee nt! ?? ::FNODOBFM::string'+0x23300<br>02 fffff8008639bd20 fffff80084faaf1f nt!KeClockInterruptNotify+0x73e<br>03 fffff8008639bf40 fffff800848f5cc2 hal!HalpTimerClockInterrupt+0x4f<br>04 fffff8008639bf70 fffff8008496522a nt!KiCallInterruptServiceRoutine+0x122<br>05 fffff8008639bfb0 fffff8008496560f nt!KiInterruptSubDispatchNoLockNoEtw+0xea<br>06 ffffd0002116f730 fffff800848f5ee0 nt!KiInterruptDispatchLBControl+0x11f<br>07 ffffd0002116f8c0 fffff800848f5ea2 nt!KxWaitForSpinLockAndAcquire+0x20<br>08 ffffd0002116f8f0 fffff800002e9559 nt!KeAcquireSpinLockRaiseToDpc+0x32<br>09 ffffd0002116f920 fffff80084e959cb VerifierExt!KeAcquireSpinLockRaiseToDpc_wrapper+0x129<br>0a ffffd0002116f970 fffff800025f2385 nt!VerifierKeAcquireSpinLockRaiseToDpc+0x5f<br>0b ffffd0002116f9b0 fffff800025f24ff myfault!MyfaultDeviceControl+0x351<br>0c ffffd0002116fb10 fffff80084e825a8 myfault!MyfaultDispatch+0xb7 0d ffffd0002116fb70 fffff80084becbb3 nt!IovCallDriver+0xb4 0e ffffd0002116fbc0 fffff80084beddaa nt!IopXxxControlFile+0x8c3 0f ffffd0002116fd60 fffff8008496f6b3 nt!NtDeviceIoControlFile+0x56<br>10 ffffd0002116fdd0 00007fff4f53b12a nt!KiSystemServiceCopyEnd+0x13<br>11 000000000050ef48 00007fff4c962f83 ntdll!NtDeviceIoControlFile+0xa<br>12 000000000050ef50 00007fff4f3614f0 KERNELBASE!DeviceIoControl+0x73<br>13 000000000050efc0 00007ff7da59275b KERNEL32!DeviceIoControlImplementation+0x74<br>14 000000000050f010 00007fff4edd182e NotMyfault!HangDialogProc+0x93<br>15 000000000050f090 00007fff4edd160c USER32!UserCallDlgProcCheckWow+0x112<br>16 000000000050f160 00007fff4ee23111 USER32!DefDlgProcWorker+0xb4<br>17 000000000050f220 00007fff4edc27a4 USER32!DefDlgProcA+0x39<br>18 000000000050f260 00007fff4edc4372 USER32!UserCallWinProcCheckWow+0x140<br>19 000000000050f320 00007fff4edc443d USER32!DispatchClientMessage+0xa2 1a 000000000050f380 00007fff4f53cecf USER32!_fnDWORD+0x2d 1b 000000000050f3e0 00007fff4edc1fca ntdll!KiUserCallbackDispatcherContinue<br>1c 000000000050f468 00007fff4edc50c3 USER32!NtUserMessageCall+0xa 1d 000000000050f470 00007fff4edc5201 USER32!SendMessageWorker+0xfb 1e 000000000050f500 00007fff4ae59fa4 USER32!SendMessageW+0x105 1f 000000000050f560 00007fff4ae59f7f COMCTL32!Button_ReleaseCapture+0xd0<br>20 000000000050f5a0 00007fff4edc27a4 COMCTL32!Button_WndProc+0x8d3<br>21 000000000050f6c0 00007fff4edc2257 USER32!UserCallWinProcCheckWow+0x140<br>22 000000000050f780 00007fff4eddd831 USER32!DispatchMessageWorker+0x1a7<br>23 000000000050f800 00007fff4ae6919e USER32!IsDialogMessageW+0x127<br>24 000000000050f860 00007fff4ae69129 COMCTL32!Prop_IsDialogMessage+0x4a<br>25 000000000050f890 00007fff4ae68e71 COMCTL32!_RealPropertySheet+0x28b<br>26 000000000050f960 00007fff4aeda157 COMCTL32!_PropertySheet+0x49<br>27 000000000050f990 00007ff7da592c2c COMCTL32!PropertySheetA+0x53<br>28 000000000050fa30 00007ff7da592e26 NotMyfault!WinMain+0x248<br>29 000000000050fc40 00007fff4f361331 NotMyfault!__mainCRTStartup+0x18e 2a 000000000050fd00 00007fff4f508cd5 KERNEL32!BaseThreadInitThunk+0xd 2b 000000000050fd30 00000000`00000000 ntdll!RtlUserThreadStart+0x1d

Am I doing something wrong here? Am I wrong in reading the documentation that DV should be able to catch this simple violation?

Thanks in advance,
Sasha

[1] http://msdn.microsoft.com/en-us/library/windows/hardware/ff551861(v=vs.85).aspx
[2] http://msdn.microsoft.com/en-us/library/windows/hardware/hh454208(v=vs.85).aspx


NTDEV is sponsored by OSR

Visit the list at: http://www.osronline.com/showlists.cfm?list=ntdev

OSR is HIRING!! See http://www.osr.com/careers

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer


NTDEV is sponsored by OSR

Visit the list at: http://www.osronline.com/showlists.cfm?list=ntdev

OSR is HIRING!! See http://www.osr.com/careers

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer


Sasha Goldshtein | CTO, Sela Group | Microsoft C# MVP | blog.sashag.nethttp: | @goldshtnhttp:
— NTDEV is sponsored by OSR Visit the list at: http://www.osronline.com/showlists.cfm?list=ntdev OSR is HIRING!! See http://www.osr.com/careers For our schedule of WDF, WDM, debugging and other seminars visit: http://www.osr.com/seminars To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer</http:></http:></mailto:xxxxx></mailto:xxxxx></mailto:xxxxx></file:></file:>

I can confirm that it works now. Very happy to see this resolved, and
thanks for taking the time to investigate this issue.

Sasha

On Wed, Aug 7, 2013 at 2:44 AM, Juncao Li wrote:

> Hi Sasha,
>
>

>
> This sample reveals an issue in DV?s dispatch routine interception model.
> We will fix it.

>
> ****
>
> To unblock you, you can move the yellow code before the call to
> IoCreateDevice(…). **
>
>

>