I have a file system driver that also acts as a filter driver. It
makes use of FsRtlRegisterFileSystemFilterCallbacks() as well as
implementing the lock routines in the FAST_IO_DISPATCH
(AcquireFileForNtCreateSection, etc.).
This works just fine on Windows XP SP2 and Windows 2003 with no
service pack. On Windows 2003 SP1, one of my unit tests, which opens
a memory-mapped file on the file system driver-- using a symbolic link
from \DosDevices\Z: to \Device\ElectricFS, not using any of the
filtering functionality) to test writing to it-- crashes with an access
violation. Disabling the FltMgr service is fine as a workaround, but
I’d rather not ship with that.
My driver receives IRP_MJ_CREATE, FastIoQueryStandardInfo,
and IRP_MJ_QUERY_INFORMATION before this crash occurs.
The call stack:
fltmgr!FltpPreFsFilterOperation+0x3b
nt!FsFilterPerformCallbacks+0xa5
nt!FsRtlAcquireFileExclusiveCommon+0x16f
nt!FsRtlAcquireToCreateMappedSection+0x12
nt!MmCreateSection+0x270
nt!NtCreateSection+0x12f
nt!KiFastCallEntry+0xf8
ntdll!KiFastSystemCallRet
ntdll!ZwCreateSection+0xc
ntdll!RtlFreeHeap+0x20e
Relevant instructions leading up to the crash, with my notes from
stepping through the code:
mov eax,[esi+0x8] # eax = FltMgr device object
mov eax,[eax+0x28] # eax = devobj->DeviceExtension
mov eax,[eax+0x2c] # read past the end of the device
extension
…
lea eax,[eax+ecx*8+0x90] # ecx is 0x15 at this point
…
cmp [eax],eax
At the time of the crash, ebx is the FltMgr device object
and edx is the FILE_OBJECT opened in my driver.
Upon inspection with WinDbg, the device extension for FltMgr looks
something like this:
struct FltMgrDevExt {
CSHORT type; /* always 0xf106 */
USHORT size; /* always 0x28 */
DEVICE_OBJECT *target; /* device being filtered */
ULONG something; /* always 815ce000 */
LIST_ENTRY chain; /* links to other extensions */
DEVICE_OBJECT *owner; /* fltmgr filter */
UNICODE_STRING deviceName;
UNICODE_STRING fsName;
} sFltMgrDevExt;
with the buffers for the strings tacked on to the end. When
FltpPreFsFilterOperation() reads past the end of the device extension,
it picks up a couple of unicode characters and eventually winds up
using them as a basis for an address.
I tried turning off the call to
FsRtlRegisterFileSystemFilterCallbacks() in my DriverEntry, but that
didn’t make a difference, so I don’t think the filter functionality
is interfering here.
Is there a way to persuade fltmgr.sys not to filter my device here?
Is there some way my driver could be causing fltmgr.sys to create a
malformed device extension? (It looks internally consistent–
deviceName.Buffer points just after the end of fsName.)
Thanks,
Max