Use of extra create parameters allocated from lookaside list

Hello !

We can allocate extra create parameters from lookaside list.

Let’s consider next scenario:
Fltregisterfilter - now we have valid pflt_filter.
FltInitExtraCreateParameterLookasideList
Fltstartfiltering
At each pre-create allocate ecp from lookaside list and attach to callback data

So far so good.

Now I want to unload my filter.
I need to call FltDeleteExtraCreateParameterLookasideList.
However there can still be create operations in progress with my attached ecp - io manager will try to free them to deleted lookaside list.
I can’t call FltDeleteExtraCreateParameterLookasideList after fltunregisterfilter because we need valid filter to delete lookaside list.

So it’s look like I can use ECPs from lookaside list only in fltcreatefileex2 calls - in that case I know when all creates that use lookaside ECPs finished and I won’t start new creates after I decide to unload.

However here https://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/fltkernel/nf-fltkernel-fltallocateextracreateparameterfromlookasidelist it is said “ Drivers must free all ECP context structures and lookaside lists they create before unloading. However, if a file system or file system filter driver attaches an ECP to an existing or newly-created ECP_LIST while processing an IRP_MJ_CREATE request, this ECP is automatically cleaned up when the IRP completes.”
So it seems lookaside ECPs can be attached to callback data.

Am I missing something? Is it possible to somehow drain all creates that have lookaside ECPs attached ?

The rules around ECPs are Byzantine and in particular SRV isn’t very good at cleaning up after itself.

Frankly I think I once understood them (the rules) but I was probably mistaken.

The only guarantee I have found is to remove them yourself in post create.

This becomes problematic if if you are wanting to have an ECP survive reparse - but that just needs special handling.

Thank you Rod !
Good to know about srv.

Guess I just won’t attach lookaside ECPs to callback data.

I have always worked under the assumption that FltMgr keeps my PFLT_FILTER referenced until after my filter unload callback. if it doesn’t then we’re all doomed as it’s pretty much impossible to solve your problem.

For my sanity I just put a breakpoint in an unload routine. Here’s the PFLT_FILTER at the start of unload:

1: kd> !fltkd.fltobj ffff9605e1920010 1

FLT_OBJECT: ffff9605e1920010  [02000000] Filter
   RundownRef               : 0x0000000000000002 (1)
   PointerCount             : 0x00000002 
   PrimaryLink              : [ffff9605dfb5d020-ffff9605de4c3020] 

And here it is after FltUnregisterFilter:

1: kd> !fltkd.fltobj ffff9605e1920010 1

FLT_OBJECT: ffff9605e1920010  [02000003] Filter DRAINING ZOMBIED
   RundownRef               : 0x0000000000000001 (0) drained
   PointerCount             : 0x00000001 
   PrimaryLink              : [ffff9605dfb5d020-ffff9605de4c3020] 

And putting a breakpoint on the last pointer count:

1: kd> dt FLTMGR!_FLT_OBJECT ffff9605e1920010
   +0x000 Flags            : 0x2000003 (No matching name)
   +0x004 PointerCount     : 1
   +0x008 RundownRef       : _EX_RUNDOWN_REF
   +0x010 PrimaryLink      : _LIST_ENTRY [ 0xffff9605`dfb5d020 - 0xffff9605`de4c3020 ]
   +0x020 UniqueIdentifier : _GUID {765d6ad3-000a-0000-6117-0700065a72e9}
1: kd> ba w4 ffff9605e1920010+4
1: kd> g
Breakpoint 2 hit
FLTMGR!FltpObjectPointerDereference+0x1f:
fffff802`f403b193 cmp     eax,1
1: kd> kc
 # Call Site
00 FLTMGR!FltpObjectPointerDereference
01 FLTMGR!FltpDoUnloadFilter
02 FLTMGR!FltpMiniFilterDriverUnload
03 nt!IopLoadUnloadDriver
04 nt!ExpWorkerThread
05 nt!PspSystemThreadStartup
06 nt!KiStartSystemThread

So, you’re safe to still use the PFLT_FILTER pointer after unregister and before you return from unload.

Thank you very much Scott !

I always assumed that pflt_filter should be considered invalid after fltunregisterfilter. Same way as any other object can’t be used after obdereferenceobject. But now I see why this is a special case.

Thank you very much again.