I have a File System Driver (not Filter Driver) that acts as a “proxy” between a file system implemented in user mode and the kernel. This FSD works well in a variety of scenarios and with multiple user mode file systems.
I am experiencing a problem with one of the file systems, named “passthrough”, which simply passes all file system operations through to NTFS. Here is how “passthrough” works, for example, for ReadFile:
[OP is the originating process, OS is NTOS, KF is my FSD, UF is the user mode file system. The UF interacts with the KF by issuing DeviceIoControl calls.]
OP: call NtReadFile
OS: IoCallDriver IRP_MJ_READ
KF: post READ IRP into a queue (ignoring caching complications here)
---- context switch ----
KF: wake up, dequeue READ IRP and return from DeviceIoControl
UF: process READ IRP and send response using DeviceIoControl
KF: complete the READ IRP (and wait for additional IRP’s)
The passthrough file system’s READ IRP processing is simply ReadFile on an underlying NTFS file. This works fine if the underlying NTFS file is opened without FILE_FLAG_NO_BUFFERING, but fails catastrophically if the file is opened with FILE_FLAG_NO_BUFFERING.
I attach the full “!analyze -v” report at the end, but the crux is that Ntfs.sys bugchecks in MmProbeAndLockPages with MEMORY_MANAGEMENT and 61946. The following message by Pavel Lebedinsky explains: http://www.osronline.com/ShowThread.cfm?link=240647
The 0x1A/0x61946 bugcheck happens when the memory manager issues a paging r=
ead and some driver then tries to create a secondary, write-access MDL desc=
ribing the same physical pages. This is bad because when that secondary MDL=
is unlocked the pages will get marked dirty when they’re not supposed be, =
causing various problems downstream.
My FSD implements a “zero-copy” technique where the OP (originating process) buffer gets mapped into the address space of the user mode file system. I do this by using IoAllocateMdl, MmProbeAndLockPages(IoWriteAccess) and MmMapLockedPagesSpecifyCache(UserMode) (in the correct process context). Thus the buffer that arrives to the passthrough file system and is later sent to ReadFile has already an MDL against it. This likely causes the issue.
According to Pavel Lebedinsky again:
To fix this you need to reuse the original MDL instead of creating a new one.
But obviously I cannot do so in my case (even if I somehow made the MDL available to the user mode file system there is no way to use it from user mode).
Any guidance on this is very much appreciated. Is there any way to create the MDL in my FSD so that it does not cause this problem? Any other workarounds? [Other than the obvious ones of ripping the zero-copy mechanism in the FSD or by making a copy of the read buffer in the user mode file system.]
Bill
kd> !analyze -v
*******************************************************************************
* *
* Bugcheck Analysis *
* *
*******************************************************************************
MEMORY_MANAGEMENT (1a)
Any other values for parameter 1 must be individually examined.
Arguments:
Arg1: 0000000000061946, The subtype of the bugcheck.
Arg2: fffffa80039918c0
Arg3: 0000000000034a31
Arg4: 0000000000000000
Debugging Details:
DUMP_CLASS: 1
DUMP_QUALIFIER: 0
BUILD_VERSION_STRING: 9200.16384.amd64fre.win8_rtm.120725-1247
DUMP_TYPE: 0
BUGCHECK_P1: 61946
BUGCHECK_P2: fffffa80039918c0
BUGCHECK_P3: 34a31
BUGCHECK_P4: 0
BUGCHECK_STR: 0x1a_61946
CPU_COUNT: 1
CPU_MHZ: c1c
CPU_VENDOR: GenuineIntel
CPU_FAMILY: 6
CPU_MODEL: 3d
CPU_STEPPING: 4
CPU_MICROCODE: 6,3d,4,0 (F,M,S,R) SIG: 0’00000000 (cache) 0’00000000 (init)
DEFAULT_BUCKET_ID: WIN8_DRIVER_FAULT
PROCESS_NAME: passthrough-x6
CURRENT_IRQL: 2
ANALYSIS_SESSION_HOST: WINDOWS
ANALYSIS_SESSION_TIME: 02-13-2017 12:47:34.0142
ANALYSIS_VERSION: 10.0.10586.567 amd64fre
LAST_CONTROL_TRANSFER: from fffff801089800ea to fffff8010887f930
STACK_TEXT:
fffff880047328f8 fffff801
089800ea : 0000000000000000 00000000
0000001a fffff88004732a60 fffff801
089044b8 : nt!DbgBreakPointWithStatus
fffff88004732900 fffff801
0897f742 : 0000000000000003 fffff880
04732a60 fffff80108904e90 00000000
0000001a : nt!KiBugCheckDebugBreak+0x12
fffff88004732960 fffff801
08885144 : 000000000000010c 00000000
00000004 0000000000000000 00000000
00000000 : nt!KeBugCheck2+0x79f
fffff88004733080 fffff801
089e60d9 : 000000000000001a 00000000
00061946 fffffa80039918c0 00000000
00034a31 : nt!KeBugCheckEx+0x104
fffff880047330c0 fffff801
088d7201 : 0000000000000000 fffff880
04733179 fffffa800383c5c0 fffffa80
039918f0 : nt! ?? ::FNODOBFM::string'+0x1e423 fffff880
04733120 fffff8800164299b : 00000000
00000001 fffffa8002aa9701 fffff980
0910ec60 0000000000000001 : nt!MmProbeAndLockPages+0x161 fffff880
047331e0 fffff88001637140 : fffffa80
02aa9780 fffff9800910ec60 fffff880
047332e0 fffff9800910ec60 : Ntfs!NtfsLockUserBuffer+0x6f fffff880
04733230 fffff880016363d8 : fffff880
047332e0 fffff88004733330 fffffa80
02aa9780 0000000000000001 : Ntfs!NtfsPrepareBuffers+0x68 fffff880
047332a0 fffff88001645b56 : 00000000
00000000 fffff880047336a0 fffff8a0
024f8198 fffff8a0024f8140 : Ntfs!NtfsNonCachedIo+0x1e8 fffff880
047334b0 fffff8800164745b : fffffa80
02aa9780 fffff9800910ec60 fffff880
04733701 0000000000000000 : Ntfs!NtfsCommonRead+0x896 fffff880
04733670 fffff80108e47d26 : fffff980
0910ec60 fffff9800910ec60 00000000
00000002 fffffa8002620340 : Ntfs!NtfsFsdRead+0x1db fffff880
04733720 fffff880014034ee : fffffa80
03572750 fffff880047337c0 fffff980
0910ec60 fffffa8002620340 : nt!IovCallDriver+0x3e6 fffff880
04733770 fffff880014010b6 : fffffa80
035dade0 0000000000000002 fffff980
0910ec60 fffffa800262b0b8 : fltmgr!FltpLegacyProcessingAfterPreCallbacksCompleted+0x25e fffff880
04733810 fffff80108e47d26 : fffff980
0910ec60 0000000000000002 00000000
00000000 fffff8010881772a : fltmgr!FltpDispatch+0xb6 fffff880
04733870 fffff80108c509e8 : 00000000
00000000 fffff88004733941 fffffa80
03855090 fffffa800262b010 : nt!IovCallDriver+0x3e6 fffff880
047338c0 fffff80108bf5c13 : fffffa80
03855090 fffff88004733b80 00000094
140c0000 fffffa8003855090 : nt!IopSynchronousServiceTail+0x158 fffff880
04733990 fffff80108884053 : fffffa80
0383c5c0 0000000000000000 00000000
00000000 0000009415c6f948 : nt!NtReadFile+0x661 fffff880
04733a90 000007fc4c192c0a : 000007fc
4925ebb6 0000009415c6f8c8 cccccccc
cccccccc cccccccccccccccc : nt!KiSystemServiceCopyEnd+0x13 00000094
15c6f868 000007fc4925ebb6 : 00000094
15c6f8c8 cccccccccccccccc cccccccc
cccccccc 0000000000000104 : ntdll!NtReadFile+0xa 00000094
15c6f870 000007f7a3a941ff : 00000000
00000000 0000000000000000 cccccccc
cccccccc 0000009415c6fa94 : KERNELBASE!ReadFile+0x11b 00000094
15c6f8f0 000007fc434bff3e : 00000094
14146d50 0000009414146d20 00000094
140c0000 0000000000000000 : passthrough_x64!Read+0xaf [c:\users\billziss\projects\winfsp\tst\passthrough\passthrough.c @ 343] 00000094
15c6fa60 000007fc434c2291 : 00000094
14146d50 0000009414147070 00000094
1414b040 0000009414147070 : winfsp_x64_7fc43490000!FspFileSystemOpRead+0xae [c:\users\billziss\projects\winfsp\src\dll\fsop.c @ 914] 00000094
15c6faf0 000007fc49aa167e : 00000094
14146d50 0000000000000000 00000000
00000000 0000000000000000 : winfsp_x64_7fc43490000!FspFileSystemDispatcherThread+0x241 [c:\users\billziss\projects\winfsp\src\dll\fs.c @ 519] 00000094
15c6fbc0 000007fc4c1ac3f1 : 00000000
00000000 0000000000000000 00000000
00000000 0000000000000000 : KERNEL32!BaseThreadInitThunk+0x1a 00000094
15c6fbf0 0000000000000000 : 00000000
00000000 0000000000000000 00000000
00000000 00000000`00000000 : ntdll!RtlUserThreadStart+0x1d
STACK_COMMAND: kb
THREAD_SHA1_HASH_MOD_FUNC: c36002737b6fc4159123ea2023cea3f05a2e0e75
THREAD_SHA1_HASH_MOD_FUNC_OFFSET: 4b75bb64569a0fc1ced02ae2eab19a870861b616
THREAD_SHA1_HASH_MOD: 45402f6c887c51b53c8a6ab8db6bf327719f04f2
FOLLOWUP_IP:
nt! ?? ::FNODOBFM::string'+1e423 fffff801
089e60d9 cc int 3
FAULT_INSTR_CODE: 8b4865cc
SYMBOL_STACK_INDEX: 4
SYMBOL_NAME: nt! ?? ::FNODOBFM::`string’+1e423
FOLLOWUP_NAME: MachineOwner
MODULE_NAME: nt
IMAGE_NAME: ntkrnlmp.exe
DEBUG_FLR_IMAGE_TIMESTAMP: 5010ac4b
IMAGE_VERSION: 6.2.9200.16384
BUCKET_ID_FUNC_OFFSET: 1e423
FAILURE_BUCKET_ID: 0x1a_61946_VRF_nt!??::FNODOBFM::string
BUCKET_ID: 0x1a_61946_VRF_nt!??::FNODOBFM::string
PRIMARY_PROBLEM_CLASS: 0x1a_61946_VRF_nt!??::FNODOBFM::string
TARGET_TIME: 2015-11-17T23:10:19.000Z
OSBUILD: 9200
OSSERVICEPACK: 0
SERVICEPACK_NUMBER: 0
OS_REVISION: 0
SUITE_MASK: 272
PRODUCT_TYPE: 1
OSPLATFORM_TYPE: x64
OSNAME: Windows 8
OSEDITION: Windows 8 WinNt TerminalServer SingleUserTS
OS_LOCALE:
USER_LCID: 0
OSBUILD_TIMESTAMP: 2012-07-26 03:32:43
BUILDDATESTAMP_STR: 120725-1247
BUILDLAB_STR: win8_rtm
BUILDOSVER_STR: 6.2.9200.16384.amd64fre.win8_rtm.120725-1247
ANALYSIS_SESSION_ELAPSED_TIME: 329
ANALYSIS_SOURCE: KM
FAILURE_ID_HASH_STRING: km:0x1a_61946_vrf_nt!??::fnodobfm::string
FAILURE_ID_HASH: {ce34d447-5962-57c2-f153-8958bf4cc1f1}