Am I going crazy...

or am I finding too many FltMgr bugs lately?
The attached sample is a ridiculously basic mini-filter which
“achieves” BSODs not only often enough to wonder, but often enough to be
useless :frowning:
The sample (has nothing to do with Scanner sample, I only used it as
a skeleton) queries file name during pre-create, file name during
post-create (just for test) and file ID and directory flag during post
create.
I’ve posted some cases where this code crashes in the last few
weeks, here’s another:
Remote Desktop on Srv03, with Local Drives brought to the terminal.
When accessing “local drives” the remote machine bug checks with 0x7E in
RDP drivers.

For this bugcheck, the GetDirectoryFlag is at fault. Even though the
code is so simple, I’ve gone through it a dozen times, and it’s good.
What is the problem with getting the FileStandardInformation during RD
session?

#include <winerror.h>
#include <fltkernel.h>
#include “scanner.h”
PFLT_FILTER gFilter;

const FLT_OPERATION_REGISTRATION Callbacks = {
{ IRP_MJ_CREATE, 0, ScannerPreCreate, ScannerPostCreate},
{ IRP_MJ_FAST_IO_CHECK_IF_POSSIBLE, 0, ScannerPreCreate,
ScannerPostCreate},
{ IRP_MJ_NETWORK_QUERY_OPEN, 0, ScannerPreCreate,
ScannerPostCreate},
{ IRP_MJ_OPERATION_END}
};

const FLT_CONTEXT_REGISTRATION ContextRegistration = {
{ FLT_CONTEXT_END }
};

const FLT_REGISTRATION FilterRegistration = {

sizeof( FLT_REGISTRATION ), // Size
FLT_REGISTRATION_VERSION, // Version
0, // Flags
ContextRegistration, // Context Registration.
Callbacks, // Operation callbacks
ScannerUnload, // FilterUnload
ScannerInstanceSetup, // InstanceSetup
ScannerQueryTeardown, // InstanceQueryTeardown
NULL, // InstanceTeardownStart
NULL, // InstanceTeardownComplete
NULL, // GenerateFileName
NULL, // GenerateDestinationFileName
NULL // NormalizeNameComponent
};

NTSTATUS
DriverEntry (
IN PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegistryPath
)
{
OBJECT_ATTRIBUTES oa;
UNICODE_STRING uniString;
PSECURITY_DESCRIPTOR sd;
NTSTATUS status;

FltRegisterFilter(DriverObject,
&FilterRegistration,
&gFilter );
FltStartFiltering( gFilter );
return STATUS_SUCCESS;
}

NTSTATUS
ScannerUnload (
FLT_FILTER_UNLOAD_FLAGS Flags
)
{
FltUnregisterFilter( gFilter );
return STATUS_SUCCESS;
}

NTSTATUS
ScannerInstanceSetup (
IN PCFLT_RELATED_OBJECTS FltObjects,
IN FLT_INSTANCE_SETUP_FLAGS Flags,
IN DEVICE_TYPE VolumeDeviceType,
IN FLT_FILESYSTEM_TYPE VolumeFilesystemType
)
{
return STATUS_SUCCESS;
}

NTSTATUS
ScannerQueryTeardown (
IN PCFLT_RELATED_OBJECTS FltObjects,
IN FLT_INSTANCE_QUERY_TEARDOWN_FLAGS Flags
)
{
return STATUS_SUCCESS;
}

FLT_PREOP_CALLBACK_STATUS
ScannerPreCreate (
IN OUT PFLT_CALLBACK_DATA Data,
IN PCFLT_RELATED_OBJECTS FltObjects,
OUT PVOID *CompletionContext
)
{
PFLT_FILE_NAME_INFORMATION lpFileNameInfo;
NTSTATUS ntRes;

ntRes = FltGetFileNameInformation(Data,
FLT_FILE_NAME_NORMALIZED |

FLT_FILE_NAME_QUERY_ALWAYS_ALLOW_CACHE_LOOKUP,
&lpFileNameInfo);
if(!NT_SUCCESS(ntRes))
ntRes = FltGetFileNameInformation(Data,
FLT_FILE_NAME_OPENED |

FLT_FILE_NAME_QUERY_ALWAYS_ALLOW_CACHE_LOOKUP,
&lpFileNameInfo);
if(NT_SUCCESS(ntRes))
FltReleaseFileNameInformation(lpFileNameInfo);
return FLT_PREOP_SUCCESS_WITH_CALLBACK;
}

__int64 GetFileID(PFLT_CALLBACK_DATA Data,
PCFLT_RELATED_OBJECTS FltObjects)
{
FILE_INTERNAL_INFORMATION FileData;
NTSTATUS ntRes;

FileData.IndexNumber.QuadPart = 0;
ntRes = FltQueryInformationFile(FltObjects->Instance,
FltObjects->FileObject,
&FileData,
sizeof(FileData),
FileInternalInformation,
NULL);
if(!NT_SUCCESS(ntRes))
{
return 0;
}
return (FileData.IndexNumber.QuadPart & 0x0000FFFFFFFFFFFF);
}

void GetDirectoryFlag(PFLT_CALLBACK_DATA Data,
PCFLT_RELATED_OBJECTS FltObjects)
{
FILE_STANDARD_INFORMATION FileData;
NTSTATUS ntRes;

FileData.Directory = FALSE;
ntRes = FltQueryInformationFile(FltObjects->Instance,
FltObjects->FileObject,
&FileData,
sizeof(FileData),
FileStandardInformation,
NULL);
}

FLT_POSTOP_CALLBACK_STATUS
ScannerPostCreate (
IN OUT PFLT_CALLBACK_DATA Data,
IN PCFLT_RELATED_OBJECTS FltObjects,
IN PVOID CompletionContext,
IN FLT_POST_OPERATION_FLAGS Flags
)
{
FLT_POSTOP_CALLBACK_STATUS returnStatus =
FLT_POSTOP_FINISHED_PROCESSING;
PFLT_FILE_NAME_INFORMATION lpFileNameInfo;
NTSTATUS ntRes;

if (!NT_SUCCESS( Data->IoStatus.Status ) ||
(STATUS_REPARSE == Data->IoStatus.Status)) {
return FLT_POSTOP_FINISHED_PROCESSING;
}
ntRes = FltGetFileNameInformation(Data,
FLT_FILE_NAME_NORMALIZED |

FLT_FILE_NAME_QUERY_ALWAYS_ALLOW_CACHE_LOOKUP,
&lpFileNameInfo);
if(NT_SUCCESS(ntRes))
FltReleaseFileNameInformation(lpFileNameInfo);
GetFileID(Data, FltObjects);
GetDirectoryFlag(Data, FltObjects);
return returnStatus;
}


Kind regards, Dejan
http://www.alfasp.com
File system audit, security and encryption kits.</fltkernel.h></winerror.h>

I would suspect that one problem is that it is generally recommended that a
filter obtain filename and other information in the post create and store it
in a context where it can be easily accessed when needed. I did not review
the code, but is there any chance that you are making that request while at
an IRQL other than passive, or while the FSD or CacheManager is holding a
lock?


David J. Craig
Engineer, Sr. Staff Software Systems
Broadcom Corporation

“Dejan Maksimovic” wrote in message news:xxxxx@ntfsd…
> or am I finding too many FltMgr bugs lately?
> The attached sample is a ridiculously basic mini-filter which
> “achieves” BSODs not only often enough to wonder, but often enough to be
> useless :frowning:
> The sample (has nothing to do with Scanner sample, I only used it as
> a skeleton) queries file name during pre-create, file name during
> post-create (just for test) and file ID and directory flag during post
> create.
> I’ve posted some cases where this code crashes in the last few
> weeks, here’s another:
> Remote Desktop on Srv03, with Local Drives brought to the terminal.
> When accessing “local drives” the remote machine bug checks with 0x7E in
> RDP drivers.
>
> For this bugcheck, the GetDirectoryFlag is at fault. Even though the
> code is so simple, I’ve gone through it a dozen times, and it’s good.
> What is the problem with getting the FileStandardInformation during RD
> session?
>
> #include <winerror.h>
> #include <fltkernel.h>
> #include “scanner.h”
> PFLT_FILTER gFilter;
>
> const FLT_OPERATION_REGISTRATION Callbacks = {
> { IRP_MJ_CREATE, 0, ScannerPreCreate, ScannerPostCreate},
> { IRP_MJ_FAST_IO_CHECK_IF_POSSIBLE, 0, ScannerPreCreate,
> ScannerPostCreate},
> { IRP_MJ_NETWORK_QUERY_OPEN, 0, ScannerPreCreate,
> ScannerPostCreate},
> { IRP_MJ_OPERATION_END}
> };
>
> const FLT_CONTEXT_REGISTRATION ContextRegistration = {
> { FLT_CONTEXT_END }
> };
>
> const FLT_REGISTRATION FilterRegistration = {
>
> sizeof( FLT_REGISTRATION ), // Size
> FLT_REGISTRATION_VERSION, // Version
> 0, // Flags
> ContextRegistration, // Context Registration.
> Callbacks, // Operation callbacks
> ScannerUnload, // FilterUnload
> ScannerInstanceSetup, // InstanceSetup
> ScannerQueryTeardown, // InstanceQueryTeardown
> NULL, // InstanceTeardownStart
> NULL, // InstanceTeardownComplete
> NULL, // GenerateFileName
> NULL, // GenerateDestinationFileName
> NULL // NormalizeNameComponent
> };
>
> NTSTATUS
> DriverEntry (
> IN PDRIVER_OBJECT DriverObject,
> IN PUNICODE_STRING RegistryPath
> )
> {
> OBJECT_ATTRIBUTES oa;
> UNICODE_STRING uniString;
> PSECURITY_DESCRIPTOR sd;
> NTSTATUS status;
>
> FltRegisterFilter(DriverObject,
> &FilterRegistration,
> &gFilter );
> FltStartFiltering( gFilter );
> return STATUS_SUCCESS;
> }
>
> NTSTATUS
> ScannerUnload (
> FLT_FILTER_UNLOAD_FLAGS Flags
> )
> {
> FltUnregisterFilter( gFilter );
> return STATUS_SUCCESS;
> }
>
> NTSTATUS
> ScannerInstanceSetup (
> IN PCFLT_RELATED_OBJECTS FltObjects,
> IN FLT_INSTANCE_SETUP_FLAGS Flags,
> IN DEVICE_TYPE VolumeDeviceType,
> IN FLT_FILESYSTEM_TYPE VolumeFilesystemType
> )
> {
> return STATUS_SUCCESS;
> }
>
> NTSTATUS
> ScannerQueryTeardown (
> IN PCFLT_RELATED_OBJECTS FltObjects,
> IN FLT_INSTANCE_QUERY_TEARDOWN_FLAGS Flags
> )
> {
> return STATUS_SUCCESS;
> }
>
> FLT_PREOP_CALLBACK_STATUS
> ScannerPreCreate (
> IN OUT PFLT_CALLBACK_DATA Data,
> IN PCFLT_RELATED_OBJECTS FltObjects,
> OUT PVOID *CompletionContext
> )
> {
> PFLT_FILE_NAME_INFORMATION lpFileNameInfo;
> NTSTATUS ntRes;
>
> ntRes = FltGetFileNameInformation(Data,
> FLT_FILE_NAME_NORMALIZED |
>
> FLT_FILE_NAME_QUERY_ALWAYS_ALLOW_CACHE_LOOKUP,
> &lpFileNameInfo);
> if(!NT_SUCCESS(ntRes))
> ntRes = FltGetFileNameInformation(Data,
> FLT_FILE_NAME_OPENED |
>
> FLT_FILE_NAME_QUERY_ALWAYS_ALLOW_CACHE_LOOKUP,
> &lpFileNameInfo);
> if(NT_SUCCESS(ntRes))
> FltReleaseFileNameInformation(lpFileNameInfo);
> return FLT_PREOP_SUCCESS_WITH_CALLBACK;
> }
>
> __int64 GetFileID(PFLT_CALLBACK_DATA Data,
> PCFLT_RELATED_OBJECTS FltObjects)
> {
> FILE_INTERNAL_INFORMATION FileData;
> NTSTATUS ntRes;
>
> FileData.IndexNumber.QuadPart = 0;
> ntRes = FltQueryInformationFile(FltObjects->Instance,
> FltObjects->FileObject,
> &FileData,
> sizeof(FileData),
> FileInternalInformation,
> NULL);
> if(!NT_SUCCESS(ntRes))
> {
> return 0;
> }
> return (FileData.IndexNumber.QuadPart & 0x0000FFFFFFFFFFFF);
> }
>
> void GetDirectoryFlag(PFLT_CALLBACK_DATA Data,
> PCFLT_RELATED_OBJECTS FltObjects)
> {
> FILE_STANDARD_INFORMATION FileData;
> NTSTATUS ntRes;
>
> FileData.Directory = FALSE;
> ntRes = FltQueryInformationFile(FltObjects->Instance,
> FltObjects->FileObject,
> &FileData,
> sizeof(FileData),
> FileStandardInformation,
> NULL);
> }
>
> FLT_POSTOP_CALLBACK_STATUS
> ScannerPostCreate (
> IN OUT PFLT_CALLBACK_DATA Data,
> IN PCFLT_RELATED_OBJECTS FltObjects,
> IN PVOID CompletionContext,
> IN FLT_POST_OPERATION_FLAGS Flags
> )
> {
> FLT_POSTOP_CALLBACK_STATUS returnStatus =
> FLT_POSTOP_FINISHED_PROCESSING;
> PFLT_FILE_NAME_INFORMATION lpFileNameInfo;
> NTSTATUS ntRes;
>
> if (!NT_SUCCESS( Data->IoStatus.Status ) ||
> (STATUS_REPARSE == Data->IoStatus.Status)) {
> return FLT_POSTOP_FINISHED_PROCESSING;
> }
> ntRes = FltGetFileNameInformation(Data,
> FLT_FILE_NAME_NORMALIZED |
>
> FLT_FILE_NAME_QUERY_ALWAYS_ALLOW_CACHE_LOOKUP,
> &lpFileNameInfo);
> if(NT_SUCCESS(ntRes))
> FltReleaseFileNameInformation(lpFileNameInfo);
> GetFileID(Data, FltObjects);
> GetDirectoryFlag(Data, FltObjects);
> return returnStatus;
> }
>
>
> –
> Kind regards, Dejan
> http://www.alfasp.com
> File system audit, security and encryption kits.
></fltkernel.h></winerror.h>

The FltGetFileNameInformation calls are in both pre-create and post-create
for testing purposes. Sometimes I require the name during pre-create (this
requirement is dying slowly but still not dead). But as far as docs go, and my
knowledge of legacy filters, it must be possible to get the name during both pre
and post-create.
Both pre and post-create are at PASSIVE_LEVEL for sure. A lock held by a
third party might cause a deadlock, but not a crash.

“David J. Craig” wrote:

I would suspect that one problem is that it is generally recommended that a
filter obtain filename and other information in the post create and store it
in a context where it can be easily accessed when needed. I did not review
the code, but is there any chance that you are making that request while at
an IRQL other than passive, or while the FSD or CacheManager is holding a
lock?


Kind regards, Dejan
http://www.alfasp.com
File system audit, security and encryption kits.

May be it’s something with that file object that you’re querying. How about
a crash analysis, dumped file object and NodeTypeCode of the FCB?

“Dejan Maksimovic” wrote news:xxxxx@ntfsd…
> or am I finding too many FltMgr bugs lately?
> The attached sample is a ridiculously basic mini-filter which
> “achieves” BSODs not only often enough to wonder, but often enough to be
> useless :frowning:
> The sample (has nothing to do with Scanner sample, I only used it as
> a skeleton) queries file name during pre-create, file name during
> post-create (just for test) and file ID and directory flag during post
> create.
> I’ve posted some cases where this code crashes in the last few
> weeks, here’s another:
> Remote Desktop on Srv03, with Local Drives brought to the terminal.
> When accessing “local drives” the remote machine bug checks with 0x7E in
> RDP drivers.
>
> For this bugcheck, the GetDirectoryFlag is at fault. Even though the
> code is so simple, I’ve gone through it a dozen times, and it’s good.
> What is the problem with getting the FileStandardInformation during RD
> session?
>
> #include <winerror.h>
> #include <fltkernel.h>
> #include “scanner.h”
> PFLT_FILTER gFilter;
>
> const FLT_OPERATION_REGISTRATION Callbacks = {
> { IRP_MJ_CREATE, 0, ScannerPreCreate, ScannerPostCreate},
> { IRP_MJ_FAST_IO_CHECK_IF_POSSIBLE, 0, ScannerPreCreate,
> ScannerPostCreate},
> { IRP_MJ_NETWORK_QUERY_OPEN, 0, ScannerPreCreate,
> ScannerPostCreate},
> { IRP_MJ_OPERATION_END}
> };
>
> const FLT_CONTEXT_REGISTRATION ContextRegistration = {
> { FLT_CONTEXT_END }
> };
>
> const FLT_REGISTRATION FilterRegistration = {
>
> sizeof( FLT_REGISTRATION ), // Size
> FLT_REGISTRATION_VERSION, // Version
> 0, // Flags
> ContextRegistration, // Context Registration.
> Callbacks, // Operation callbacks
> ScannerUnload, // FilterUnload
> ScannerInstanceSetup, // InstanceSetup
> ScannerQueryTeardown, // InstanceQueryTeardown
> NULL, // InstanceTeardownStart
> NULL, // InstanceTeardownComplete
> NULL, // GenerateFileName
> NULL, // GenerateDestinationFileName
> NULL // NormalizeNameComponent
> };
>
> NTSTATUS
> DriverEntry (
> IN PDRIVER_OBJECT DriverObject,
> IN PUNICODE_STRING RegistryPath
> )
> {
> OBJECT_ATTRIBUTES oa;
> UNICODE_STRING uniString;
> PSECURITY_DESCRIPTOR sd;
> NTSTATUS status;
>
> FltRegisterFilter(DriverObject,
> &FilterRegistration,
> &gFilter );
> FltStartFiltering( gFilter );
> return STATUS_SUCCESS;
> }
>
> NTSTATUS
> ScannerUnload (
> FLT_FILTER_UNLOAD_FLAGS Flags
> )
> {
> FltUnregisterFilter( gFilter );
> return STATUS_SUCCESS;
> }
>
> NTSTATUS
> ScannerInstanceSetup (
> IN PCFLT_RELATED_OBJECTS FltObjects,
> IN FLT_INSTANCE_SETUP_FLAGS Flags,
> IN DEVICE_TYPE VolumeDeviceType,
> IN FLT_FILESYSTEM_TYPE VolumeFilesystemType
> )
> {
> return STATUS_SUCCESS;
> }
>
> NTSTATUS
> ScannerQueryTeardown (
> IN PCFLT_RELATED_OBJECTS FltObjects,
> IN FLT_INSTANCE_QUERY_TEARDOWN_FLAGS Flags
> )
> {
> return STATUS_SUCCESS;
> }
>
> FLT_PREOP_CALLBACK_STATUS
> ScannerPreCreate (
> IN OUT PFLT_CALLBACK_DATA Data,
> IN PCFLT_RELATED_OBJECTS FltObjects,
> OUT PVOID *CompletionContext
> )
> {
> PFLT_FILE_NAME_INFORMATION lpFileNameInfo;
> NTSTATUS ntRes;
>
> ntRes = FltGetFileNameInformation(Data,
> FLT_FILE_NAME_NORMALIZED |
>
> FLT_FILE_NAME_QUERY_ALWAYS_ALLOW_CACHE_LOOKUP,
> &lpFileNameInfo);
> if(!NT_SUCCESS(ntRes))
> ntRes = FltGetFileNameInformation(Data,
> FLT_FILE_NAME_OPENED |
>
> FLT_FILE_NAME_QUERY_ALWAYS_ALLOW_CACHE_LOOKUP,
> &lpFileNameInfo);
> if(NT_SUCCESS(ntRes))
> FltReleaseFileNameInformation(lpFileNameInfo);
> return FLT_PREOP_SUCCESS_WITH_CALLBACK;
> }
>
> __int64 GetFileID(PFLT_CALLBACK_DATA Data,
> PCFLT_RELATED_OBJECTS FltObjects)
> {
> FILE_INTERNAL_INFORMATION FileData;
> NTSTATUS ntRes;
>
> FileData.IndexNumber.QuadPart = 0;
> ntRes = FltQueryInformationFile(FltObjects->Instance,
> FltObjects->FileObject,
> &FileData,
> sizeof(FileData),
> FileInternalInformation,
> NULL);
> if(!NT_SUCCESS(ntRes))
> {
> return 0;
> }
> return (FileData.IndexNumber.QuadPart & 0x0000FFFFFFFFFFFF);
> }
>
> void GetDirectoryFlag(PFLT_CALLBACK_DATA Data,
> PCFLT_RELATED_OBJECTS FltObjects)
> {
> FILE_STANDARD_INFORMATION FileData;
> NTSTATUS ntRes;
>
> FileData.Directory = FALSE;
> ntRes = FltQueryInformationFile(FltObjects->Instance,
> FltObjects->FileObject,
> &FileData,
> sizeof(FileData),
> FileStandardInformation,
> NULL);
> }
>
> FLT_POSTOP_CALLBACK_STATUS
> ScannerPostCreate (
> IN OUT PFLT_CALLBACK_DATA Data,
> IN PCFLT_RELATED_OBJECTS FltObjects,
> IN PVOID CompletionContext,
> IN FLT_POST_OPERATION_FLAGS Flags
> )
> {
> FLT_POSTOP_CALLBACK_STATUS returnStatus =
> FLT_POSTOP_FINISHED_PROCESSING;
> PFLT_FILE_NAME_INFORMATION lpFileNameInfo;
> NTSTATUS ntRes;
>
> if (!NT_SUCCESS( Data->IoStatus.Status ) ||
> (STATUS_REPARSE == Data->IoStatus.Status)) {
> return FLT_POSTOP_FINISHED_PROCESSING;
> }
> ntRes = FltGetFileNameInformation(Data,
> FLT_FILE_NAME_NORMALIZED |
>
> FLT_FILE_NAME_QUERY_ALWAYS_ALLOW_CACHE_LOOKUP,
> &lpFileNameInfo);
> if(NT_SUCCESS(ntRes))
> FltReleaseFileNameInformation(lpFileNameInfo);
> GetFileID(Data, FltObjects);
> GetDirectoryFlag(Data, FltObjects);
> return returnStatus;
> }
>
>
> –
> Kind regards, Dejan
> http://www.alfasp.com
> File system audit, security and encryption kits.
></fltkernel.h></winerror.h>

(If anything in this e-mail is not clear, I apologize, I typed it in pieces
over a period of one hour, testing a few bits in the interim)

That’s the problem. The crash always indicates other drivers; even with
Driver Verifier, the bugcheck is the same (0x7E, some are stack overflows, this
particular one (where GetDirectoryFlag causes a problem) isn’t).
Here’s a rundown of what happens with what code:

  • Only GetDirectoryFlag call from post-create (no name query anywhere, no
    GetFileID), crash of Srv03 server, when Remote Desktop connects to it, with
    Local Drives brought to the server, once the “Local drives” are accessed.
  • Only GetFileID during post-create causes a stack overflow with earlier
    Kaspersky AV (June build I think, fixed in 7.0). This one was no problem,
    because it was KAV’s fault.
  • Name query during post-create hangs Altris virtualization package
  • FltGetFileNameInformation from either pre/post create causes a crash (in
    FltMgr) with Infineon TPM module drivers as soon as the drive is first
    accessed.
    Aside from the last issue, which points to FltMgr in the crash dump, the
    other issues never reveal anything (with DV on for all drivers, it still
    triggers 0x7E bugcheck, two are stack overflow, others are not).
    To clear some doubts, the code I have posted is minimized, the actual
    TestScanner sample checks for errors :wink:
    If RdpDr doesn’t support advanced FCBs I would understand why
    FltIsDirectory would fail, but in this case, the query file information
    crashes.

Here’s the stack dump, as I mentioned, no traces of FltMgr/Scanner:
ba36d1b0 bacc9c93 81af7008 81af7008 81af7008 0x0
ba36d1c8 bacc9d45 81af7008 bacd0410 81af8bb0 rdpdr!RxLowIoCompletionTail+0x33
<>
ba36d1dc bacc3f22 81af7008 ba36d20c bacc4291 rdpdr!RxLowIoCompletion+0x3f
ba36d1e8 bacc4291 81af7008 00000000 00000016
rdpdr!DrDevice::CompleteRxContext+0x2a
ba36d20c bacbaff7 ba36d250 00000000 00000016
rdpdr!DrDevice::CompleteBusyExchange+0x4d
ba36d23c bacc536d e11979b8 81b20e80 ba36d2b4
rdpdr!DrDrive::OnQueryFileInfoCompletion+0x2a5
ba36d260 bacc169d e11979b8 0000002a ba36d2b4
rdpdr!DrDevice::OnDeviceIoCompletion+0xa9
ba36d280 bacc185a e11979b8 0000002a ba36d2b4
rdpdr!DrExchangeManager::OnDeviceIoCompletion+0x55
ba36d294 bacc251f e11979b8 0000002a ba36d2b4
rdpdr!DrExchangeManager::HandlePacket+0x26
ba36d2c0 bacc1e34 00000000 82f84f68 ba36d360
rdpdr!DrSession::ReadCompletion+0xc5
ba36d2d8 809ad23e 00000000 82f84f68 81b2e8f0
rdpdr!DrSession::ReadCompletionRoutine+0x38
ba36d2fc 8081d741 00000000 82f84f68 ba36d360 nt!IovpLocalCompletionRoutine+0xb4

ba36d32c 809ad77e 82f84f68 81b2e170 00000000 nt!IopfCompleteRequest+0xcd
ba36d398 f76295d8 825e2008 00000000 e1028000 nt!IovCompleteRequest+0x9a
ba36d3d4 f762a0d2 825e2008 00000005 00000000
termdd!IcaChannelInputInternal+0x1f0
ba36d3fc ba2176e1 81d3284c 00000005 00000000 termdd!IcaChannelInput+0x3c
ba36d430 ba2113c1 e1028000 005e3a36 00000032 RDPWD!WDW_OnDataReceived+0x181
ba36d458 ba2111b9 e1028c00 e102b150 ba36d400 RDPWD!SM_MCSSendDataCallback+0x159

ba36d4c0 ba210fe0 00000045 ba36d4f8 0000004c RDPWD!HandleAllSendDataPDUs+0x155
ba36d4dc ba22eba4 00000045 ba36d4f8 e1028000 RDPWD!RecognizeMCSFrame+0x32
ba36d504 ba21006b e1028000 00000000 825e3a68 RDPWD!MCSIcaRawInputWorker+0x346
ba36d52c f762d194 e1028000 00000000 825e3a1c RDPWD!MCSIcaRawInput+0x65
ba36d550 ba741fcb 81bb4df4 00000000 825e3a1c termdd!IcaRawInput+0x58
ba36dd90 f762c265 825e38d0 00000000 825e2db0 TDTCP!TdInputThread+0x371
ba36ddac 809418f4 825e2898 00000000 00000000 termdd!_IcaDriverThread+0x4d
ba36dddc 80887f4a f762c218 81b3c0b0 00000000 nt!PspSystemThreadStartup+0x2e
00000000 00000000 00000000 00000000 00000000 nt!KiThreadStartup+0x16

frank wrote:

> May be it’s something with that file object that you’re querying. How about
> a crash analysis, dumped file object and NodeTypeCode of the FCB?


Kind regards, Dejan
http://www.alfasp.com
File system audit, security and encryption kits.

I’ve observed that fltmgr engages in some rather dangerous ‘stack
extension’ behavior in the pre-create FltGetFileNameInformation() API path
where fltmgr forwards a IRP request to a worker thread when it is about to
run out of stack space in the current thread, it then waits synchrously on
that worker thread. It will do this until it runs out of threads,
dead-locks or succeeds. This can result in:

  1. synchronous re-entrancy in surprising ways, sometimes while holding
    resources

  2. thread pool exhausion

Both of which, depending upon a point of view, expose flaws in other
filter drivers, or are flaws in fltmgr. I don’t expect fltmgr to ever
change to be more paranoid about doing un-usual things, so until every
last filter driver is either banned by Microsoft entirely or fixed to
work-around fltmgr it doesn’t seem prudent to use the
FltGetFileNameInformation in pre-create, and if you must, definately don’t
use the GetDirectoryFlag.

t.

On Sun, 2 Sep 2007, Dejan Maksimovic wrote:

(If anything in this e-mail is not clear, I apologize, I typed it in pieces
over a period of one hour, testing a few bits in the interim)

That’s the problem. The crash always indicates other drivers; even with
Driver Verifier, the bugcheck is the same (0x7E, some are stack overflows, this
particular one (where GetDirectoryFlag causes a problem) isn’t).
Here’s a rundown of what happens with what code:

  • Only GetDirectoryFlag call from post-create (no name query anywhere, no
    GetFileID), crash of Srv03 server, when Remote Desktop connects to it, with
    Local Drives brought to the server, once the “Local drives” are accessed.
  • Only GetFileID during post-create causes a stack overflow with earlier
    Kaspersky AV (June build I think, fixed in 7.0). This one was no problem,
    because it was KAV’s fault.
  • Name query during post-create hangs Altris virtualization package
  • FltGetFileNameInformation from either pre/post create causes a crash (in
    FltMgr) with Infineon TPM module drivers as soon as the drive is first
    accessed.
    Aside from the last issue, which points to FltMgr in the crash dump, the
    other issues never reveal anything (with DV on for all drivers, it still
    triggers 0x7E bugcheck, two are stack overflow, others are not).
    To clear some doubts, the code I have posted is minimized, the actual
    TestScanner sample checks for errors :wink:
    If RdpDr doesn’t support advanced FCBs I would understand why
    FltIsDirectory would fail, but in this case, the query file information
    crashes.

Here’s the stack dump, as I mentioned, no traces of FltMgr/Scanner:
ba36d1b0 bacc9c93 81af7008 81af7008 81af7008 0x0
ba36d1c8 bacc9d45 81af7008 bacd0410 81af8bb0 rdpdr!RxLowIoCompletionTail+0x33
<>
> ba36d1dc bacc3f22 81af7008 ba36d20c bacc4291 rdpdr!RxLowIoCompletion+0x3f
> ba36d1e8 bacc4291 81af7008 00000000 00000016
> rdpdr!DrDevice::CompleteRxContext+0x2a
> ba36d20c bacbaff7 ba36d250 00000000 00000016
> rdpdr!DrDevice::CompleteBusyExchange+0x4d
> ba36d23c bacc536d e11979b8 81b20e80 ba36d2b4
> rdpdr!DrDrive::OnQueryFileInfoCompletion+0x2a5
> ba36d260 bacc169d e11979b8 0000002a ba36d2b4
> rdpdr!DrDevice::OnDeviceIoCompletion+0xa9
> ba36d280 bacc185a e11979b8 0000002a ba36d2b4
> rdpdr!DrExchangeManager::OnDeviceIoCompletion+0x55
> ba36d294 bacc251f e11979b8 0000002a ba36d2b4
> rdpdr!DrExchangeManager::HandlePacket+0x26
> ba36d2c0 bacc1e34 00000000 82f84f68 ba36d360
> rdpdr!DrSession::ReadCompletion+0xc5
> ba36d2d8 809ad23e 00000000 82f84f68 81b2e8f0
> rdpdr!DrSession::ReadCompletionRoutine+0x38
> ba36d2fc 8081d741 00000000 82f84f68 ba36d360 nt!IovpLocalCompletionRoutine+0xb4
>
> ba36d32c 809ad77e 82f84f68 81b2e170 00000000 nt!IopfCompleteRequest+0xcd
> ba36d398 f76295d8 825e2008 00000000 e1028000 nt!IovCompleteRequest+0x9a
> ba36d3d4 f762a0d2 825e2008 00000005 00000000
> termdd!IcaChannelInputInternal+0x1f0
> ba36d3fc ba2176e1 81d3284c 00000005 00000000 termdd!IcaChannelInput+0x3c
> ba36d430 ba2113c1 e1028000 005e3a36 00000032 RDPWD!WDW_OnDataReceived+0x181
> ba36d458 ba2111b9 e1028c00 e102b150 ba36d400 RDPWD!SM_MCSSendDataCallback+0x159
>
> ba36d4c0 ba210fe0 00000045 ba36d4f8 0000004c RDPWD!HandleAllSendDataPDUs+0x155
> ba36d4dc ba22eba4 00000045 ba36d4f8 e1028000 RDPWD!RecognizeMCSFrame+0x32
> ba36d504 ba21006b e1028000 00000000 825e3a68 RDPWD!MCSIcaRawInputWorker+0x346
> ba36d52c f762d194 e1028000 00000000 825e3a1c RDPWD!MCSIcaRawInput+0x65
> ba36d550 ba741fcb 81bb4df4 00000000 825e3a1c termdd!IcaRawInput+0x58
> ba36dd90 f762c265 825e38d0 00000000 825e2db0 TDTCP!TdInputThread+0x371
> ba36ddac 809418f4 825e2898 00000000 00000000 termdd!_IcaDriverThread+0x4d
> ba36dddc 80887f4a f762c218 81b3c0b0 00000000 nt!PspSystemThreadStartup+0x2e
> 00000000 00000000 00000000 00000000 00000000 nt!KiThreadStartup+0x16
>
> frank wrote:
>
>> May be it’s something with that file object that you’re querying. How about
>> a crash analysis, dumped file object and NodeTypeCode of the FCB?
>
> –
> Kind regards, Dejan
> http://www.alfasp.com
> File system audit, security and encryption kits.
>
>
>
> —
> NTFSD is sponsored by OSR
>
> For our schedule debugging and file system seminars
> (including our new fs mini-filter seminar) visit:
> http://www.osr.com/seminars
>
> You are currently subscribed to ntfsd as: xxxxx@openmars.com
> To unsubscribe send a blank email to xxxxx@lists.osr.com
>

I agree, I’ve seen similar tricky work (e.g. FltLockUserBuffer).
But, such basic API calls need to work, otherwise FltMgr is useless.

Tracy Camp wrote:

I’ve observed that fltmgr engages in some rather dangerous ‘stack
extension’ behavior in the pre-create FltGetFileNameInformation() API path
where fltmgr forwards a IRP request to a worker thread when it is about to
run out of stack space in the current thread, it then waits synchrously on
that worker thread. It will do this until it runs out of threads,
dead-locks or succeeds. This can result in:

  1. synchronous re-entrancy in surprising ways, sometimes while holding
    resources

  2. thread pool exhausion

Both of which, depending upon a point of view, expose flaws in other
filter drivers, or are flaws in fltmgr. I don’t expect fltmgr to ever
change to be more paranoid about doing un-usual things, so until every
last filter driver is either banned by Microsoft entirely or fixed to
work-around fltmgr it doesn’t seem prudent to use the
FltGetFileNameInformation in pre-create, and if you must, definately don’t
use the GetDirectoryFlag.


Kind regards, Dejan
http://www.alfasp.com
File system audit, security and encryption kits.

This is a known bug in RDPDR. Unfortunately fix is not available in 2k3
and xp. The workaround Neal talked about in
http://www.osronline.com/showThread.cfm?link=71952 may be helpful for
you.

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Dejan Maksimovic
Sent: Sunday, September 02, 2007 10:30 AM
To: Windows File Systems Devs Interest List
Subject: Re: [ntfsd] Am I going crazy…

I agree, I’ve seen similar tricky work (e.g. FltLockUserBuffer).
But, such basic API calls need to work, otherwise FltMgr is useless.

Tracy Camp wrote:

I’ve observed that fltmgr engages in some rather dangerous ‘stack
extension’ behavior in the pre-create FltGetFileNameInformation() API
path
where fltmgr forwards a IRP request to a worker thread when it is
about to
run out of stack space in the current thread, it then waits
synchrously on
that worker thread. It will do this until it runs out of threads,
dead-locks or succeeds. This can result in:

  1. synchronous re-entrancy in surprising ways, sometimes while holding
    resources

  2. thread pool exhausion

Both of which, depending upon a point of view, expose flaws in other
filter drivers, or are flaws in fltmgr. I don’t expect fltmgr to ever
change to be more paranoid about doing un-usual things, so until every
last filter driver is either banned by Microsoft entirely or fixed to
work-around fltmgr it doesn’t seem prudent to use the
FltGetFileNameInformation in pre-create, and if you must, definately
don’t
use the GetDirectoryFlag.


Kind regards, Dejan
http://www.alfasp.com
File system audit, security and encryption kits.


NTFSD is sponsored by OSR

For our schedule debugging and file system seminars
(including our new fs mini-filter seminar) visit:
http://www.osr.com/seminars

You are currently subscribed to ntfsd as: xxxxx@microsoft.com
To unsubscribe send a blank email to xxxxx@lists.osr.com

Thanks, this should help! (I’ve tried searching archives, but it seems I
am pretty bad with searches)

Janet Zhang wrote:

This is a known bug in RDPDR. Unfortunately fix is not available in 2k3
and xp. The workaround Neal talked about in
http://www.osronline.com/showThread.cfm?link=71952 may be helpful for
you.


Kind regards, Dejan
http://www.alfasp.com
File system audit, security and encryption kits.

Just to clarify and reinforce, the FltGetFileNameInformation() API is the recommended way to query a name for a file/stream in the pre-create callback. Fltmgr does only what is absolutely necessary to guarantee the correctness of the name returned to the caller.

If there are any specific cases, where fltmgr is not playing well in the space, we will be happy to address them.

Sarosh Havewala
Lead File System Filters
Microsoft Corp.

This posting is provided “AS IS” with no warranties, and confers no rights.

Sarosh,
I have a problem when calling FltGetDestinationFileNameInformation when
renaming stream of a file on a network drive.

If I rename the file itself (e.g. “filex” to “filez”) the name fetch
works fine (FLT_FILE_NAME_NORMALIZED) is set.
If I rename a stream on that file (filex:stream1 to filex:stream2) I get
the error:
STATUS_OBJECT_NAME_INVALID
when the flags are:
FLT_FILE_NAME_NORMALIZED |
FLT_FILE_NAME_QUERY_ALWAYS_ALLOW_CACHE_LOOKUP
if I change FLT_FILE_NAME_NORMALIZED to FLT_FILE_NAME_OPENED I don’t get
the error.

This was on Windows 2003.

Thanks,
Ken

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of
xxxxx@microsoft.com
Sent: Monday, September 10, 2007 8:42 PM
To: Windows File Systems Devs Interest List
Subject: RE:[ntfsd] Am I going crazy…

Just to clarify and reinforce, the FltGetFileNameInformation() API is
the recommended way to query a name for a file/stream in the pre-create
callback. Fltmgr does only what is absolutely necessary to guarantee the
correctness of the name returned to the caller.

If there are any specific cases, where fltmgr is not playing well in the
space, we will be happy to address them.

Sarosh Havewala
Lead File System Filters
Microsoft Corp.

This posting is provided “AS IS” with no warranties, and confers no
rights.


NTFSD is sponsored by OSR

For our schedule debugging and file system seminars
(including our new fs mini-filter seminar) visit:
http://www.osr.com/seminars

You are currently subscribed to ntfsd as: xxxxx@legato.com
To unsubscribe send a blank email to xxxxx@lists.osr.com

I doubt any of the issues are FltMgr’s fault, but they are quite a few and we get hampered by some customers as if it’s our fault. We have two big issues at the moment:

  • stack overflow with KIS (suspecting KIS, can’t repro with KIS after build 614)
  • Infineon TPM module driver causes problems if the API is called for the first open on the drive.
    I’ll be happy to provide complete repro steps off the list.
    KIS issue is of little importance because we can only repro with a specific build (KIS = Kaspersky Internet Security) and only on customer’s VMs.
    The TPM module issue (reproducible by running the sample I posted, and plugging in a TPM module simply) is a big issue.

On the API topic (not related to bugs), developers should be aware that FltGetFileNameInformation CANNOT be called in post-create for a FAILED open/create/replace (obvious reason - lpFileObject->FileName is not valid and the FO is not opened). For most filters
this is not an issue, but any monitoring software will obviously not work without it.

Regards, Dejan.

xxxxx@microsoft.com wrote:

Just to clarify and reinforce, the FltGetFileNameInformation() API is the recommended way to query a name for a file/stream in the pre-create callback. Fltmgr does only what is absolutely necessary to guarantee the correctness of the name returned to the caller.

If there are any specific cases, where fltmgr is not playing well in the space, we will be happy to address them.


Kind regards, Dejan
http://www.alfasp.com
File system audit, security and encryption kits.

Is the OS updated? Might be related to this:
http://support.microsoft.com/kb/917315
(though it sounds it’s an extension to the problem)

xxxxx@emc.com wrote:

Sarosh,
I have a problem when calling FltGetDestinationFileNameInformation when
renaming stream of a file on a network drive.

If I rename the file itself (e.g. “filex” to “filez”) the name fetch
works fine (FLT_FILE_NAME_NORMALIZED) is set.
If I rename a stream on that file (filex:stream1 to filex:stream2) I get
the error:
STATUS_OBJECT_NAME_INVALID
when the flags are:
FLT_FILE_NAME_NORMALIZED |
FLT_FILE_NAME_QUERY_ALWAYS_ALLOW_CACHE_LOOKUP
if I change FLT_FILE_NAME_NORMALIZED to FLT_FILE_NAME_OPENED I don’t get
the error.

This was on Windows 2003.


Kind regards, Dejan
http://www.alfasp.com
File system audit, security and encryption kits.

Sarosh, is there please anything you can do for me to have my minifilter
altitudes assigned ? I do not want to be called a pirate and ship with the
altitude possibly assigned to someone else. It’s more than 3 months that I
am waiting and have sent lots of messages to altreq@ms

Thanks,

Daniel Terhell
Resplendence Software Projects Sp
xxxxx@resplendence.com
http://www.resplendence.com

wrote in message news:xxxxx@ntfsd…
> Just to clarify and reinforce, the FltGetFileNameInformation() API is the
> recommended way to query a name for a file/stream in the pre-create
> callback. Fltmgr does only what is absolutely necessary to guarantee the
> correctness of the name returned to the caller.
>
> If there are any specific cases, where fltmgr is not playing well in the
> space, we will be happy to address them.
>
> Sarosh Havewala
> Lead File System Filters
> Microsoft Corp.
>
> This posting is provided “AS IS” with no warranties, and confers no
> rights.
>
>
>

Daniel Terhell wrote:

Sarosh, is there please anything you can do for me to have my minifilter
altitudes assigned ? I do not want to be called a pirate and ship with
the altitude possibly assigned to someone else. It’s more than 3 months
that I am waiting and have sent lots of messages to altreq@ms

Seconded - I wish that MS would fix their signup page (it’s not worked
for a year or more)… I think altreq goes to /dev/null.

I’ve considered writing an app that reassigns altitudes in at boot (walk
the registry, look for conflicts and change them) - not sure how
successful that would be but it might be a way out of the problem. No
time to write the damned thing though… Our minifilters are currently
on hold due to reprioritisation but some customers already have beta
versions with random altitudes because of this issue.

Tony

AFAIK altitudes could have decimal places (up to some high number) so why
dont just set altitude to
“{altitude}.{guid}” . There should be no conflicts.

Jan

“Tony Hoyle” wrote in message news:xxxxx@ntfsd…
> Daniel Terhell wrote:
> > Sarosh, is there please anything you can do for me to have my minifilter
> > altitudes assigned ? I do not want to be called a pirate and ship with
> > the altitude possibly assigned to someone else. It’s more than 3 months
> > that I am waiting and have sent lots of messages to altreq@ms
> >
> Seconded - I wish that MS would fix their signup page (it’s not worked
> for a year or more)… I think altreq goes to /dev/null.
>
> I’ve considered writing an app that reassigns altitudes in at boot (walk
> the registry, look for conflicts and change them) - not sure how
> successful that would be but it might be a way out of the problem. No
> time to write the damned thing though… Our minifilters are currently
> on hold due to reprioritisation but some customers already have beta
> versions with random altitudes because of this issue.
>
> Tony
>

Thanks but the idea behind the altitude is to have the right position in the
stack.

/Daniel

“Jan Milan” wrote in message news:xxxxx@ntfsd…
> AFAIK altitudes could have decimal places (up to some high number) so why
> dont just set altitude to
> “{altitude}.{guid}” . There should be no conflicts.
>
> Jan
>
> “Tony Hoyle” wrote in message news:xxxxx@ntfsd…
>> Daniel Terhell wrote:
>> > Sarosh, is there please anything you can do for me to have my
>> > minifilter
>> > altitudes assigned ? I do not want to be called a pirate and ship with
>> > the altitude possibly assigned to someone else. It’s more than 3 months
>> > that I am waiting and have sent lots of messages to altreq@ms
>> >
>> Seconded - I wish that MS would fix their signup page (it’s not worked
>> for a year or more)… I think altreq goes to /dev/null.
>>
>> I’ve considered writing an app that reassigns altitudes in at boot (walk
>> the registry, look for conflicts and change them) - not sure how
>> successful that would be but it might be a way out of the problem. No
>> time to write the damned thing though… Our minifilters are currently
>> on hold due to reprioritisation but some customers already have beta
>> versions with random altitudes because of this issue.
>>
>> Tony
>>
>
>
>

“Tony Hoyle” wrote in message news:xxxxx@ntfsd…
considered writing an app that reassigns altitudes in at boot (walk
> the registry, look for conflicts and change them) - not sure how
> successful that would be but it might be a way out of the problem. No
> time to write the damned thing though… Our minifilters are currently on
> hold due to reprioritisation but some customers already have beta versions
> with random altitudes because of this issue.
>

Thanks, dynamic altitudes sound like the only option. I think the major flaw
in this design is that the second driver with the same altitude just refuses
to load instead of making some simple aribitrary decision of putting it
below or above. I do not want to be considered a pirate though. I mean even
after everything I had to give up just for playing by the rules, is there
then nothing I can do right ?

/Daniel