L1C63x64.sys: Bug Check 0xD1 (DRIVER_IRQL_NOT_LESS_OR_EQUAL)


In this case the operating system has been crashing from time to time. Let’s first gather some basic information about the crash.

3: kd> !analyze -v
DRIVER_IRQL_NOT_LESS_OR_EQUAL (d1)
An attempt was made to access a pageable (or completely invalid) address at an
interrupt request level (IRQL) that is too high.  This is usually
caused by drivers using improper addresses.
If kernel debugger is available get stack backtrace.
Arguments:
Arg1: 0000000000000000, memory referenced
Arg2: 0000000000000002, IRQL
Arg3: 0000000000000000, value 0 = read operation, 1 = write operation
Arg4: fffff800ce831cb3, address which referenced memory

...

TRAP_FRAME:  ffffd0016dd62e40 -- (.trap 0xffffd0016dd62e40)
NOTE: The trap frame does not contain all registers.
Some register values may be zeroed or incorrect.
rax=0000000000000000 rbx=0000000000000000 rcx=00000000000015f2
rdx=0000000000000000 rsi=0000000000000000 rdi=0000000000000000
rip=fffff800ce831cb3 rsp=ffffd0016dd62fd0 rbp=ffffe001a7f93880
 r8=0000000000000365  r9=ffffe001aa499000 r10=ffffe001a6c08c78
r11=ffffd0016dd62fe0 r12=0000000000000000 r13=0000000000000000
r14=0000000000000000 r15=0000000000000000
iopl=0         nv up ei pl nz na pe nc
L1C63x64!DmaFillTpds+0x177:
fffff800`ce831cb3 488b08          mov     rcx,qword ptr [rax] ds:00000000`00000000=????????????????
Resetting default scope

3: kd> lmvm L1C63x64
Browse full module list
start             end                 module name
fffff800`ce82b000 fffff800`ce84d000   L1C63x64   (pdb symbols)          d:\symstore\symbols\L1c63x64.pdb\DF9236FBD6744CE8A7D9FF5A931BF7271\L1c63x64.pdb
    Loaded symbol image file: L1C63x64.sys
    Image path: \SystemRoot\system32\DRIVERS\L1C63x64.sys
    Image name: L1C63x64.sys
    Browse all global symbols  functions  data
    Timestamp:        Mon Apr 01 06:15:17 2013 (5158FBC5)
    CheckSum:         000245C4
    ImageSize:        00022000

3: kd> k
 # Child-SP          RetAddr           Call Site
00 ffffd001`6dd62cf8 fffff802`a41e87e9 nt!KeBugCheckEx
01 ffffd001`6dd62d00 fffff802`a41e703a nt!KiBugCheckDispatch+0x69
02 ffffd001`6dd62e40 fffff800`ce831cb3 nt!KiPageFault+0x23a
03 ffffd001`6dd62fd0 fffff800`ce831edb L1C63x64!DmaFillTpds+0x177
04 ffffd001`6dd63030 fffff802`a40416f5 L1C63x64!DmaProcessSGList+0x9f
05 ffffd001`6dd63060 fffff802`a403fb49 hal!HalpAllocateAdapterCallbackV2+0x149
06 ffffd001`6dd63100 fffff802`a4036b8e hal!HalAllocateAdapterChannelV2+0x129
07 ffffd001`6dd63140 fffff800`cd86310b hal!HalBuildScatterGatherListV2+0x1735e
08 ffffd001`6dd631e0 fffff800`ce8320e4 ndis!NdisMAllocateNetBufferSGList+0x10b
09 ffffd001`6dd632a0 fffff800`ce832512 L1C63x64!DmaSendNetBufferList+0x1d0
0a ffffd001`6dd63380 fffff800`cd863a21 L1C63x64!MiniportSendNetBufferLists+0x11e
0b ffffd001`6dd633c0 fffff800`ce869d0f ndis!NdisSendNetBufferLists+0x551
0c ffffd001`6dd635b0 fffff800`ce87dcb5 vmswitch!VmsPtNicPvtPacketForward+0x1ef
0d ffffd001`6dd63710 fffff800`ce87ad8a vmswitch!VmsRouterDeliverNetBufferLists+0x335
0e ffffd001`6dd637f0 fffff800`cd85d903 vmswitch!VmsExtPtReceiveNetBufferLists+0x13a
0f ffffd001`6dd63850 fffff800`cd86d29b ndis!ndisMIndicateNetBufferListsToOpen+0x123
10 ffffd001`6dd63910 fffff800`cd85e8f6 ndis!ndisMTopReceiveNetBufferLists+0x2db
11 ffffd001`6dd639a0 fffff800`ce8679c9 ndis!NdisMIndicateReceiveNetBufferLists+0xb96
12 ffffd001`6dd63b80 fffff800`cd863a21 vmswitch!VmsExtMpSendNetBufferLists+0x359
13 ffffd001`6dd63d10 fffff800`ce86d347 ndis!NdisSendNetBufferLists+0x551
14 ffffd001`6dd63f00 fffff800`ce86b8dc vmswitch!VmsExtPtRouteNetBufferLists+0x377
15 ffffd001`6dd63fd0 fffff800`ce86b816 vmswitch!VmsExtPtRouteNetBufferListsWithBwCap+0x90
16 ffffd001`6dd64050 fffff800`cd863a21 vmswitch!VmsMpNicSendNetBufferLists+0x122
17 ffffd001`6dd640f0 fffff800`cda6589b ndis!NdisSendNetBufferLists+0x551
18 ffffd001`6dd642e0 fffff800`cda63124 tcpip!IppFragmentPackets+0x4eb
19 ffffd001`6dd64420 fffff800`cda62875 tcpip!IppDispatchSendPacketHelper+0x94
1a ffffd001`6dd645b0 fffff800`cda61a22 tcpip!IppPacketizeDatagrams+0x2d5
1b ffffd001`6dd64750 fffff800`cda6f462 tcpip!IppSendDatagramsCommon+0x4a2
1c ffffd001`6dd64940 fffff800`cda6fc3d tcpip!UdpSendMessagesOnPathCreation+0x472
1d ffffd001`6dd64d80 fffff800`cda2aa1c tcpip!UdpSendMessages+0x24d
1e ffffd001`6dd651b0 fffff802`a41559a6 tcpip!UdpTlProviderSendMessagesCalloutRoutine+0x15
1f ffffd001`6dd651e0 fffff800`cda2a97c nt!KeExpandKernelStackAndCalloutInternal+0xe6
20 ffffd001`6dd652d0 fffff800`ce516719 tcpip!UdpTlProviderSendMessages+0x6c
21 ffffd001`6dd65350 fffff800`ce4fe0e5 afd!AfdFastDatagramSend+0x579
22 ffffd001`6dd65510 fffff802`a4468374 afd!AfdFastIoDeviceControl+0x10d6
23 ffffd001`6dd65880 fffff802`a4469146 nt!IopXxxControlFile+0x3d4
24 ffffd001`6dd65a20 fffff802`a41e84b3 nt!NtDeviceIoControlFile+0x56
25 ffffd001`6dd65a90 00000000`77a02772 nt!KiSystemServiceCopyEnd+0x13
26 00000000`0298f128 00000000`77a02371 wow64cpu!CpupSyscallStub+0x2
27 00000000`0298f130 00000000`77a2323a wow64cpu!DeviceIoctlFileFault+0x31
28 00000000`0298f1e0 00000000`77a2317e wow64!RunCpuSimulation+0xa
29 00000000`0298f230 00007ff8`2b16b338 wow64!Wow64LdrpInitialize+0x172
2a 00000000`0298f770 00007ff8`2b16b20e ntdll!_LdrpInitialize+0xd8
2b 00000000`0298f7e0 00000000`00000000 ntdll!LdrInitializeThunk+0xe

3: kd> ub L1C63x64!DmaFillTpds+0x177
L1C63x64!DmaFillTpds+0x157:
fffff800`ce831c93 0fb65554        movzx   edx,byte ptr [rbp+54h]
fffff800`ce831c97 488bce          mov     rcx,rsi
fffff800`ce831c9a e8b99d0000      call    L1C63x64!TxMailBox (fffff800`ce83ba58)
fffff800`ce831c9f 4c39642468      cmp     qword ptr [rsp+68h],r12
fffff800`ce831ca4 7530            jne     L1C63x64!DmaFillTpds+0x19a (fffff800`ce831cd6)
fffff800`ce831ca6 44386555        cmp     byte ptr [rbp+55h],r12b
fffff800`ce831caa 7423            je      L1C63x64!DmaFillTpds+0x193 (fffff800`ce831ccf)
fffff800`ce831cac 488b8630090000  mov     rax,qword ptr [rsi+930h]
3: kd> u L1C63x64!DmaFillTpds+0x177
L1C63x64!DmaFillTpds+0x177:
fffff800`ce831cb3 488b08          mov     rcx,qword ptr [rax]
fffff800`ce831cb6 48898e30090000  mov     qword ptr [rsi+930h],rcx
fffff800`ce831cbd 4885c9          test    rcx,rcx
fffff800`ce831cc0 7507            jne     L1C63x64!DmaFillTpds+0x18d (fffff800`ce831cc9)
fffff800`ce831cc2 4c89a638090000  mov     qword ptr [rsi+938h],r12
fffff800`ce831cc9 ff8e88090000    dec     dword ptr [rsi+988h]
fffff800`ce831ccf 4c89a6f0090000  mov     qword ptr [rsi+9F0h],r12
fffff800`ce831cd6 488b5c2470      mov     rbx,qword ptr [rsp+70h]

From above we can see that the system was crashed when the L1C63x64!DmaFillTpds function was removing an element from a singly linked list and the list was empty.

The next step will be to find out the address in the RSI register at the moment of the crash and make sure that it belongs to our driver. Examining nt!KiPageFault and nt!KiBugCheckDispatch routines we can see that nt!KiBugCheckDispatch saved the value in RSI on the stack.

3: kd> u nt!KiBugCheckDispatch
nt!KiBugCheckDispatch:
fffff802`a41e8780 4881ec38010000  sub     rsp,138h
fffff802`a41e8787 488d842400010000 lea     rax,[rsp+100h]
...
fffff802`a41e87cb 48897010        mov     qword ptr [rax+10h],rsi

3: kd> dps ffffd001`6dd62e40-8-138+100+10 L1
ffffd001`6dd62e10  ffffe001`aa499000

Using the !pool command we can find the pool tag and then the driver that contains the tag.

3: kd> !pool ffffe001`aa499000
Pool page ffffe001aa499000 region is Nonpaged pool
*ffffe001aa499000 : large page allocation, tag is ArIc, size is 0x3980 bytes
		Owning component : Unknown (update pooltag.txt)

3: kd> !for_each_module ".echo @#ModuleName; s-a @#Base @#End \"ArIc\""
...
L1C63x64
fffff800`ce834124  41 72 49 63 ff 15 a2 10-01 00 48 89 47 08 48 85  ArIc......H.G.H.

Now that we know that the memory belongs to our driver, let’s try to find out the purpose of its use. By using the "Search for Disassembly Pattern" command we can dump all places in the driver where memory is accessed at offset 930 and then examine them.

3: kd> # 30090000 fffff800`ce82b000 L22000
L1C63x64!NicInitialize+0x276:
fffff800`ce82cb22 4889b730090000  mov     qword ptr [rdi+930h],rsi
L1C63x64!DmaFillTpds+0x170:
fffff800`ce831cac 488b8630090000  mov     rax,qword ptr [rsi+930h]
L1C63x64!DmaFillTpds+0x17a:
fffff800`ce831cb6 48898e30090000  mov     qword ptr [rsi+930h],rcx
L1C63x64!DmaSendNetBufferList+0xa2:
fffff800`ce831fb6 488b8730090000  mov     rax,qword ptr [rdi+930h]
L1C63x64!DmaSendNetBufferList+0xac:
fffff800`ce831fc0 48898f30090000  mov     qword ptr [rdi+930h],rcx
L1C63x64!DmaSendNetBufferList+0x255:
fffff800`ce832169 488b8730090000  mov     rax,qword ptr [rdi+930h]
L1C63x64!DmaSendNetBufferList+0x267:
fffff800`ce83217b 4889b730090000  mov     qword ptr [rdi+930h],rsi
L1C63x64!DmaSendNetBufferList+0x2c1:
fffff800`ce8321d5 488b8730090000  mov     rax,qword ptr [rdi+930h]
L1C63x64!DmaSendNetBufferList+0x2cb:
fffff800`ce8321df 48898f30090000  mov     qword ptr [rdi+930h],rcx
L1C63x64!HandleTxIntr+0x31:
fffff800`ce8322a5 488b9330090000  mov     rdx,qword ptr [rbx+930h]
L1C63x64!HandleTxIntr+0x55:
fffff800`ce8322c9 4883bb3009000000 cmp     qword ptr [rbx+930h],0
L1C63x64!MiniportCancelSendNetBufferLists+0x3c:
fffff800`ce83232c 488b8330090000  mov     rax,qword ptr [rbx+930h]
L1C63x64!MiniportCancelSendNetBufferLists+0x72:
fffff800`ce832362 48898b30090000  mov     qword ptr [rbx+930h],rcx
L1C63x64!MiniportSendNetBufferLists+0xdd:
fffff800`ce8324d1 48898b30090000  mov     qword ptr [rbx+930h],rcx
L1C63x64!MiniportSendNetBufferLists+0x105:
fffff800`ce8324f9 488b9330090000  mov     rdx,qword ptr [rbx+930h]
L1C63x64!MiniportSendNetBufferLists+0x126:
fffff800`ce83251a 4883bb3009000000 cmp     qword ptr [rbx+930h],0
L1C63x64!MpFreeQueuedSendNetBufferLists+0xad:
fffff800`ce8326b9 4839ab30090000  cmp     qword ptr [rbx+930h],rbp
L1C63x64!MpFreeQueuedSendNetBufferLists+0xba:
fffff800`ce8326c6 488b8b30090000  mov     rcx,qword ptr [rbx+930h]
L1C63x64!MpFreeQueuedSendNetBufferLists+0xc4:
fffff800`ce8326d0 48898330090000  mov     qword ptr [rbx+930h],rax
L1C63x64!MpFreeQueuedSendNetBufferLists+0x11c:
fffff800`ce832728 4883bb3009000000 cmp     qword ptr [rbx+930h],0
L1C63x64!TxFreeNBL+0x97:
fffff800`ce832bb7 4c398b30090000  cmp     qword ptr [rbx+930h],r9

3: kd> u L1C63x64!NicInitialize fffff800`ce82cb22
L1C63x64!NicInitialize:
...
fffff800`ce82c8d5 488bf9          mov     rdi,rcx
...
fffff800`ce82cb22 4889b730090000  mov     qword ptr [rdi+930h],rsi

3: kd> # NicInitialize fffff800`ce82b000 L22000
L1C63x64!MiniportInitializeEx+0xd6:
fffff800`ce82c652 e855020000      call    L1C63x64!NicInitialize (fffff800`ce82c8ac)
...

3: kd> u L1C63x64!MiniportInitializeEx fffff800`ce82c652
L1C63x64!MiniportInitializeEx:
fffff800`ce82c57c 48895c2410      mov     qword ptr [rsp+10h],rbx
fffff800`ce82c581 55              push    rbp
fffff800`ce82c582 56              push    rsi
fffff800`ce82c583 57              push    rdi
fffff800`ce82c584 4156            push    r14
fffff800`ce82c586 4157            push    r15
fffff800`ce82c588 4881ec10010000  sub     rsp,110h
fffff800`ce82c58f 488b05eabc0100  mov     rax,qword ptr [L1C63x64!_security_cookie (fffff800`ce848280)]
fffff800`ce82c596 4833c4          xor     rax,rsp
fffff800`ce82c599 4889842400010000 mov     qword ptr [rsp+100h],rax
fffff800`ce82c5a1 4d8bf8          mov     r15,r8
fffff800`ce82c5a4 33f6            xor     esi,esi
fffff800`ce82c5a6 ba80390000      mov     edx,3980h
fffff800`ce82c5ab 448d4e10        lea     r9d,[rsi+10h]
fffff800`ce82c5af 41b841724963    mov     r8d,63497241h
fffff800`ce82c5b5 4c8bf1          mov     r14,rcx
fffff800`ce82c5b8 33ed            xor     ebp,ebp
fffff800`ce82c5ba ff15088b0100    call    qword ptr [L1C63x64!_imp_NdisAllocateMemoryWithTagPriority (fffff800`ce8450c8)]
fffff800`ce82c5c0 488bf8          mov     rdi,rax
fffff800`ce82c5c3 4885c0          test    rax,rax
fffff800`ce82c5c6 7514            jne     L1C63x64!MiniportInitializeEx+0x60 (fffff800`ce82c5dc)
fffff800`ce82c5c8 bb9a0000c0      mov     ebx,0C000009Ah
fffff800`ce82c5cd be891300c0      mov     esi,0C0001389h
fffff800`ce82c5d2 bd05060000      mov     ebp,605h
fffff800`ce82c5d7 e952010000      jmp     L1C63x64!MiniportInitializeEx+0x1b2 (fffff800`ce82c72e)
fffff800`ce82c5dc 33d2            xor     edx,edx
fffff800`ce82c5de 41b880390000    mov     r8d,3980h
fffff800`ce82c5e4 488bc8          mov     rcx,rax
fffff800`ce82c5e7 e874810100      call    L1C63x64!memset (fffff800`ce844760)
fffff800`ce82c5ec 4c89b798090000  mov     qword ptr [rdi+998h],r14
fffff800`ce82c5f3 498b4718        mov     rax,qword ptr [r15+18h]
fffff800`ce82c5f7 488d4c2420      lea     rcx,[rsp+20h]
fffff800`ce82c5fc 33d2            xor     edx,edx
fffff800`ce82c5fe 41b8e0000000    mov     r8d,0E0h
fffff800`ce82c604 488987e8090000  mov     qword ptr [rdi+9E8h],rax
fffff800`ce82c60b e850810100      call    L1C63x64!memset (fffff800`ce844760)
fffff800`ce82c610 488d542420      lea     rdx,[rsp+20h]
fffff800`ce82c615 498bce          mov     rcx,r14
fffff800`ce82c618 c74424209e021c00 mov     dword ptr [rsp+20h],1C029Eh
fffff800`ce82c620 48897c2428      mov     qword ptr [rsp+28h],rdi
fffff800`ce82c625 c744243041010000 mov     dword ptr [rsp+30h],141h
fffff800`ce82c62d c744243402000000 mov     dword ptr [rsp+34h],2
fffff800`ce82c635 c744243805000000 mov     dword ptr [rsp+38h],5
fffff800`ce82c63d ff15b58a0100    call    qword ptr [L1C63x64!_imp_NdisMSetMiniportAttributes (fffff800`ce8450f8)]
fffff800`ce82c643 8bd8            mov     ebx,eax
fffff800`ce82c645 85c0            test    eax,eax
fffff800`ce82c647 7517            jne     L1C63x64!MiniportInitializeEx+0xe4 (fffff800`ce82c660)
fffff800`ce82c649 4d8bc7          mov     r8,r15
fffff800`ce82c64c 498bd6          mov     rdx,r14
fffff800`ce82c64f 488bcf          mov     rcx,rdi
fffff800`ce82c652 e855020000      call    L1C63x64!NicInitialize (fffff800`ce82c8ac)

Looking at the L1C63x64!MiniportInitializeEx function we can see that it uses boilerplate code for allocating an adapter context area and then initializes it in the L1C63x64!NicInitialize function.

Continuing our analysis we will find that the second paramater to the L1C63x64!MiniportSendNetBufferLists function was stored at offset 930. From the MSDN we know that the second argument to this function is a pointer to the first NET_BUFFER_LIST structure in a linked list of NET_BUFFER_LIST structures.

3: kd> u L1C63x64!MiniportSendNetBufferLists fffff800`ce8324d1 
L1C63x64!MiniportSendNetBufferLists:
fffff800`ce8323f4 48895c2408      mov     qword ptr [rsp+8],rbx
fffff800`ce8323f9 48896c2410      mov     qword ptr [rsp+10h],rbp
fffff800`ce8323fe 4889742418      mov     qword ptr [rsp+18h],rsi
fffff800`ce832403 57              push    rdi
fffff800`ce832404 4156            push    r14
fffff800`ce832406 4157            push    r15
fffff800`ce832408 4883ec20        sub     rsp,20h
fffff800`ce83240c 488bea          mov     rbp,rdx
fffff800`ce83240f 488bd9          mov     rbx,rcx
...
fffff800`ce83247a 488db3200a0000  lea     rsi,[rbx+0A20h]
fffff800`ce832481 488bce          mov     rcx,rsi
fffff800`ce832484 ff15c62d0100    call    qword ptr [L1C63x64!_imp_KeAcquireSpinLockAtDpcLevel (fffff800`ce845250)]
fffff800`ce83248a 488bcd          mov     rcx,rbp
fffff800`ce83248d 4885ed          test    rbp,rbp
fffff800`ce832490 0f8484000000    je      L1C63x64!MiniportSendNetBufferLists+0x126 (fffff800`ce83251a)
...
fffff800`ce8324d1 48898b30090000  mov     qword ptr [rbx+930h],rcx

This pointer was saved by the ndis!NdisSendNetBufferLists function on the stack.

3: kd> u ndis!NdisSendNetBufferLists
ndis!NdisSendNetBufferLists:
fffff800`cd8634d0 488bc4          mov     rax,rsp
fffff800`cd8634d3 44894018        mov     dword ptr [rax+18h],r8d
fffff800`cd8634d7 48895010        mov     qword ptr [rax+10h],rdx
fffff800`cd8634db 48894808        mov     qword ptr [rax+8],rcx

3: kd> dq ffffd001`6dd635b0-8+10 L1
ffffd001`6dd635b8  ffffe001`a7086db0

If we display information about the net buffer list we will see that it was freed.

3: kd> !ndiskd.nbl ffffe001`a7086db0 1
    NBL                ffffe001a7086db0    Next NBL           ffffe001a976a1d0
    First NB           ffffe001a7086f10    Source             ffffe001a947f010 - VMSP
    Flags              FREED_BACK_TO_NDIS
    Parent NBL         ffffe001a8b1edf0    ChildRefCount      0

3: kd> dt ndis!_NET_BUFFER_LIST ffffe001`a7086db0
   +0x000 Next             : 0xffffe001`a976a1d0  _NET_BUFFER_LIST
   +0x008 FirstNetBuffer   : 0xffffe001`a7086f10  _NET_BUFFER
   +0x000 Link             : _SLIST_HEADER
   +0x000 NetBufferListHeader : _NET_BUFFER_LIST_HEADER
   +0x010 Context          : 0xffffe001`a7086fc0 _NET_BUFFER_LIST_CONTEXT
   +0x018 ParentNetBufferList : 0xffffe001`a8b1edf0  _NET_BUFFER_LIST
   +0x020 NdisPoolHandle   : 0xffffe001`a93f1980 Void
   +0x030 NdisReserved     : [2] (null) 
   +0x040 ProtocolReserved : [4] (null) 
   +0x060 MiniportReserved : [2] (null) 
   +0x070 Scratch          : (null) 
   +0x078 SourceHandle     : 0xffffe001`a947f010 Void
   +0x080 NblFlags         : 0
   +0x084 ChildRefCount    : 0n0
   +0x088 Flags            : 0
   +0x08c Status           : 0n0
   +0x08c NdisReserved2    : 0
   +0x090 NetBufferListInfo : [26] (null)

So, between ndis!NdisMAllocateNetBufferSGList and L1C63x64!DmaProcessSGList calls the net buffer list was freed, when it wasn’t guarded by the spin lock, and the bad approach of removing elements from a singly linked list led to the crash.

3: kd> ub L1C63x64!DmaSendNetBufferList+0x1d0 L10
L1C63x64!DmaSendNetBufferList+0x181:
fffff800`ce832095 488b4518        mov     rax,qword ptr [rbp+18h]
fffff800`ce832099 488d9f200a0000  lea     rbx,[rdi+0A20h],
fffff800`ce8320a0 488b08          mov     rcx,qword ptr [rax]
fffff800`ce8320a3 48894d18        mov     qword ptr [rbp+18h],rcx
fffff800`ce8320a7 41814f1001000010 or      dword ptr [r15+10h],offset Captlib+0x1 (00000000`10000001)
fffff800`ce8320af 488bcb          mov     rcx,rbx
fffff800`ce8320b2 ff1590310100    call    qword ptr [L1C63x64!_imp_KeReleaseSpinLockFromDpcLevel (fffff800`ce845248)]
fffff800`ce8320b8 8b87fc090000    mov     eax,dword ptr [rdi+9FCh]
fffff800`ce8320be 488b8f000a0000  mov     rcx,qword ptr [rdi+0A00h]
fffff800`ce8320c5 89442428        mov     dword ptr [rsp+28h],eax
fffff800`ce8320c9 498b4730        mov     rax,qword ptr [r15+30h]
fffff800`ce8320cd 41b901000000    mov     r9d,1
fffff800`ce8320d3 4d8bc7          mov     r8,r15
fffff800`ce8320d6 498bd6          mov     rdx,r14
fffff800`ce8320d9 4889442420      mov     qword ptr [rsp+20h],rax
fffff800`ce8320de ff15b4300100    call    qword ptr [L1C63x64!_imp_NdisMAllocateNetBufferSGList (fffff800`ce845198)]

3: kd> u L1C63x64!DmaProcessSGList L10
L1C63x64!DmaProcessSGList:
fffff800`ce831e3c 48895c2408      mov     qword ptr [rsp+8],rbx
fffff800`ce831e41 48896c2410      mov     qword ptr [rsp+10h],rbp
fffff800`ce831e46 4889742418      mov     qword ptr [rsp+18h],rsi
fffff800`ce831e4b 57              push    rdi
fffff800`ce831e4c 4883ec20        sub     rsp,20h
fffff800`ce831e50 498b7128        mov     rsi,qword ptr [r9+28h]
fffff800`ce831e54 498bf9          mov     rdi,r9
fffff800`ce831e57 498bd8          mov     rbx,r8
fffff800`ce831e5a 488dae200a0000  lea     rbp,[rsi+0A20h]
fffff800`ce831e61 488bcd          mov     rcx,rbp
fffff800`ce831e64 ff15e6330100    call    qword ptr [L1C63x64!_imp_KeAcquireSpinLockAtDpcLevel (fffff800`ce845250)]

This is how the issue will look like in C language.

typedef struct _NET_BUFFER_LIST {
    _NET_BUFFER_LIST *Next;
} NET_BUFFER_LIST, *PNET_BUFFER_LIST;

typedef struct _ADAPTER_CONTEXT {
    PNET_BUFFER_LIST NetBufferList;
    KSPIN_LOCK SpinLock;
} ADAPTER_CONTEXT, *PADAPTER_CONTEXT;

ADAPTER_CONTEXT AdapterContext;

VOID
Routine(
...
    )
{

...

    KeAcquireSpinLockAtDpcLevel(&AdapterContext.SpinLock);
    
    //
    // Bad
    //

    AdapterContext.NetBufferList = (PNET_BUFFER_LIST)AdapterContext.NetBufferList->Next;

    //
    // Good
    //

    if (AdapterContext.NetBufferList) {

        AdapterContext.NetBufferList = (PNET_BUFFER_LIST)AdapterContext.NetBufferList->Next;
    }

...

}

Conclusion

There are a few other places in the driver where is used the same way of removing elements from a singly linked list. This analysis was done on 2.1.0.16 version of the driver (Qualcomm Atheros AR8151 PCI-E Gigabit Ethernet Controller (NDIS 6.30)), but the latest 2.1.0.21 version has the same issues. Hope it will be fixed in the next release.