Hi,
I have in my filesystem filter driver a bugcheck:
DRIVER_VERIFIER_DETECTED_VIOLATION (c4) -
Arg1: 00000000000000e3, Kernel Zw API called with user-mode address as parameter.
Arg2: fffff8002afba2e0, Address inside the driver making the incorrect API call.
Arg3: 00000000005c82a8, User-mode address used as API parameter.
Arg3 mentioned here is the inputBuffer (from user mode) that represents the device to open passed to ZwCreateFile:
STACK_TEXT:
nt!DbgBreakPointWithStatus
nt!KiBugCheckDebugBreak+0x12
nt!KeBugCheck2+0x8ab
nt!KeBugCheckEx+0x104
nt!VerifierBugCheckIfAppropriate+0x3c
nt!ViZwCheckAddress+0x35
nt!ViZwCheckUnicodeString+0x2e
nt!ViZwCheckObjectAttributes+0x26
nt!VfZwCreateFile+0x5d
MYDRV!GetPdoDeviceFromFdo
MYDRV!DrvFastIoDeviceControl
nt!IopXxxControlFile+0x7c2
nt!NtDeviceIoControlFile+0x56
nt!KiSystemServiceCopyEnd+0x13
wow64cpu!CpupSyscallStub+0x2
wow64cpu!DeviceIoctlFileFault+0x31
wow64!RunCpuSimulation+0xa
wow64!Wow64LdrpInitialize+0x172
ntdll!_LdrpInitialize+0xcb
ntdll!LdrInitializeThunk+0xe
The call from the stack that triggers bugcheck is (from function GetPdoDeviceFromFdo):
RtlInitUnicodeString(&devicePath, (LPWSTR)inputBuffer);
InitializeObjectAttributes(&objectAttributes, &devicePath, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, NULL);
ntStatus = ZwCreateFile(&fileHandle, SYNCHRONIZE | FILE_ANY_ACCESS, &objectAttributes, &status, NULL, 0, FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_OPEN, FILE_SYNCHRONOUS_IO_NONALERT, NULL, 0);
0: kd> dv
inputBuffer = 0x00000000005c82a8 -- this is the address verifier "seems" to compalin !! outputBuffer = 0x00000000
0389f79c
outputBufferLength = 0x411
devicePath = “??\Volume{b90196ba-3f1c-11e6-9bfa-08002781e119}”
Device Path is created based on inputBuffer and passed as objectAttributes to ZwCreateFile. What could go wrong about this ?
Debugging this it seems to happen while system is starting, I saw times where this call was successful using same devicePath (verifier was not enabled). Or maybe other parameters are wrong, not what is hinted by verifier ?
This call happens as part of a user mode IO control defined for our driver communication device. One unusual thing is that this is using fast io (fastIoDispatch->FastIoDeviceControl = DrvFastIoDeviceControl) The control code was defined like this:
#define MyDrv_getpdodev (ULONG) CTL_CODE(IOCTL_UNKNOWN_BASE, 0x815, METHOD_BUFFERED, FILE_ANY_ACCESS)
What I find strange is that the inputBuffer is a valid user mode address (but ioctl uses method buffered). The callstack is running at irql PASSIVE so that should not be an issue.
Any hints to check will be welcomed !
Regards
-Ghita