Bug in Filter Manager's FltIsDirectory PDF

In XP the implementation of FltIsDirectory is buggy. This document describes the issue and an opensource fix which pacthes filtermanager with a working solution.

 

 

FltIsDirectory() is used find out whether a file object is for a directory or a file.  Unfortuately in Windows XP the filter manager communicates directly with the next lowest driver to estblish this information Thus, any minifilter which does file object shadowing will cause NTFS to crash, if a minifilter above it issues FltIsDirectory. In dumps that I have seen, the filter "cmdguard.sys" is often the unfortunate victim.   Let me emphasise that I believe that that filter is entirely innocent of that crash.

 

A typical dump has Ntfs!NtfsDecodeFileObject at the top of the stack, then fltmgr!FltIsDirectory below it somewhere.

 

Ntfs!NtfsDecodeFileObject+0x37
Ntfs!NtfsCommonQueryInformation+0x56
Ntfs!NtfsFsdDispatchSwitch+0x12a
Ntfs!NtfsFsdDispatchWait+0x1c
nt!IopfCallDriver+0x31
sr!SrPassThrough+0x31
nt!IopfCallDriver+0x31
fltmgr!FltpQueryInformationFile+0x99
fltmgr!SetStreamListStandardInformationFlags+0x7e
fltmgr!FltIsDirectory+0x4b

 

As far as I am aware there is no hotfix available for this, although I'd be happy to hear otherwise. This is somewhat frustrating given the pressure that the MS Developers have put on people to go down the shadow file object route.

 

The fix would be to get FltIsFilter to obey the filter hierarchy, and example might be:

 

 

NTSTATUS
FLTAPI
MyFltIsDirectory (
    __in PFILE_OBJECT FileObject,
    __in PFLT_INSTANCE Instance,
    __out PBOOLEAN IsDirectory
    )
{
    NTSTATUS status;
    FILE_BASIC_INFORMATION basic = {0};
    ULONG len;

    //
    // Grab the attributes _at the correct altitude__
    //
    status = FltQueryInformationFile(Instance, FileObject, &basic, sizeof(basic), FileBasicInformation, &len);

    //
    // Set the flag.  Doesn't matter whether we have failed or not...
    //
    *IsDirectory = BooleanFlagOn(basic.FileAttributes, FILE_ATTRIBUTE_DIRECTORY);

    //
    // And back top the user
    //
    return status;
}

 

 

The only technique I have found to make this work is to patch filter manager 'in situ'. The best way to achieve this is as a separate non unloadable driver, this allows one to use the "trampoline" to patch the code in a crash proof manner. If one needs to make the code unloadable one has to patch and unpatch and it is this last operation which can be problematic.

 

I have made my code available open source under the Apache 2 license at http://steadingsoftware.com/PatchFltMgr/PatchFltMgr.ZIP. Please feel free to contact me at rdw _at_ steadingsoftware _dot_ come if you need further assistance.

 

Recent Article

Testing at the edge

Hints and tips for exploring the corners of your Windows FSD or File System filter.

 

Several people have recently asked me about testing “into the corners of the file system”, and this article is an attempt to point out some of the darker corners that you may want to look into while testing file systems and file system drivers. 

Read more...
 

Recent Blog

Logo for Kernel Filter drivers

It looks likely that Microsoft will be introducing a logo program for filesystem and registry filters.

Read more...