Open fcyinxunpeng opened 2 months ago
Hi @fcyinxunpeng ,
RequestContext->Irp->MdlAddress be filled by the program of antivirus software?
It technically could but I believe it shouldn't provide one as the current IRP major is IRP_MJ_DIRECTORY_CONTROL
https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/wdm/ns-wdm-_irp
Pointer to an MDL describing a user buffer, if the driver is using direct I/O, and the IRP major function code is one of the following:
IRP_MJ_READ
The MDL describes an empty buffer that the device or driver fills in.
IRP_MJ_WRITE
The MDL describes a buffer that contains data for the device or driver.
IRP_MJ_DEVICE_CONTROL or IRP_MJ_INTERNAL_DEVICE_CONTROL
If the IOCTL code specifies the METHOD_IN_DIRECT transfer type, the MDL describes a buffer that contains data for the device or driver.
Normally we should allocate that MDL from the UserBuffer
and own it but due to how the code is written, we try to use their.
https://github.com/dokan-dev/dokany/blob/69e3d88c693da08fc1e9c540c162877880eac155/sys/directory.c#L105-L114
We could change our code to override their value by removing this check and the same one in DokanAllocateMdl
to ignore their (bogus?) value.
https://github.com/dokan-dev/dokany/blob/69e3d88c693da08fc1e9c540c162877880eac155/sys/directory.c#L106
Hi @Liryna , Thanks for your reply. I removed this check and the same one in DokanAllocateMdl() https://github.com/dokan-dev/dokany/blob/69e3d88c693da08fc1e9c540c162877880eac155/sys/directory.c#L106 https://github.com/dokan-dev/dokany/blob/69e3d88c693da08fc1e9c540c162877880eac155/sys/dokan.c#L589 But it seems like it's not working because RequestContext->Irp->UserBuffer is always NULL, while RequestContext->Irp->MdlAddress is not NULL even when I don't have antivirus software installed.
If I zero memory in DokanQueryDirecory():
if (RequestContext->Irp->MdlAddress == NULL) {
...
}else{
// test code
buffer = MmGetSystemAddressForMdlNormalSafe(RequestContext->Irp->MdlAddress);
RtlZeroMemory(buffer, bufferLen); // won't crash at this line
}
Dokany2.sys doesn't crash at this line of code, so RequestContext->Irp->MdlAddress is valid at this moment. Maybe then the antivirus software free the content of RequestContext->Irp->MdlAddress , even though dokany2.sys returns a _STATUSPENDING?
Thanks for testing! Yeah that could be possible. Would you be able to contact Rising so they can look into this on their side ?
OK, I intend to ask for official help. And I found that the MmGetSystemAddressForMdlNormalSafe function returns a user-space address instead of a kernel-space address when I use antivirus software scanning.
This is the official reply of rising:
The problem is that when traversing the directory, Rising Anti-Virus Software V17 passes in a user-mode address, causing a blue screen when the dokany driver writes to this address. You can suggest to dokany that you add a method to determine whether the request mode is user mode, or after detecting the user mode address, use the writing method of the user mode address, such as try except and so on.
But I think the real reason is that the anti-virus software modified the address of MmGetSystemAddressForMdlNormalSafe() to point to user space, but this address is only valid in the current context. When dokany is executing DokanCompleteDirectoryControl(), this address is invalid.
Thanks @fcyinxunpeng ! I am not sure about their answer. I believe we do everything correctly. We try catch and lock the page when we receive the request https://github.com/dokan-dev/dokany/blob/69e3d88c693da08fc1e9c540c162877880eac155/sys/dokan.c#L590-L600 and only release when we no longer need it. https://github.com/dokan-dev/dokany/blob/master/sys/directory.c#L323
I agree with you that they might not wait for our completion and do something with the buffer they gave us and things go wrong.
@fcyinxunpeng Were you able to get more info from Rising ?
@Liryna I decompiled one of Rising's driver files named rsutil.sys. In the IoCompletion of IRP_MJ_DIRECTORY_CONTROL, the code releases the MDL without checking the value of IRP->PendingReturned. I have emailed this conclusion to the Rising staff. She replied that it has been forwarded to the developers to investigate the issue, but three weeks have passed, and there has been no news. Rising may not want to modify their code regarding this issue.
Environment
Check List
Description
When I run memfs.exe with administrator privileges on a PC with certain antivirus software installed, I get a BSOD,seemingly crashing in dokan2.sys
If I disable the antivirus software or stop its USB protection feature, memfs.exe can work normally. Also, if I enable the antivirus software and its USB protection feature but run memfs.exe without administrator privileges, memfs.exe can work normally. I've tested version 2.1.0.1000 on both Windows 7 and Windows 10. The name of the antivirus software is Rising, and it's from China. Here is the download page: rising v17 download page
I am a novice and not very familiar with Windows driver development. I have conducted some basic debugging and it seems that the buffer obtained through the MmGetSystemAddressForMdlNormalSafe() function points to an incorrect address. When executing RtlZeroMemory() on this buffer, an error occurred.
I looked into the code, and I have a question: In the DokanQueryDirectory() function (sys/directory.c:106), could the value of RequestContext->Irp->MdlAddress be filled by the program of antivirus software?
My English is bad. This is the translation provided by ChatGPT. Thank you very much.
Logs
Here is my log and the output of !analyze -v:
dokan log:
log.txt
!analyze -v output:
analyze.txt
minidump file:
minidump.dmp