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.