MmUnlockPages and BSOD Bug Check 0x4E PFN_LIST_CORRUPT

Hi All,

I am trying to unlock pages described by a MDL. When calling the function MmUnlockPages, i got the BSOD PFN_LIST_CORRUPT.
The Arg1 says it is still locked for IO so MmUnlockPages call is basically trying to unlock before freeing the MDL. Then why the BSOD occurs?
If we are freeing the pages before unlocking then it is wrong. But here I am trying to unlock before freeing it but still observing BSOD.

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: 000000000000009a, ===>** A driver attempted to free a page that is still locked for IO. **
Arg2: 00000000005fe6e6
Arg3: 0000000000000000
Arg4: 0000000000000000

Thanks in Advance,
Parsa

Where did you get the MDL? Are these pages that you locked? Did you get a stack trace?

As an example, if you try to MmUnlockPages on an MDL that you got in an IRP, that would cause this.

Hi Tim,

Thanks for you reply.

The MDL is created in my driver code. The user mode program allocates memory and passes to the driver in the IOCTL call. Then driver creates MDL to map the user space address like

DrvMDL = IoAllocateMdl(UserBuf, sizeof(MEM_BYTES), FALSE, FALSE, NULL);

Then i am calling MmProbeAndLockPages to lock the pages in try/except block.

try
{
MmProbeAndLockPages(DrvMDL, UserMode, IoWriteAccess);
}
except(EXCEPTION_EXECUTE_HANDLER)
{
ntStatus = STATUS_INVALID_USER_BUFFER;
break;
}

One thing I missed in my code is if locking the physical pages fails then in the except block I am not freeing the MDL so DrvMDL could be pointing MDL pages that is not actually locked. So call to MmUnlockPages can cause BSOD. I tried this experiment too (unlocking the pages without locking) but in this case i am getting BSOD 0x4E but it has different parameters.