PFN_LIST_CORRUPT in TDI Filter Driver

Hi,

My Tdi Filter Driver Monitors certain applications and blocks their IRPs
based on user choice.Everything works well but some times the following code
for denying IRPs generates bugcheck 4E.As soon as IoCompleteRequest is
called a Bug Check 4E appears. It seems that Io Manager is calling
MmUnlockPages Twice on the MDL when i call IoCompleteRequest.But why ? how
to avoid this bug check ? any ideas ? Is there any way to check the validity
of this MDL attached with IRP before calling IoCompleteRequest or any
workarounds ?

if(pIrp != NULL)
{
// Just Complete it with error code
pIrp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST;
pIrp->IoStatus.Information = 0;

IoCompleteRequest(pIrp,IO_NO_INCREMENT);

pEntry->pHoldingIrp = NULL;

}

The stack looks like this -
kd> !analyze -v
****************************************************************************
***
*
*
* Bugcheck Analysis
*
*
*
****************************************************************************
***

PFN_LIST_CORRUPT (4e)
Typically caused by drivers passing bad memory descriptor lists (ie: calling
MmUnlockPages twice with the same list, etc). If a kernel debugger is
available get the stack trace.
Arguments:
Arg1: 00000007, A driver has unlocked a page more times than it locked it
Arg2: 00001573, page frame number
Arg3: 00000001, current share count
Arg4: 00000000, 0

Debugging Details:

DEFAULT_BUCKET_ID: DRIVER_FAULT

BUGCHECK_STR: 0x4E

LAST_CONTROL_TRANSFER: from 8042c0c3 to 80455d74

STACK_TEXT:
b79b994c 8042c0c3 00000003 b79b9994 00000007
nt!RtlpBreakWithStatusInstruction
b79b997c 8042c487 00000003 00001573 818e32c8 nt!KiBugCheckDebugBreak+0x31
b79b9d08 8044cc80 0000004e 00000007 00001573 nt!KeBugCheckEx+0x390
b79b9d28 80437612 8154a5c8 81660de8 b79b9d64
nt!MiDecrementReferenceCount+0xbf
b79b9d40 8041faa2 8154a500 8153a6a8 8046d41c nt!MmUnlockPages+0x10f
b79b9d64 ed3ec755 8153a6a8 81660de8 8158d9a8 nt!IopfCompleteRequest+0x1e9
b79b9d78 80418dc7 8153a6a8 00000000 00000000
netfilter!NetFilterDenyIrpFreeMemoryWorkRoutine+0x6a
[E:\NetFilter\NetFilter\Timer.c @ 398]
b79b9da8 804553af 8153a6a8 00000000 00000000 nt!ExpWorkerThread+0xae
b79b9ddc 804695b2 80418d02 80000001 00000000 nt!PspSystemThreadStartup+0x69
00000000 00000000 00000000 00000000 00000000 nt!KiThreadStartup+0x16

FOLLOWUP_IP:
netfilter!NetFilterDenyIrpFreeMemoryWorkRoutine+6a
ed3ec755 6880c63eed push 0xed3ec680

FOLLOWUP_NAME: MachineOwner

SYMBOL_NAME: netfilter!NetFilterDenyIrpFreeMemoryWorkRoutine+6a

MODULE_NAME: netfilter

IMAGE_NAME: netfilter.SYS

DEBUG_FLR_IMAGE_TIMESTAMP: 3f8a7fbb

STACK_COMMAND: kb

BUCKET_ID: 0x4E_netfilter!NetFilterDenyIrpFreeMemoryWorkRoutine+6a

Followup: MachineOwner

any help is appreciated.
Regards…
Subodh

If you use partial MDLs - be sure that you first IoFreeMdl the partial MDL,
and only then the main MDL.

Maxim Shatskih, Windows DDK MVP
StorageCraft Corporation
xxxxx@storagecraft.com
http://www.storagecraft.com

----- Original Message -----
From:
To: “Windows System Software Devs Interest List”
Sent: Monday, October 13, 2003 3:07 PM
Subject: [ntdev] PFN_LIST_CORRUPT in TDI Filter Driver

> Hi,
>
> My Tdi Filter Driver Monitors certain applications and blocks their IRPs
> based on user choice.Everything works well but some times the following code
> for denying IRPs generates bugcheck 4E.As soon as IoCompleteRequest is
> called a Bug Check 4E appears. It seems that Io Manager is calling
> MmUnlockPages Twice on the MDL when i call IoCompleteRequest.But why ? how
> to avoid this bug check ? any ideas ? Is there any way to check the validity
> of this MDL attached with IRP before calling IoCompleteRequest or any
> workarounds ?
>
> if(pIrp != NULL)
> {
> // Just Complete it with error code
> pIrp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST;
> pIrp->IoStatus.Information = 0;
>
> IoCompleteRequest(pIrp,IO_NO_INCREMENT);
>
> pEntry->pHoldingIrp = NULL;
>
> }
>
> The stack looks like this -
> kd> !analyze -v
> *************************************************************************
>

> *
> *
> * Bugcheck Analysis
> *
> *
> *
> *************************************************************************
>

>
> PFN_LIST_CORRUPT (4e)
> Typically caused by drivers passing bad memory descriptor lists (ie: calling
> MmUnlockPages twice with the same list, etc). If a kernel debugger is
> available get the stack trace.
> Arguments:
> Arg1: 00000007, A driver has unlocked a page more times than it locked it
> Arg2: 00001573, page frame number
> Arg3: 00000001, current share count
> Arg4: 00000000, 0
>
> Debugging Details:
> ------------------
>
>
> DEFAULT_BUCKET_ID: DRIVER_FAULT
>
> BUGCHECK_STR: 0x4E
>
> LAST_CONTROL_TRANSFER: from 8042c0c3 to 80455d74
>
> STACK_TEXT:
> b79b994c 8042c0c3 00000003 b79b9994 00000007
> nt!RtlpBreakWithStatusInstruction
> b79b997c 8042c487 00000003 00001573 818e32c8 nt!KiBugCheckDebugBreak+0x31
> b79b9d08 8044cc80 0000004e 00000007 00001573 nt!KeBugCheckEx+0x390
> b79b9d28 80437612 8154a5c8 81660de8 b79b9d64
> nt!MiDecrementReferenceCount+0xbf
> b79b9d40 8041faa2 8154a500 8153a6a8 8046d41c nt!MmUnlockPages+0x10f
> b79b9d64 ed3ec755 8153a6a8 81660de8 8158d9a8 nt!IopfCompleteRequest+0x1e9
> b79b9d78 80418dc7 8153a6a8 00000000 00000000
> netfilter!NetFilterDenyIrpFreeMemoryWorkRoutine+0x6a
> [E:\NetFilter\NetFilter\Timer.c @ 398]
> b79b9da8 804553af 8153a6a8 00000000 00000000 nt!ExpWorkerThread+0xae
> b79b9ddc 804695b2 80418d02 80000001 00000000 nt!PspSystemThreadStartup+0x69
> 00000000 00000000 00000000 00000000 00000000 nt!KiThreadStartup+0x16
>
>
> FOLLOWUP_IP:
> netfilter!NetFilterDenyIrpFreeMemoryWorkRoutine+6a
> ed3ec755 6880c63eed push 0xed3ec680
>
> FOLLOWUP_NAME: MachineOwner
>
> SYMBOL_NAME: netfilter!NetFilterDenyIrpFreeMemoryWorkRoutine+6a
>
> MODULE_NAME: netfilter
>
> IMAGE_NAME: netfilter.SYS
>
> DEBUG_FLR_IMAGE_TIMESTAMP: 3f8a7fbb
>
> STACK_COMMAND: kb
>
> BUCKET_ID: 0x4E_netfilter!NetFilterDenyIrpFreeMemoryWorkRoutine+6a
>
> Followup: MachineOwner
> ---------
>
>
> any help is appreciated.
> Regards…
> Subodh
>
>
> —
> Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256
>
> You are currently subscribed to ntdev as: xxxxx@storagecraft.com
> To unsubscribe send a blank email to xxxxx@lists.osr.com

In many cases the transport frees the MDL for you (also the associated Irp, and
it undoes the page-fixing). I’m not sure if that applies here, but it is worth
investigating.

xxxxx@softhome.net wrote:

Hi,

My Tdi Filter Driver Monitors certain applications and blocks their IRPs
based on user choice.Everything works well but some times the following code
for denying IRPs generates bugcheck 4E.As soon as IoCompleteRequest is
called a Bug Check 4E appears. It seems that Io Manager is calling
MmUnlockPages Twice on the MDL when i call IoCompleteRequest.But why ? how
to avoid this bug check ? any ideas ? Is there any way to check the validity
of this MDL attached with IRP before calling IoCompleteRequest or any
workarounds ?


If replying by e-mail, please remove “nospam.” from the address.

James Antognini
Windows DDK MVP

Really? What TDI path namely? TDI_SEND? Never saw this.

Maxim Shatskih, Windows DDK MVP
StorageCraft Corporation
xxxxx@storagecraft.com
http://www.storagecraft.com

----- Original Message -----
From: “James Antognini”
Newsgroups: ntdev
To: “Windows System Software Devs Interest List”
Sent: Monday, October 13, 2003 10:03 PM
Subject: [ntdev] Re: PFN_LIST_CORRUPT in TDI Filter Driver

> In many cases the transport frees the MDL for you (also the associated Irp,
and
> it undoes the page-fixing). I’m not sure if that applies here, but it is
worth
> investigating.
>
> xxxxx@softhome.net wrote:
>
> > Hi,
> >
> > My Tdi Filter Driver Monitors certain applications and blocks their IRPs
> > based on user choice.Everything works well but some times the following
code
> > for denying IRPs generates bugcheck 4E.As soon as IoCompleteRequest is
> > called a Bug Check 4E appears. It seems that Io Manager is calling
> > MmUnlockPages Twice on the MDL when i call IoCompleteRequest.But why ? how
> > to avoid this bug check ? any ideas ? Is there any way to check the
validity
> > of this MDL attached with IRP before calling IoCompleteRequest or any
> > workarounds ?
>
> –
> If replying by e-mail, please remove “nospam.” from the address.
>
> James Antognini
> Windows DDK MVP
>
>
>
> —
> Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256
>
> You are currently subscribed to ntdev as: xxxxx@storagecraft.com
> To unsubscribe send a blank email to xxxxx@lists.osr.com

Yes, in TDI Send. For example, I just ran my TDI client (see
http://home.mindspring.com/~antognini/) and set a read-write-access breakpoint on
the MDL used in my TDIClnSend routine (in TDIClientRtns.cpp). Eventually, I saw
this:

ChildEBP RetAddr Args to Child
f48913c8 804ea612 00000000 804ef57b 81aa21f8 nt!RtlpInterlockedPushEntrySList+0xe
f48913d0 804ef57b 81aa21f8 81b6be10 81a50020 nt!IoFreeMdl+0x60
f4891420 804f816d 81b6be10 f489146c f4891460 nt!IopCompleteRequest+0x107
f4891470 806b28c4 00000000 00000000 f4891488 nt!KiDeliverApc+0xb1
f4891470 806b1e6f 00000000 00000000 f4891488 hal!HalpApcInterrupt2ndEntry+0x31
f48914fc f83e4cc3 81967df0 81e87ad8 00000103 hal!KfLowerIrql+0x2f
f4891534 f83f71b5 00000000 00000000 81a80008 NDIS!ndisMAllocSGListS+0x132
f4891550 f7bfc1bf 81a80008 81967df0 00000103 NDIS!ndisMSendSG+0xce
f4891584 f83e4922 81edcb40 81967df0 00000002 psched!MpSend+0xab1
f48915a4 f48fa6a8 81e01a38 81967df0 81b9e7b0 NDIS!ndisMSendX+0x125
f48915cc f48fbc21 81b9e7b0 81967df0 81eedb80 tcpip!ARPSendData+0x181
f48915f4 f490e73a 81b9e700 f4891602 00000001 tcpip!ARPTransmit+0xe1
f4891624 f490e58b 8199a728 0502a8c0 81967df0 tcpip!SendIPPacket+0x18c
f4891744 f48feffe 00000000 00000000 81a4f020 tcpip!IPTransmit+0x2505
f48917ac f48ff27a 00000053 00000000 81b6be40 tcpip!TCPSend+0x57a
f48917cc f48ff4d7 00000001 00000000 00000000 tcpip!TdiSend+0x193
f4891800 f48fe8cd 81b6bdd0 81aa2a5c e197e055 tcpip!TCPSendData+0x81
f4891814 804ea221 81d89530 81b6bdd0 f3f3bc31
tcpip!TCPDispatchInternalDeviceControl+0x4a
f4891824 f3f37996 e197e055 f3f3bc31 819f4960 nt!IopfCallDriver+0x31
f489189c f3f358b2 81dbfe08 81d89530 e197e004 TDIClient!TDIClnSend+0x286
[c:\ja.pgm\src\c\drivers\tdiclient\sys\tdiclientrtns.cpp @ 1707]
nt!RtlpInterlockedPushEntrySList+0xe:
80531a2a 8d8a01000100 lea ecx,[edx+0x10001]

Thus, the MDL was apparently being freed, if I may judge from the second-youngest
routine being IoFreeMdl.

Further, I observed the MDL in a number of passes through TDIClnSend, and the same
MDL address was used several times. Yet I never release the MDL.

I would imagine the same is true of TDI Receive, but I didn’t try that.

My test system is WinXP SP1 Pro.

“Maxim S. Shatskih” wrote:

Really? What TDI path namely? TDI_SEND? Never saw this.


If replying by e-mail, please remove “nospam.” from the address.

James Antognini
Windows DDK MVP