Why shouldn't FltReadFile read into user-mode buffer?

My colleague is at the MS IFS plugfest this week, and our mini-filter driver iis bugchecking with driver verifier turned on. It is using FltReadFile() to read data from a kernel-opened file into a user-mode buffer in PreCreate (surrounded by a __try/__except of course).

Verifier complains that the IRP was issued in kernel mode, but trying to write to a user-mode buffer. The strange thing is that I’ve been running the same driver with driver verifier in our lab for months now, and never hit this bugcheck using standard verifier settings. Maybe a non-standard setting does this check?

What’s wrong with this kind of operation in PreRead ?
I sure hate to lock the user buffer and call MmGetSystemAddressForMdlSafe(), but that seems to be the only way to solve the problem (or copy the data, which is even less appealing.)

Carl

FltReadFile is going to build an IRP with a RequestorMode of KernelMode.
This is going to cause everyone that processes the request to skip buffer
validation, which is really bad when the buffer supplied is a user mode
buffer.

Do you enable Driver Verifier on FltMgr as well as your driver in your
normal testing?

You have a few options:

* Map the buffer and pass the mapped address along. This is probably the
best “I’m at PlugFest and this just needs to work right now” fix
* If you have an MDL, switch to FltReadFileEx (Win8)
* You could build your own callback data and set the requestor mode to User.
This is a bit frowned upon in the docs in that you’re not supposed to build
callback data if a Flt API exists for what you want (i.e. FltReadFile), but
it should just work (have not tried this for this particular situation).

-scott
OSR
@OSRDrivers

wrote in message news:xxxxx@ntfsd…

My colleague is at the MS IFS plugfest this week, and our mini-filter driver
iis bugchecking with driver verifier turned on. It is using FltReadFile()
to read data from a kernel-opened file into a user-mode buffer in PreCreate
(surrounded by a __try/__except of course).

Verifier complains that the IRP was issued in kernel mode, but trying to
write to a user-mode buffer. The strange thing is that I’ve been running
the same driver with driver verifier in our lab for months now, and never
hit this bugcheck using standard verifier settings. Maybe a non-standard
setting does this check?

What’s wrong with this kind of operation in PreRead ?
I sure hate to lock the user buffer and call MmGetSystemAddressForMdlSafe(),
but that seems to be the only way to solve the problem (or copy the data,
which is even less appealing.)

Carl

Scott Says:
FltReadFile is going to build an IRP with a RequestorMode of KernelMode. This is going to cause everyone that processes the request to skip buffer validation, which is really bad when the buffer supplied is a user mode buffer. Do you enable Driver Verifier on FltMgr as well as your driver in your normal testing?


Yup. I know that. I guess my own __try/__except don’t really inform other filters/file systems of my intent. And I learned from previous postings on this subject that you can’t change the IRP RequestorMode for the one the filter manager builds.

For now, I will just use FltLockUserBuffer/MmGetSystemAddressForMdlSafe(), but I like the idea of using just FltLockUserBuffer (to make an MDL if I don’t have one) followed by FltReadFileEx. That seems like the best solution overall. My buddy at Plugfest may get to try it out later this week.

And no, I don’t usually attach the Verifier to fltmgr, only to my own driver.

Thanks,
Carl

Final status - Can’t use FltReadFileEx because the driver has to work in pre-Win8 situation.
As Scott hinted, including fltmgr.sys in the list of drivers to be checked was the trick to getting the bugcheck. That was a good tip. Thanks.

Another trick is to use a checked build of filtermgr.sys

A different class of errors, but still useful (harder to do since the Windows 10 checked build is much harder to find last I heard).

Tony
OSR

If I may, with a final trick that I sometimes like to do in a situation
where I am lost to “why does this happen”, just use the debugger you have
attached and just go through the FltReadFile itself during your call, step
by step with the disassembly in front of you.
Most certainly you would have seen the user buffer issue being checked,
there is also a nt variable used for this. These things are done typically
at the start of the function call.
I believe there is also ObIsKernelHandle that just checks the address
itself if it is in the range of kernel mode, nothing else.
Anyway, hope this helps as well.

Regards,
Gabriel
Windows Kernel Driver Consulting
www.kasardia.com
On Apr 27, 2016 03:11, “Tony Mason” wrote:

>


>
> Another trick is to use a checked build of filtermgr.sys
>
> A different class of errors, but still useful (harder to do since the
> Windows 10 checked build is much harder to find last I heard).
>
> Tony
> OSR
>
>
> —
> NTFSD is sponsored by OSR
>
>
> MONTHLY seminars on crash dump analysis, WDF, Windows internals and
> software drivers!
> Details at http:
>
> To unsubscribe, visit the List Server section of OSR Online at <
> http://www.osronline.com/page.cfm?name=ListServer&gt;
></http:>

Thanks to all. I was not AT the plugfest myself, so probing around with the debugger wasn’t possible at the time.

Now I have an question about another possible solution that doesn’t involve MmGetSystemAddressForMdlSafe(). After calling FltCreateFileEx(), I have a file object. Can I not just roll my own IRP_MJ_READ IRP, specifying the user buffer and proper RequestorMode to send a read request down the driver stack?

When you do so, you’ll create interop issues for yourself, as you will potentially skip mini-filters below you but in the same filter manager call frame. However, the idea isn’t unreasonable if you just do it with a call back data structure that you allocate and set up properly it should work interoperably.

Tony
OSR