Question about freeing memory allocated via MmAllocatePagesForMdl

Hello All,

I am allocating some physical memory via MmAllocatePagesForMdl which I then
map to user space of my controlling process.

At some point later, the process does an IOCTL and I unmap the pages and
free them. So far so good.

Now, let us say, my process dies without calling this IOCTL, do I still
need to both unmap and free or is just free’ing good enough? I am wondering
if the Windows kernel would unmap the pages automatically when it destroys
the virtual address space of the process?

I am seeing a physical memory leak when I arbitrarily kill the process
without calling the IOCTL which doesn’t give it a chance to unmap. Please
note that I still free the pages inside my driver at some point in the
future, but that still doesn’t seem to free the pages. So it appears that I
still need to unmap the pages at the last point where my driver is invoked
in the process context even when the process exists uncleanly. Is this
understanding correct?

Thanks
screwgauge

>Now, let us say, my process dies without calling this IOCTL, do I still need to both unmap and free or is just free’ing good >enough?

No, it isn’t.

I am wondering if the Windows kernel would unmap the pages automatically when it destroys the virtual address space of >the process?

No. None of this will be done automatically for you.

I am seeing a physical memory leak when I arbitrarily kill the process without calling the IOCTL which doesn’t give it a chance >to unmap.

Run with Verifier on, this should give you a bugcheck.

So it appears that I still need to unmap the pages at the last point where my driver is invoked in the process context even >when the process exists uncleanly. Is this understanding correct?

Yes, your driver will receive an IRP_MJ_CLEANUP for its handle to your driver. That is where you should carefully unmap the locked pages and free the memory if required. In case you are writing a minifilter, the right place to do this is when the reference count of the communication port object goes down to zero, in the disconnect callback routine of your communication port.

Moreover, the practice of sharing kernel memory with an application is considered bad practice. It’s very hard to get right and you need to know what you are doing. You should strongly consider using the inverted call method for communication between your app and the driver or just use the communication port functions if you are a minifilter.

//Daniel

“Suman Saraf” wrote in message news:xxxxx@ntfsd…
Hello All,

I am allocating some physical memory via MmAllocatePagesForMdl which I then map to user space of my controlling process.

At some point later, the process does an IOCTL and I unmap the pages and free them. So far so good.

Now, let us say, my process dies without calling this IOCTL, do I still need to both unmap and free or is just free’ing good enough? I am wondering if the Windows kernel would unmap the pages automatically when it destroys the virtual address space of the process?

I am seeing a physical memory leak when I arbitrarily kill the process without calling the IOCTL which doesn’t give it a chance to unmap. Please note that I still free the pages inside my driver at some point in the future, but that still doesn’t seem to free the pages. So it appears that I still need to unmap the pages at the last point where my driver is invoked in the process context even when the process exists uncleanly. Is this understanding correct?

Thanks
screwgauge

I like to give simple design rules, and especially anti-rules. There are
always exceptions, but these exceptions can be understood only by
highly-experienced driver writers.

One rule is: If you think you want to share kernel memory with user
memory, you are wrong.

So any design in which you create kernel memory and share it with user
space should be understood to be valid only as measured by your experience
writing drivers. If you are new at this, the probability that this design
is screamingly wrong approach 100%. If you are highly-experienced, with
many drivers and years of experience, you just might be right, and my
simple rule does not apply. From the nature of the questions, however, I
suspect that you are new at this, because an experienced driver writer
would have already known about all these problems.

Throw it out and start using inverted call. Any rationale about why the
idea of sharing kernel memory with user space is “good” is based on urban
legend. Except in those specifically rare and exotic situations where it
is the right decision. People who don’t understand Windows often latch
onto this solution as their first approach, particularly because it is a
common pattern in many realtime systems (where it works fine, because they
all run in real mode and therefore there is no cost or complexity in such
systems. You are no longer in that world). If this is what you have
done, then redesign the driver. You are dancing through a minefield.
Without a map.
joe

>Now, let us say, my process dies without calling this IOCTL, do I still
> need to both unmap and free or is just free’ing good >enough?

No, it isn’t.

>I am wondering if the Windows kernel would unmap the pages automatically
> when it destroys the virtual address space of >the process?

No. None of this will be done automatically for you.

>I am seeing a physical memory leak when I arbitrarily kill the process
> without calling the IOCTL which doesn’t give it a chance >to unmap.

Run with Verifier on, this should give you a bugcheck.

>So it appears that I still need to unmap the pages at the last point
> where my driver is invoked in the process context even >when the process
> exists uncleanly. Is this understanding correct?

Yes, your driver will receive an IRP_MJ_CLEANUP for its handle to your
driver. That is where you should carefully unmap the locked pages and free
the memory if required. In case you are writing a minifilter, the right
place to do this is when the reference count of the communication port
object goes down to zero, in the disconnect callback routine of your
communication port.

Moreover, the practice of sharing kernel memory with an application is
considered bad practice. It’s very hard to get right and you need to
know what you are doing. You should strongly consider using the inverted
call method for communication between your app and the driver or just use
the communication port functions if you are a minifilter.

//Daniel

“Suman Saraf” wrote in message
> news:xxxxx@ntfsd…
> Hello All,
>
> I am allocating some physical memory via MmAllocatePagesForMdl which I
> then map to user space of my controlling process.
>
> At some point later, the process does an IOCTL and I unmap the pages and
> free them. So far so good.
>
> Now, let us say, my process dies without calling this IOCTL, do I still
> need to both unmap and free or is just free’ing good enough? I am
> wondering if the Windows kernel would unmap the pages automatically when
> it destroys the virtual address space of the process?
>
> I am seeing a physical memory leak when I arbitrarily kill the process
> without calling the IOCTL which doesn’t give it a chance to unmap. Please
> note that I still free the pages inside my driver at some point in the
> future, but that still doesn’t seem to free the pages. So it appears that
> I still need to unmap the pages at the last point where my driver is
> invoked in the process context even when the process exists uncleanly. Is
> this understanding correct?
>
> Thanks
> screwgauge
>
>
> —
> NTFSD is sponsored by OSR
>
> OSR is hiring!! Info at http://www.osr.com/careers
>
> For our schedule of debugging and file system seminars visit:
> http://www.osr.com/seminars
>
> To unsubscribe, visit the List Server section of OSR Online at
> http://www.osronline.com/page.cfm?name=ListServer

Pages mapped into user space using MmMapLockedPages are unmapped automatically when the process terminates. So your memory leak is caused by something else.

Note that you do have to unmap the pages manually if you ever want to free (or unlock) them. See this thread for details:

https://www.osronline.com/ShowThread.cfm?link=213823

Better yet, follow Daniel’s advice below and use a different approach that doesn’t require mapping kernel memory into user space.

From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of xxxxx@xxx.com
Sent: Tuesday, September 24, 2013 8:44 AM
To: Windows File Systems Devs Interest List
Subject: Re:[ntfsd] Question about freeing memory allocated via MmAllocatePagesForMdl

Now, let us say, my process dies without calling this IOCTL, do I still need to both unmap and free or is just free’ing good >enough?

No, it isn’t.

I am wondering if the Windows kernel would unmap the pages automatically when it destroys the virtual address space of >the process?

No. None of this will be done automatically for you.

I am seeing a physical memory leak when I arbitrarily kill the process without calling the IOCTL which doesn’t give it a chance >to unmap.

Run with Verifier on, this should give you a bugcheck.

So it appears that I still need to unmap the pages at the last point where my driver is invoked in the process context even >when the process exists uncleanly. Is this understanding correct?

Yes, your driver will receive an IRP_MJ_CLEANUP for its handle to your driver. That is where you should carefully unmap the locked pages and free the memory if required. In case you are writing a minifilter, the right place to do this is when the reference count of the communication port object goes down to zero, in the disconnect callback routine of your communication port.

Moreover, the practice of sharing kernel memory with an application is considered bad practice. It’s very hard to get right and you need to know what you are doing. You should strongly consider using the inverted call method for communication between your app and the driver or just use the communication port functions if you are a minifilter.