Curious IRP_MJ_FLUSH_BUFFERS from SRV

Hello Everyone,

I am seeing a rather curious IRP in a filter, coming from SRV, and I am
hoping someone can shed some light.

This is an IRP_MJ_FLUSH_BUFFERS from SRV. The IRP Flags, MdlAddress and
AssociatedIrp.SystemBuffer are unexpected.

Here is the stack, to set the stage a little:

kd> kv nf

Memory ChildEBP RetAddr Args to Child

00 b948ac5c b8fd9673 8e0d3360 8d74f868 b948accc nt!DbgBreakPoint
(FPO: [0,0,0])
01 10 b948ac6c f78744ca 8d74f8c4 b948ac8c b948aca8
mine!PreFlushBuffersCallback+0x55 (FPO: [Non-Fpo]) (CONV: stdcall)
02 60 b948accc f7875f2a 0048ad14 00000000 b948ad14
fltMgr!FltpPerformPreCallbacks+0x2d4 (FPO: [1,16,0])
03 14 b948ace0 f78768d2 b948ad14 00000000 8d72aee8
fltMgr!FltpPassThroughInternal+0x32 (FPO: [2,0,0])
04 1c b948acfc f7876ce3 b948ad01 00000000 8e31e808
fltMgr!FltpPassThrough+0x1c2 (FPO: [1,0,4])
05 30 b948ad2c 8081d5c3 8d72aee8 8d56ff70 8d56f5d0
fltMgr!FltpDispatch+0x10d (FPO: [2,6,0])
06 14 b948ad40 b95d99f9 8d4d96b0 8d56f5d0 00000000
nt!IofCallDriver+0x45 (FPO: [0,0,4])
07 14 b948ad54 b95c7f6d 8d56f5d0 8d2e3cc8 b95a481c
srv!StartFlush+0x9a (FPO: [2,0,4])
08 24 b948ad78 b9591e87 8d56f5d8 8d66aaa0 b95a96c7
srv!SrvSmbFlush+0xfd (FPO: [0,2,4])
09 c b948ad84 b95a96c7 00000000 8d66fdb0 00000000
srv!SrvProcessSmb+0xb7 (FPO: [0,0,0])
0a 28 b948adac 809419d6 0066aaa0 00000000 00000000
srv!WorkerThread+0x138 (FPO: [1,5,0])
0b 30 b948addc 80887faa b95a9602 8d66aaa0 00000000
nt!PspSystemThreadStartup+0x2e (FPO: [SEH])

The IRP is the second parameter of fltMgr!FltpDispatch:

kd> !irp 8d56ff70
Irp is active with 15 stacks 15 is current (= 0x8d5701d8)
Mdl=8d570218: System buffer=e1cacae4: Thread 8d813ce8: Irp stack trace.
Pending has been returned
cmd flg cl Device File Completion-Context
[SNIP]
[f, 0] 0 0 8dfeac10 00000000 b9e48f60-8d6c27c8
\Driver\Tcpip netbt!SendCompletion
Args: 00000000 00000000 00000000 00000000

[9, 0] 0 e1 8d72aee8 8d7ecf60 b9591f41-8d56f5d0 Success Error Cancel
pending
\FileSystem\FltMgr srv!SrvFsdIoCompletionRoutine
Args: 00000000 00000000 00000000 00000000

Let’s have a closer look at this IRP:

kd> dt -r1 nt!_IRP 8d56ff70
+0x000 Type : 6
+0x002 Size : 0x28c
+0x004 MdlAddress : 0x8d570218 _MDL
+0x000 Next : (null)
+0x004 Size : 48
+0x006 MdlFlags : 4100
+0x008 Process : (null)
+0x00c MappedSystemVa : 0x8d4d9690
+0x010 StartVa : 0x8d4d9000
+0x014 ByteCount : 0x4140
+0x018 ByteOffset : 0x690
+0x008 Flags : 0x50
+0x00c AssociatedIrp : __unnamed
+0x000 MasterIrp : 0xe1cacae4 _IRP
+0x000 IrpCount : -506803484
+0x000 SystemBuffer : 0xe1cacae4
+0x010 ThreadListEntry : _LIST_ENTRY [0x8d56ff80 - 0x8d56ff80]
+0x000 Flink : 0x8d56ff80 _LIST_ENTRY [ 0x8d56ff80 -
0x8d56ff80 ]
+0x004 Blink : 0x8d56ff80 _LIST_ENTRY [ 0x8d56ff80 -
0x8d56ff80 ]
+0x018 IoStatus : _IO_STATUS_BLOCK
+0x000 Status : 0
+0x000 Pointer : (null)
+0x004 Information : 0
+0x020 RequestorMode : 0 ‘’
+0x021 PendingReturned : 0x1 ‘’
+0x022 StackCount : 15 ‘’
+0x023 CurrentLocation : 15 ‘’
+0x024 Cancel : 0 ‘’
+0x025 CancelIrql : 0 ‘’
+0x026 ApcEnvironment : 0 ‘’
+0x027 AllocationFlags : 0 ‘’
+0x028 UserIosb : (null)
+0x02c UserEvent : (null)
+0x030 Overlay : __unnamed
+0x000 AsynchronousParameters : __unnamed
+0x000 AllocationSize : _LARGE_INTEGER 0x0
+0x038 CancelRoutine : (null)
+0x03c UserBuffer : (null)
+0x040 Tail : __unnamed
+0x000 Overlay : __unnamed
+0x000 Apc : _KAPC
+0x000 CompletionKey : 0x8d85fd50

Curious, the IRP Flags are 0x50:

#define IRP_BUFFERED_IO 0x00000010

#define IRP_INPUT_OPERATION 0x00000040
#define IRP_SYNCHRONOUS_PAGING_IO 0x00000040

Hmm …

IRP_MJ_FLUSH_BUFFERS has no input or output, so how come we have
IRP_BUFFERED_IO?
IRP_MJ_FLUSH_BUFFFERS is not an input operation, so how come we have
IRP_INPUT_OPERATION?
Or should I be saying IRP_SYNCHRONOUS_PAGING_IO?

The MdlAddress is non null:

kd> !pool 0x8d4d9000
Pool page 8d4d9000 region is Nonpaged pool
*8d306000 : large page allocation, Tag is LSwi, size is 0x275000 bytes
Pooltag LSwi : initial work context

I suppose the “LS” in “LSwi” might stand for “Lanman Server”?
I always see an MdlAddress with this non paged pool tag in the curious IRP.

The AssociatedIrp is non NULL, and it is not an IRP, it’s a paged pool
allocation:

kd> !irp 0xe1cacae4
IRP signature does not match, probably not an IRP

kd> !pool 0xe1cacae4
[SNIP]
*e1caca38 size: f8 previous size: 10 (Allocated) *LSbf
Pooltag LSbf : buffer descriptor
[SNIP]

I always see an AssociatedIrp.SystemBuffer which is non NULL in the curious
IRP. The paged pool tag is always an “LS” tag (e.g., LSbf, LSmf), often it
is allocate-d pool, sometimes it is free-d pool.

I wonder if (a) we are seeing some non documented “out of band” interaction
between SRV and NTFSD, or (b) these values in the IRP Flags, MdlAddress,
AssociatedIrp.SystemBuffer are “incidental” and “not relevant”. To be
honest, I’m not so sure what this IRP means in the file system interface.

If anyone can shed some light on this curious IRP, I’d be very grateful, and
thanks in advance.

Best Wishes,
Lyndon

> I wonder if (a) we are seeing some non documented “out of band” interaction

between SRV and NTFSD

Probably this is some perverted way of providing the completion context to SRV.

The contract for flush IRP says that the FSD ignores any data associated with the IRP. So, SRV probably uses the data as the completion context.

Actually, there are other cases when the IRP is documented as data-less, but the undocumented data really exists for it. This occurs for some IRPs which are sent from undoc user mode code to undoc components of the storage stack, passing thru the FSD which really ignores the data.


Maxim S. Shatskih
Windows DDK MVP
xxxxx@storagecraft.com
http://www.storagecraft.com

Hi Maxim

Thanks, I was wondering about that sort of thing regards the MdlAddress. How
about the AssociatedIrp.SystemBuffer and Flags
IRP_INPUT_OPERATION/IRP_SYNCHRONOUS_PAGING_IO - any ideas?

Best Wishes,
Lyndon

“Maxim S. Shatskih” wrote in message news:xxxxx@ntfsd…

I wonder if (a) we are seeing some non documented “out of band”
interaction
between SRV and NTFSD

Probably this is some perverted way of providing the completion context to
SRV.

The contract for flush IRP says that the FSD ignores any data associated
with the IRP. So, SRV probably uses the data as the completion context.

Actually, there are other cases when the IRP is documented as data-less, but
the undocumented data really exists for it. This occurs for some IRPs which
are sent from undoc user mode code to undoc components of the storage stack,
passing thru the FSD which really ignores the data.


Maxim S. Shatskih
Windows DDK MVP
xxxxx@storagecraft.com
http://www.storagecraft.com