Windows System Software -- Consulting, Training, Development -- Unique Expertise, Guaranteed Results

Home NTDEV
Before Posting...
Please check out the Community Guidelines in the Announcements and Administration Category.

More Info on Driver Writing and Debugging


The free OSR Learning Library has more than 50 articles on a wide variety of topics about writing and debugging device drivers and Minifilters. From introductory level to advanced. All the articles have been recently reviewed and updated, and are written using the clear and definitive style you've come to expect from OSR over the years.


Check out The OSR Learning Library at: https://www.osr.com/osr-learning-library/


MDL using leads to PFN BugCheck 4E

K_WellerK_Weller Member Posts: 13

Hi all,

my driver (WDM) worked like this for years. Now, all of the sudden the driver issues a BugCheck 4E, {9a, 67762, 6, 2} when I unconnect the device with an open user space application in the background.
The user space DLL share some MDL with the kernel.

I allocate and map it like this:

`void MAP()
{

PVODI myAdress = ExAllocatePoolWithTag(NonPagedPool, MY_SIZE, '123');

mdl = IoAllocateMdl(myAdress, MY_SIZE, FALSE, FALSE, NULL);

if (!mdl)
{
    return;
}

MmBuildMdlForNonPagedPool(mdl);

userVAToReturn = MmMapLockedPagesSpecifyCache(mdl,    
    UserMode,     // Mode
    MmCached,     // Caching
    NULL,         // Address
    FALSE,        // Bugcheck?
    NormalPagePriority); // Priority  


//
// If we get NULL back, the request didn't work.
// I'm thinkin' that's better than a bug check anyday.
//
if (!userVAToReturn)  {
    MmFreePagesFromMdl(mdl);
    IoFreeMdl(mdl);
    return;
}

//
// Return the allocated pointers.
//
*UserVa = userVAToReturn;
*PMemMdl = mdl;

// store it here to free them if device will surprise removed
m_myUserVA = userVAToReturn;
m_myMddl = mdl;

}`

And if the device gets unplugged for example I call this:

`void UNMAP()
{

if (!m_myMddl) {
    return;
}

//
// Unmap the pages.
//
MmUnmapLockedPages(m_myUserVA, m_myMddl);

//
// Release the MDL.
//
IoFreeMdl(m_myMddl);
m_myMddl = NULL; 
m_myUserVA = NULL;

}`

This is part of the code was never touched in the last years and I did not write it. But well it was working OK without any issues for the last couple of years. Now ( I guess) since an Windows 10 update it starts Bugchecking with above E4 code: PFN_LIST_CORRUPT

If I do not allocate the above mdl it won't BugCheck ... Some months ago on the same PC it was working well.

So the question is, is the MDL code correct or do I missed something here ?
Is this OK to free the the mdl inside the driver and not from the UserMode dll in this case ?

Best regards,
K.Weller

Comments

  • Sergey_PisarevSergey_Pisarev Member - All Emails Posts: 264

    Have you tried to run this driver under verifier ?

  • K_WellerK_Weller Member Posts: 13

    Hi Sergey,

    I'll do. I missed it unfortunately.
    But beside that I nopticed something else. The allocated buffer:

    myAdress 
    
    PVODI myAdress = ExAllocatePoolWithTag(NonPagedPool, MY_SIZE, '123');
    
    mdl = IoAllocateMdl(myAdress, MY_SIZE, FALSE, FALSE, NULL);
    

    is a bigger block and is devided. One half is used for what ever, the other half will become the mdl.
    I changed this and handle this seperate now and now it is working again. But well I'm still not sure if all in this code area is OK or not.
    But I will try with the verifier and post my results.

    Thanks and Reagrds,
    K.Weller

  • Mark_RoddyMark_Roddy Member - All Emails Posts: 4,374
    via Email
    "Note that if the call to MmMapLockedPages or MmMapLockedPagesSpecifyCache
    specified user mode, the caller must be in the context of the original
    process before calling MmUnmapLockedPages. This is because the unmapping
    operation occurs in the context of the calling process, and, if the context
    is incorrect, the unmapping operation could delete the address range of a
    random process."

    Mark Roddy
  • K_WellerK_Weller Member Posts: 13

    Hi Mark,

    this means I need to trigger the unmapping from the same user mode process which mapped it ?
    Or is my driver the correct context and I can take care of the mapping from inside the driver during clean up for example if a "SurpriseRemoval" happens etc. So if I save pointers like I showed above and clean them up it is OK?

    Or am I totally wrong in understanding this issue ?

    I probably do not understand this, from the Remarks section fully and if this is related to above:

    The routine returns a user address that is valid in the context of the process in which the driver is running. For example, if a 64-bit driver is running in the context of a 32-bit application, the buffer is mapped to an address in the 32-bit address range of the application.

    https://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/wdm/nf-wdm-mmmaplockedpagesspecifycache

    @Sergey_Pisarev
    verifier seems to do not find anything obviously here. So the bugcheck from above appears and verifier will not bugcheck.

    thanks and Regards,
    K.Weller

  • Peter_Viscarola_(OSR)Peter_Viscarola_(OSR) Administrator Posts: 8,090

    means I need to trigger the unmapping from the same user mode process which mapped it ?

    Yes. Exactly this.

    is my driver the correct context and I can take care of the mapping from inside the driver during clean up

    Specific to Cleanup (as in the function that’s called when the last close of a handle is issued): Yes, cleanup is called in the context of the process that’s calling Close. If a process opens a handle to your device, and then calls Close, your driver will be called in the context of the “correct” process.

    Understand, however, that there are situations in which things don’t work out well. For example, consider when a process opens your device, then your driver maps the section into the process address space. Sometime later, that process duplicates that handle to another process. Who’s to say that the other process isn’t the last one to call Close, causing your a Cleanup to run in the context of the wrong process?

    This is one reason why we so strongly recommend people do not map sections back into user space... and if they do, they do it using Direct I/O and not roll their own.

    Peter

    Peter Viscarola
    OSR
    @OSRDrivers

Sign In or Register to comment.

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Upcoming OSR Seminars
OSR has suspended in-person seminars due to the Covid-19 outbreak. But, don't miss your training! Attend via the internet instead!
Writing WDF Drivers 7 Dec 2020 LIVE ONLINE
Internals & Software Drivers 25 Jan 2021 LIVE ONLINE
Developing Minifilters 8 March 2021 LIVE ONLINE