In my filter,In IRP_MJ_WRITE dispatch routine:
In a MN_NORMAL,not paging IO,and the device object is DO_NEITHER_IO(of course it is),so I use Irp->UserBuffer.
It will works well,but in some situation,it will BSOD.
BYTE * pData=NULL;
…
pData=Irp->UserBuffer;
for (i=0;i It will BSOD. In a example: When BSOD occurs,I can see the pData is 0x02A00000,and the pData is invalid.
But why?the pData is from user process,and I handle it in this process context. And what shall I do?
Applications can send you invalid buffers and if your driver cannot
correctly detect and handle this, you’re driver is broken.
It is possible this is an application bug, or perhaps it is something
more subtle, but in either case you clearly have a bug at the moment
because you are not properly probing and using structured exception
handling around your access of a user buffer.
Tony
Tony Mason
Consulting Partner
OSR Open Systems Resources, Inc. http://www.osr.com
And,If I use SEH,I can’t modify the data in Pdata,I just return Error.
That’s to say,this IRP_MJ_WRITE must be bug in App?And the FSD also just return Error?
I can’t miss a normal write,it will modify the data of the file.
Truthfully, I’m not even sure what you are saying.
The normal way this is done is:
__try {
if (UserMode == Irp->RequestorMode) {
// validate that the buffer is in the right address
space
ProbeForRead(Irp->UserBuffer,
IoSp->Parameters.Write.Length, 0);
}
// access buffer here
} __except (MyExceptionFilter(GetExceptionInformation(),
GetExceptionCode()) {
//
// handle exception here
//
Irp->IoStatus.Status = GetExceptionCode();
Irp->IoStatus.Information = 0; // nothing being returned
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return GetExceptionCode();
}
In your exception filter, decide if this is a buffer error (out of
quota, access violation, etc.) and if it is return
EXCEPTION_EXECUTE_HANDLER. Otherwise reject the exception from your
filter (EXCEPTION_CONTINUE_SEARCH) and it’ll still blue screen, just not
because the user buffer is invalid.
My concern is that if you are struggling with something as basic as
this, you are working beyond your current level of knowledge and
experience. When you do not like the answers that we give you, perhaps
you might want to spend more time searching based upon what we’ve told
you. The collective experience of the group on this list is substantial
and it would be wise of you to utilize it with the respect that it is
due.
Regards,
Tony
Tony Mason
Consulting Partner
OSR Open Systems Resources, Inc. http://www.osr.com
I have observed the situation I described.
It is not because the App use invalid memory!
1.Before I calldown(IoCallDriver) the IRP ,I observed the Irp->UserBuffer is 0x05430000,and I use “DB” command to view the memory,the memory is “???”(that means the memory is invalid?).
2.I calldown(IoCallDriver) the IRP,the returned NTSTATUS is STATUS_SUCCESS!
And I use “DB” command to view the memory,the memory is “D0 CF 11 E0…”!That’s the right data,that’s the data of the file!
OK!This is my question:
Why before I CallDown the IRP,the Irp->UserBuffer is invalid?
And After I CallDown the IRP,the IRP->UserBuffer is filled by the correct data?
I would assume its just not paged in yet as you cant page anything while
broken in with a debugger (all interrupts are masked off). You can
attempt to force the pagein however, provided your in the right process
context with “.pagein 0x05430000” and you should then be able to view
the buffer before calling down.
I have observed the situation I described.
It is not because the App use invalid memory!
1.Before I calldown(IoCallDriver) the IRP ,I observed the Irp->UserBuffer is 0x05430000,and I use “DB” command to view the memory,the memory is “???”(that means the memory is invalid?).
2.I calldown(IoCallDriver) the IRP,the returned NTSTATUS is STATUS_SUCCESS!
And I use “DB” command to view the memory,the memory is “D0 CF 11 E0…”!That’s the right data,that’s the data of the file!
OK!This is my question:
Why before I CallDown the IRP,the Irp->UserBuffer is invalid?
And After I CallDown the IRP,the IRP->UserBuffer is filled by the correct data?
i assume he replied .pagein because you posted that you viewed your buffer
with DB
that implies you were using windbg
and .pagein (notice there is a dot in front) is a windbg extension command
that would pagein the buffer you are trying to view
i dont think he was asking you to do pagein in your code
Since its a usermode address you can probe it in within a __try/__except
block safely. You should be able to just reference it but id recommend
using ProbeForRead() ahead of time to validate the buffer. In either
case if the buffer is invalid (and its has to be a usermode address
reference), it will raise an exception and will be caught with the
__except block.
Excellent point. Thanks for clarifying. I suppose in my head the
secondary (unrelated point) I was attempting to make is try/except cant
catch kernel addresses but I ended up just being more confusing then
helpful and really was just wrong in the end. I have seen code
attempting to use try blocks to wrap kernel pointers before.
Maxim S. Shatskih wrote:
> block safely. You should be able to just reference it but id recommend
> using ProbeForRead() ahead of time to validate the buffer.
>
This is a must, since otherwise the app can pass the kernel space pointer there
and junk the kernel itself.
Oh,God,I have MmProbeAndLockPages,but still get a exception.
When I meet a non-paging IO,the Irp->MdlAddress is NULL,and according to the flag of the DO,I should take the Irp->UserBuffer.
I have described the case:
>1.Before I calldown(IoCallDriver) the IRP ,I observed the Irp->UserBuffer is
0x05430000,and I use “DB” command to view the memory,the memory is
“???”(that means the memory is invalid?).
>2.I calldown(IoCallDriver) the IRP,the returned NTSTATUS is STATUS_SUCCESS!
And I use “DB” command to view the memory,the memory is “D0 CF 11 E0…”!That’s the right data,that’s the data of the file!
wrote in message news:xxxxx@ntfsd… > Oh,God,I have MmProbeAndLockPages,but still get a exception. > When I meet a non-paging IO,the Irp->MdlAddress is NULL,and according to > the flag of the DO,I should take the Irp->UserBuffer. > I have described the case: >>>1.Before I calldown(IoCallDriver) the IRP ,I observed the Irp->UserBuffer >>>is > 0x05430000,and I use “DB” command to view the memory,the memory is > “???”(that means the memory is invalid?). >>>2.I calldown(IoCallDriver) the IRP,the returned NTSTATUS is >>>STATUS_SUCCESS! > And I use “DB” command to view the memory,the memory is “D0 CF 11 > E0…”!That’s the right data,that’s the data of the file! > > OK,the following is my code for handling it: > > __try > { > if (!(PtrMdl = IoAllocateMdl(Irp->UserBuffer, nSize, FALSE, FALSE, NULL))) > { > nRet=STATUS_INSUFFICIENT_RESOURCES; > Irp->IoStatus.Status=nRet; > } > else > { > MmProbeAndLockPages(PtrMdl, Irp->RequestorMode, IoWriteAccess); > pData = MmGetSystemAddressForMdlSafe(PtrMdl, NormalPagePriority ); > } > } >__except(EXCEPTION_EXECUTE_HANDLER) > { > nRet=STATUS_INVALID_USER_BUFFER; > Irp->IoStatus.Status=nRet; > IoFreeMdl(PtrMdl); > } > > > But,when I call MmProbeAndLockPages,will throw the except. > What’s wrong with my code?I think it should work. > Thanks for your help~~~ >
wrote in message news:xxxxx@ntfsd… > Oh,God,I have MmProbeAndLockPages,but still get a exception. > When I meet a non-paging IO,the Irp->MdlAddress is NULL,and according to > the flag of the DO,I should take the Irp->UserBuffer. > I have described the case: >>>1.Before I calldown(IoCallDriver) the IRP ,I observed the Irp->UserBuffer >>>is > 0x05430000,and I use “DB” command to view the memory,the memory is > “???”(that means the memory is invalid?). >>>2.I calldown(IoCallDriver) the IRP,the returned NTSTATUS is >>>STATUS_SUCCESS! > And I use “DB” command to view the memory,the memory is “D0 CF 11 > E0…”!That’s the right data,that’s the data of the file! > > OK,the following is my code for handling it: > > __try > { > if (!(PtrMdl = IoAllocateMdl(Irp->UserBuffer, nSize, FALSE, FALSE, NULL))) > { > nRet=STATUS_INSUFFICIENT_RESOURCES; > Irp->IoStatus.Status=nRet; > } > else > { > MmProbeAndLockPages(PtrMdl, Irp->RequestorMode, IoWriteAccess); > pData = MmGetSystemAddressForMdlSafe(PtrMdl, NormalPagePriority ); > } > } >__except(EXCEPTION_EXECUTE_HANDLER) > { > nRet=STATUS_INVALID_USER_BUFFER; > Irp->IoStatus.Status=nRet; > IoFreeMdl(PtrMdl); > } > > > But,when I call MmProbeAndLockPages,will throw the except. > What’s wrong with my code?I think it should work. > Thanks for your help~~~ >
If access mode is UserMode then the address range is checked to be in user
space, if KernelMode the check is skipped.
So it is reasonable to use Irp->RequestorMode.
Also, for IRP_MJ_WRITE request the operation should be IoReadAccess and
IoWriteAccess for IRP_MJ_READ .
But this doesn’t solve the problem because I suppose the reason is an
invalid range.
“Lyndon J Clarke” wrote in message news:xxxxx@ntfsd… > MmProbeAndLockPages(PtrMdl, KernelMode, IoWriteAccess); > ^^^^^^^^^^ > > ??? > > wrote in message news:xxxxx@ntfsd… >> Oh,God,I have MmProbeAndLockPages,but still get a exception. >> When I meet a non-paging IO,the Irp->MdlAddress is NULL,and according to >> the flag of the DO,I should take the Irp->UserBuffer. >> I have described the case: >>>>1.Before I calldown(IoCallDriver) the IRP ,I observed the >>>>Irp->UserBuffer is >> 0x05430000,and I use “DB” command to view the memory,the memory is >> “???”(that means the memory is invalid?). >>>>2.I calldown(IoCallDriver) the IRP,the returned NTSTATUS is >>>>STATUS_SUCCESS! >> And I use “DB” command to view the memory,the memory is “D0 CF 11 >> E0…”!That’s the right data,that’s the data of the file! >> >> OK,the following is my code for handling it: >> >> __try >> { >> if (!(PtrMdl = IoAllocateMdl(Irp->UserBuffer, nSize, FALSE, FALSE, >> NULL))) >> { >> nRet=STATUS_INSUFFICIENT_RESOURCES; >> Irp->IoStatus.Status=nRet; >> } >> else >> { >> MmProbeAndLockPages(PtrMdl, Irp->RequestorMode, IoWriteAccess); >> pData = MmGetSystemAddressForMdlSafe(PtrMdl, NormalPagePriority ); >> } >> } >>__except(EXCEPTION_EXECUTE_HANDLER) >> { >> nRet=STATUS_INVALID_USER_BUFFER; >> Irp->IoStatus.Status=nRet; >> IoFreeMdl(PtrMdl); >> } >> >> >> But,when I call MmProbeAndLockPages,will throw the except. >> What’s wrong with my code?I think it should work. >> Thanks for your help~~~ >> > > >
Fair comment, agreed, IIRC Irp->RequestorMode is exact as FatLockUserBuffer
“Slava Imameyev” wrote in message news:xxxxx@ntfsd… >> MmProbeAndLockPages(PtrMdl, KernelMode, IoWriteAccess); > > If access mode is UserMode then the address range is checked to be in user > space, if KernelMode the check is skipped. > So it is reasonable to use Irp->RequestorMode. > > Also, for IRP_MJ_WRITE request the operation should be IoReadAccess and > IoWriteAccess for IRP_MJ_READ . > > But this doesn’t solve the problem because I suppose the reason is an > invalid range. > > – > Slava Imameyev, xxxxx@hotmail.com > > > “Lyndon J Clarke” wrote in message > news:xxxxx@ntfsd… >> MmProbeAndLockPages(PtrMdl, KernelMode, IoWriteAccess); >> ^^^^^^^^^^ >> >> ??? >> >> wrote in message news:xxxxx@ntfsd… >>> Oh,God,I have MmProbeAndLockPages,but still get a exception. >>> When I meet a non-paging IO,the Irp->MdlAddress is NULL,and according to >>> the flag of the DO,I should take the Irp->UserBuffer. >>> I have described the case: >>>>>1.Before I calldown(IoCallDriver) the IRP ,I observed the >>>>>Irp->UserBuffer is >>> 0x05430000,and I use “DB” command to view the memory,the memory is >>> “???”(that means the memory is invalid?). >>>>>2.I calldown(IoCallDriver) the IRP,the returned NTSTATUS is >>>>>STATUS_SUCCESS! >>> And I use “DB” command to view the memory,the memory is “D0 CF 11 >>> E0…”!That’s the right data,that’s the data of the file! >>> >>> OK,the following is my code for handling it: >>> >>> __try >>> { >>> if (!(PtrMdl = IoAllocateMdl(Irp->UserBuffer, nSize, FALSE, FALSE, >>> NULL))) >>> { >>> nRet=STATUS_INSUFFICIENT_RESOURCES; >>> Irp->IoStatus.Status=nRet; >>> } >>> else >>> { >>> MmProbeAndLockPages(PtrMdl, Irp->RequestorMode, IoWriteAccess); >>> pData = MmGetSystemAddressForMdlSafe(PtrMdl, NormalPagePriority ); >>> } >>> } >>>__except(EXCEPTION_EXECUTE_HANDLER) >>> { >>> nRet=STATUS_INVALID_USER_BUFFER; >>> Irp->IoStatus.Status=nRet; >>> IoFreeMdl(PtrMdl); >>> } >>> >>> >>> But,when I call MmProbeAndLockPages,will throw the except. >>> What’s wrong with my code?I think it should work. >>> Thanks for your help~~~ >>> >> >> >> > > >