Crash dump while acquiring PagingIoResource

Hi All,

In my mini-filter driver, in preclose() operation, i am calling flushcahe code which leads t o system crash.

In the memory dump, it shows that while acquiring PagingIoResource it crashes while doing hal!KeAcquireInStackQueuedSpinLock.

Flushcache code:

int FlushCache(PFILE_OBJECT pFileObject)
{
PFSRTL_COMMON_FCB_HEADER pFcbHeader = NULL;
LARGE_INTEGER lnWaitTime;

if(FALSE == CcIsFileCached(pFileObject))
{
return 0;
}

pFcbHeader = (PFSRTL_COMMON_FCB_HEADER)(pFileObject->FsContext);

if(NULL != pFileObject->SectionObjectPointer)
{
KeEnterCriticalRegion();

Retry:

if ( (ExAcquireResourceExclusiveLite(pFcbHeader->Resource, TRUE)) )
{
//// ERROR HERE IN MINI DUMP
if((ExAcquireResourceExclusiveLite(pFcbHeader->PagingIoResource,FALSE)))
{
CcFlushCache(pFileObject->SectionObjectPointer, 0, 0, NULL);

if(NULL != pFileObject->SectionObjectPointer->ImageSectionObject)
{
MmFlushImageSection(pFileObject->SectionObjectPointer,
MmFlushForWrite);
}

if (NULL != pFileObject->SectionObjectPointer->DataSectionObject)
{
CcPurgeCacheSection(pFileObject->SectionObjectPointer,
NULL,0,FALSE);
}

ExReleaseResourceLite(pFcbHeader->PagingIoResource);

ExReleaseResourceLite(pFcbHeader->Resource);
}
else
{
ExReleaseResourceLite(pFcbHeader->Resource);

lnWaitTime.QuadPart = -500000;

KeDelayExecutionThread(KernelMode,FALSE,&lnWaitTime);

goto Retry;
}
}
else
{
lnWaitTime.QuadPart = -500000;
KeDelayExecutionThread(KernelMode,FALSE,&lnWaitTime);
goto Retry;
}

KeLeaveCriticalRegion();
}
return 0;
}

Memory Dump:

1: kd> !analyze -v
*******************************************************************************
* *
* Bugcheck Analysis *
* *
*******************************************************************************

Unknown bugcheck code (1000000a)
Unknown bugcheck description
Arguments:
Arg1: 00000034
Arg2: 00000002
Arg3: 00000001
Arg4: 806e4a16

Debugging Details:

DEFAULT_BUCKET_ID: DRIVER_FAULT

BUGCHECK_STR: 0xA

LAST_CONTROL_TRANSFER: from f698cbb6 to 806e4a16

STACK_TEXT:
f8892bac f698cbb6 00000000 00000000 00000001 hal!KeAcquireInStackQueuedSpinLock+0x26
f8892bcc f69916c1 813c3400 00060006 82ae2ff6 TestFilter!FlushCache+0x86 [flushcache.c]
f8892bf0 bae5cdeb ff9b966c f8892c3c f8892c6c TestFilter!PreCloseOperation+0x91 [operations.c]
f8892c1c bae44888 00000001 00000002 f8892c6c fltmgr!FltvPreOperation+0x3f
f8892c7c bae462a0 00892cc4 827b6fdc f8892cc4 fltmgr!FltpPerformPreCallbacks+0x2d4
f8892c90 bae46c48 f8892cc4 00000000 819f1ca0 fltmgr!FltpPassThroughInternal+0x32
f8892cac bae47059 f8892cc4 813c3400 822f5f38 fltmgr!FltpPassThrough+0x1c2
f8892cdc 804eeeb1 819f1ca0 827b6de0 806e4428 fltmgr!FltpDispatch+0x10d
f8892cec 80656128 827b6df0 827b6de0 813c3400 nt!IopfCallDriver+0x31
f8892d10 805827b4 813c33e8 813c33d8 00000000 nt!IovCallDriver+0xa0
f8892d48 805b9e25 003c3400 00000000 813c3400 nt!IopDeleteFile+0x132
f8892d64 805ba278 813c3400 00000001 80561e80 nt!ObpRemoveObjectRoutine+0xdf
f8892d74 80563720 822ef830 80537757 00000000 nt!ObpProcessRemoveObjectQueue+0x36
f8892dac 805ce794 00000000 00000000 00000000 nt!ExWorkerQueue
f8892ddc 805450ce 80537668 00000000 00000000 nt!PspSystemThreadStartup+0x34
00000000 00000000 00000000 00000000 00000000 nt!KiThreadStartup+0x16

FOLLOWUP_IP:
TestFilter!FlushCache+86 [flushcache.c]
f698cbb6 0fb6d0 movzx edx,al

FOLLOWUP_NAME: MachineOwner

SYMBOL_NAME: TestFilter!FlushCache+86

MODULE_NAME: TestFilter

IMAGE_NAME: TestFilter.sys

DEBUG_FLR_IMAGE_TIMESTAMP: 4551e602

STACK_COMMAND: kb

BUCKET_ID: 0xA_TestFilter!FlushCache+86

Followup: MachineOwner

Thanks for your help,
Mahesh

You assume that all file systems have a paging I/O resource. That isn’t
a requirement. Unfortunately, that’s a risk of reaching into someone
else’s data structures under the believe that you know how they have set
them up.

In the file systems class I actually describe this particular issue
(it’s subtle because we’re talking about bits in the common header, but
I also mention the key routine here.)

Of course, there’s little anyone can do to make trying to flush another
driver’s cache “safe” but at least you could use
FsRtlAcquireFileExclusive instead of trying to do the locking
explicitly. Fair warning: I have not actually written the code to do
this, but I do know that what you are trying to do looks much like the
way that FsRtlAcquireFileExclusive functions. If you cannot use it
directly, it behooves you to study its implementation so you have a
greater probability of success.

Tony

Tony Mason
Consulting Partner
OSR Open Systems Resources, Inc.
http://www.osr.com

I also would note that your code is not a flush, this is a purge. “Purge”
stands for removing association of page frames with the data segment without
saving their content to the disk, “Flush” stands for writing the content of
the dirty page frames to the disk. So if you want to free page frames,
delete data segment and lose data your code is good.


Slava Imameyev, xxxxx@hotmail.com

wrote in message news:xxxxx@ntfsd…
> Hi All,
>
> In my mini-filter driver, in preclose() operation, i am calling flushcahe
> code which leads t o system crash.
>
> In the memory dump, it shows that while acquiring PagingIoResource it
> crashes while doing hal!KeAcquireInStackQueuedSpinLock.
>
> Flushcache code:
>
> int FlushCache(PFILE_OBJECT pFileObject)
> {
> PFSRTL_COMMON_FCB_HEADER pFcbHeader = NULL;
> LARGE_INTEGER lnWaitTime;
>
> if(FALSE == CcIsFileCached(pFileObject))
> {
> return 0;
> }
>
> pFcbHeader = (PFSRTL_COMMON_FCB_HEADER)(pFileObject->FsContext);
>
> if(NULL != pFileObject->SectionObjectPointer)
> {
> KeEnterCriticalRegion();
>
> Retry:
>
> if ( (ExAcquireResourceExclusiveLite(pFcbHeader->Resource, TRUE)) )
> {
> //// ERROR HERE IN MINI DUMP
>
> if((ExAcquireResourceExclusiveLite(pFcbHeader->PagingIoResource,FALSE)))
> {
> CcFlushCache(pFileObject->SectionObjectPointer, 0, 0, NULL);
>
> if(NULL != pFileObject->SectionObjectPointer->ImageSectionObject)
> {
>
> MmFlushImageSection(pFileObject->SectionObjectPointer,
>
> MmFlushForWrite);
> }
>
> if (NULL != pFileObject->SectionObjectPointer->DataSectionObject)
> {
>
> CcPurgeCacheSection(pFileObject->SectionObjectPointer,
>
> NULL,0,FALSE);
> }
>
> ExReleaseResourceLite(pFcbHeader->PagingIoResource);
>
> ExReleaseResourceLite(pFcbHeader->Resource);
> }
> else
> {
> ExReleaseResourceLite(pFcbHeader->Resource);
>
> lnWaitTime.QuadPart = -500000;
>
> KeDelayExecutionThread(KernelMode,FALSE,&lnWaitTime);
>
> goto Retry;
> }
> }
> else
> {
> lnWaitTime.QuadPart = -500000;
> KeDelayExecutionThread(KernelMode,FALSE,&lnWaitTime);
> goto Retry;
> }
>
> KeLeaveCriticalRegion();
> }
> return 0;
> }
>
>
> Memory Dump:
>
> 1: kd> !analyze -v
> ***
> *
>
> * Bugcheck Analysis
>
> *
>
>

>
> Unknown bugcheck code (1000000a)
> Unknown bugcheck description
> Arguments:
> Arg1: 00000034
> Arg2: 00000002
> Arg3: 00000001
> Arg4: 806e4a16
>
> Debugging Details:
> ------------------
>
>
> DEFAULT_BUCKET_ID: DRIVER_FAULT
>
> BUGCHECK_STR: 0xA
>
> LAST_CONTROL_TRANSFER: from f698cbb6 to 806e4a16
>
> STACK_TEXT:
> f8892bac f698cbb6 00000000 00000000 00000001
> hal!KeAcquireInStackQueuedSpinLock+0x26
> f8892bcc f69916c1 813c3400 00060006 82ae2ff6 TestFilter!FlushCache+0x86
> [flushcache.c]
> f8892bf0 bae5cdeb ff9b966c f8892c3c f8892c6c
> TestFilter!PreCloseOperation+0x91 [operations.c]
> f8892c1c bae44888 00000001 00000002 f8892c6c fltmgr!FltvPreOperation+0x3f
> f8892c7c bae462a0 00892cc4 827b6fdc f8892cc4
> fltmgr!FltpPerformPreCallbacks+0x2d4
> f8892c90 bae46c48 f8892cc4 00000000 819f1ca0
> fltmgr!FltpPassThroughInternal+0x32
> f8892cac bae47059 f8892cc4 813c3400 822f5f38 fltmgr!FltpPassThrough+0x1c2
> f8892cdc 804eeeb1 819f1ca0 827b6de0 806e4428 fltmgr!FltpDispatch+0x10d
> f8892cec 80656128 827b6df0 827b6de0 813c3400 nt!IopfCallDriver+0x31
> f8892d10 805827b4 813c33e8 813c33d8 00000000 nt!IovCallDriver+0xa0
> f8892d48 805b9e25 003c3400 00000000 813c3400 nt!IopDeleteFile+0x132
> f8892d64 805ba278 813c3400 00000001 80561e80
> nt!ObpRemoveObjectRoutine+0xdf
> f8892d74 80563720 822ef830 80537757 00000000
> nt!ObpProcessRemoveObjectQueue+0x36
> f8892dac 805ce794 00000000 00000000 00000000 nt!ExWorkerQueue
> f8892ddc 805450ce 80537668 00000000 00000000
> nt!PspSystemThreadStartup+0x34
> 00000000 00000000 00000000 00000000 00000000 nt!KiThreadStartup+0x16
>
>
> FOLLOWUP_IP:
> TestFilter!FlushCache+86 [flushcache.c]
> f698cbb6 0fb6d0 movzx edx,al
>
> FOLLOWUP_NAME: MachineOwner
>
> SYMBOL_NAME: TestFilter!FlushCache+86
>
> MODULE_NAME: TestFilter
>
> IMAGE_NAME: TestFilter.sys
>
> DEBUG_FLR_IMAGE_TIMESTAMP: 4551e602
>
> STACK_COMMAND: kb
>
> BUCKET_ID: 0xA_TestFilter!FlushCache+86
>
> Followup: MachineOwner
> ---------
>
> Thanks for your help,
> Mahesh
>
>
>
>
>
>

Hi,

Thanks for replying.

Tony, I am searching for your suggested approach and the IFS Kit says FsRtlAcquireFileExclusive is for system use.

Slava, I am first Flushing the cache (using CCFlushCache) and then purging it or am i misconcept about what you are trying to say.

Thanks
Mahesh

>I am first Flushing the cache (using CCFlushCache) and then purging it

Yes, I saw. You purge pages for every close request( am I right?), so the
following scenario is possible( even on UP system ).

Suppose that there are two threads-
Thread A receives close request for data stream
Thread B maps the same data stream

  1. Thread B opens the file( data stream ) and maps it
    < schedule thread A>
  2. your filter receive close request and calls CcFlushCache
    < schedule thread B>
  3. Thread B changes the memory mapping the file( suppose that pages are
    resident so there is no page fault that puts the thread into a wait state
    because you acquire the file exclusively ) unmaps the file, close the
    section( as a result there are no so called “user’s maps” and pages can be
    purged )
    < schedule thread A>
  4. your filter purges dirty page frames!

You lose data! Customers will find that if your filter is installed some
weird things happen - sometimes they lose their data and don’t receive any
errors.


Slava Imameyev, xxxxx@hotmail.com

wrote in message news:xxxxx@ntfsd…
> Hi,
>
> Thanks for replying.
>
> Tony, I am searching for your suggested approach and the IFS Kit says
> FsRtlAcquireFileExclusive is for system use.
>
> Slava, I am first Flushing the cache (using CCFlushCache) and then purging
> it or am i misconcept about what you are trying to say.
>
> Thanks
> Mahesh
>
>

The problem is that it IS for system use. What you are trying to do is
something an FSD would do internally or - if provoked by the system -
would be interlocked using this system use function.

Purging an FSD’s cache is something outside the bounds of normal
behavior, which is why you are experiencing problems.

Tony

Tony Mason
Consulting Partner
OSR Open Systems Resources, Inc.
http://www.osr.com

Hi Slava,

Thanks for replying.

How should i get around this scenario, in case of multiple threads you mentioned.

Based on this I have one more question, in order to insert a header\trailer in my file, I keep some flags in the stream context associated with the file. for e.g. if cached WRITE is called I set a flag which indicates that the size of the file has increased. So if I get another cached set information I should not increase the file size again. I also reset these flags every time a file is being obtained in write mode. Due to multiple threads will this create a problem?

Mahesh