Given the functionality of your filter, failing the create at this point is
also an option.
-scott
OSR
@OSRDrivers
“Ged Murphy” wrote in message news:xxxxx@ntfsd…
Yeah ideally I’d opt to just let the thread go, but because Windows allows
it to complete its op I have to intervene otherwise it causes a potential
security issue in our software. I say ‘potential’ because in reality it
probably doesn’t exist, but I need to code against it just in case.
More info : The terminating threads I’m seeing are coming off the back of
UAC and the user process being torn down when the loader heuristics realise
it needs to be elevated. This means the terminating thread I’m seeing is
coming from a terminating process.
Therefore once the IO has completed, the thread will terminate and won’t be
issuing any more requests. This means the resulting file handle will never
be used by the terminating thread nor any other threads as they’re all being
torn down, and under this situation there’s no real security risk. However
there is the possibility that in other cases the process might not be
terminating, it could just be this one thread. We now have a process with a
handle to a file which it possibly shouldn’t have (it never went through our
rules engine), and that handle will still be valid for other threads in that
process to use.
So in light of all this, I opted to just reissue the request on the same
thread and this seems to work without issues in my testing. As you said
Scott, the thread has already been alerted and it won’t be alerted again.
Add in the fact that Windows allows the thread to complete its op, it just
‘feels’ correct that we do the same.
Although I’m pretty confident that no issues will arise from this, I have
chosen to add code to move it off to a deferred call under an engineering
key, in case I see a problem with it later.
Also apologies to Gabriel. I’ve just re-read my last post and it comes
across as a bit rude, which was not my intention at all. I was probably
having a bad day
Thanks to all. Hopefully this thread will help someone else
-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Scott Noone
Sent: 09 May 2016 15:10
To: Windows File Systems Devs Interest List
Subject: Re:[ntfsd] FltSendMessage on terminating threads
Just to back up a bit…
When a thread is terminated, an alert is raised on the thread.
FsrtlCancellableWaitForSingleObject senses this condition if the alert was
raised either before or during the wait, dismisses the alert on the thread,
and returns STATUS_THREAD_IS_TERMINATING. Once the alert is dismissed, if
you wait again the wait “works” because there is no longer an alert pending.
The OS does returns this error because it makes sense that if the thread
wants to terminate itself then we should let it. Any operation that we’re
waiting for on behalf of the thread no longer really matters, so let’s make
it all to go away and kill the thread (and maybe the process). Note that
even absent any third party products the behavior here is really
non-deterministic: if a thread is trying to create a file on the file system
and I asynchronously terminate it, does the file get created or not?
All that being said, how you handle this really depends on your particular
filter. However, the three options that you outlined (resubmit, post to a
thread, or queue work item) are functionally equivalent in that you’re going
to prevent the terminating thread from terminating itself until the response
comes back. They also all have the downside in that the layers beneath you
will (effectively) not be able to wait cancellable for the operation and
break out of their waits due to thread termination.
As an aside, FltMgr always forces create operations to be synchronous.
-scott
OSR
@OSRDrivers
wrote in message news:xxxxx@ntfsd…
Ged,
Not going into too many details, doing the enforcement fully in kernel mode
can be achieved if you make the right design decisions in the beginning,
without linking the GUI to the enforcement side of things. I have done it
before, achieving performance that would surpass all current AV on the
market today ( according to the ADK ), but that is not the point here.
As you said yourself this is an edge case scenario, you do not need to worry
too much performance here. Queuing a work item or having a worker thread for
this, or re-issueing the flt call, does not impact the overall performance
as much, or in any noticeable way.
There is no one right answer here. You need to make your own benchmarking
and performance test and chose what best fits your design. Either reissue
the call to fltsendxx or worker thread or work item. It’s just something you
just need to eventually test yourself. I doubt there is a preferred method.
It is what fits your model best.
You could also let us know what was the best solution here for you, for the
forum.
Cheers.
--------------------------------------------------------
Gabriel Bercea
Windows Kernel Driver Consulting
http://
www.kasardia.com
From: Ged Murphy
Sent: Thursday, May 5, 19:08
Subject: RE: [ntfsd] FltSendMessage on terminating threads
To: Windows File Systems Devs Interest List
No sane person would implement a processing engine in the kernel, especially
when it’s controlled by a large and complex GUI. Asking usermode to do tasks
like this is what the comms architecture is built for.
Yeah PsIsThreadTerminating just looks at the ETHREAD.Terminating member
which I mentioned before. We already know that it’s terminating because
FltSendMessage (via FsRtlCancellableWaitForMultipleObjects) has already told
us.
The last two options you provided are solutions I’ve already talked about
previously in this thread, but stated that I didn’t feel they were
particularly elegant. Leaving a system thread hanging around just to handle
rare cases when threads are queued for termination mid-op seems wasteful. I’m
leaning towards moving the operation off to a deferred work item as I think
it’s the best supported solution I can see. But I don’t like to pend
operations that are synchronous, which a create operation is.
What I am actually asking is what is the preferred solution here?
What have other people done in this scenario?
I’m just looking to share knowledge as searching the list doesn’t come up
with any solutions for this particular scenario, and the MS docs make no
mention of it.
I have noticed that if you re-issue the call to FltSendMessage, then it
succeeds the second time. It feels like a hack, but considering the thread
allows the op to go all the way down to the file system driver, succeed and
come back up the stack without issues, is it really such a horrible thing to
do??
Ged.
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of
xxxxx@kasardia.com
Sent: 05 May 2016 16:04
To: Windows File Systems Devs Interest List
Subject: RE: [ntfsd] FltSendMessage on terminating threads
Well you got a few options here. One that you might not be able to
implement, at least I the short term, but it’s desirable is that your rule
parsing be done in kernel mode. This way you do all the enforcement inline
and all is fine.
Secondly you could deliver the query to a worker thread in your driver (
only for the case where the thread is terminating , see
PsIsThreadTerminating ). From the inline call you could just wait a
configurable timeout for your worker thread to process the request should it
hang or something and then choose your security policy ( default allow or
default deny ) in case of errors during the applying of the rules or user
mode call.
The third option would be do it everytime with a km thread pool.
--------------------------------------------------------
Gabriel Bercea
Windows Kernel Driver Consulting
http://%3cbr/%3ewww.kasardia.com
On Thu, May 5, 2016 at 6:36 AM -0700, “Ged Murphy”
wrote:
In response to your last question about the IO Manager, I had assumed it
would have cancelled the request because a terminating thread will always
call IoCancelThreadIo as part of its termination routines. So I would have
expected the IO to have been cancelled when the fltmgr gave control back.
I shouldn’t have assumed here as It’s likely that the thread doesn’t get as
far as calling IoCancelThreadIo when it’s released from FltSendMessage.
Ged.
From: xxxxx@lists.osr.com
[mailtomailto:xxxxx@lists.osr.com] On Behalf Of
xxxxx@kasardia.com
Sent: 05 May 2016 13:40
To: Windows File Systems Devs Interest List
Subject: Re: [ntfsd] FltSendMessage on terminating threads
Hey,
I want to ask why isn’t he UM thread queued for termination ?
Is it possible for you to just use a thread pool or some sort in user mode
and issue a call with a timeout from the driver there ?
I don’t see a good reason why threads would be terminating in this paradigm
of work.
The scenario you are describing to me personally seems a bit unclear butnin
the same time the overall design seems also a bit shady.
Why would you assume that the IO manager would cancel the request. I think
that is the other way around in a sense, that the thread itself would not
terminate until all the IO queued on that thread are completed.
Regardless, I would re think the overall design because it just seems to me
that something is just off about it.
--------------------------------------------------------
Gabriel Bercea
Windows Kernel Driver Consulting
http://%3cbr/%3ewww.kasardia.com
From: Ged Murphy
Sent: Thursday, May 5, 13:10
Subject: [ntfsd] FltSendMessage on terminating threads
To: Windows File Systems Devs Interest List
Hi all, I have a filter driver that makes allow/block decisions for various
files, and relies on a rules engine running in usermode to make these
decisions. Occasionally when querying usermode, my calls to FltSendMessage
return with STATUS_THREAD_IS_TERMINATING due to the thread I’m using being
queued for termination. In the case I’m seeing at the moment, this is
happening in the pre-create operation. The ETHREAD also shows the thread
being in a terminating state with the thread.CrossThreadFlags having the
CT_TERMINATED_BIT set, and the thread.Terminated member is set to TRUE
+0x280 CrossThreadFlags : 0x8823 +0x280 Terminated : 0y1 I incorrectly
assumed that the IO would be terminated on this thread when it was returned
back to the IO Manager, so simply ignored the request and allowed it to
continue. However I was seeing cases where some files were getting past the
rules engine and have tracked it down to files on threads that are queued
for termination. I followed the thread and caught it on its way back up the
stack in the post-create, and was surprised to see that the operation had
completed successfully, even though the ETHREAD still had the above flags
set. What’s the correct course of action in this scenario? I could queue a
deferred work item and make the call up on that, or have a dedicated system
thread available to handle cases such as these, both methods have their
drawbacks. I’ve also seen talk on the list of retrying FltSendMessage again
works the second time around, but that just feels wrong. Any pointers
welcome. Thanks. — NTFSD is sponsored by OSR MONTHLY seminars on crash
dump analysis, WDF, Windows internals and software drivers! Details at To
unsubscribe, visit the List Server section of OSR Online at
— NTFSD is sponsored by OSR MONTHLY seminars on crash dump analysis, WDF,
Windows internals and software drivers! Details at To unsubscribe, visit the
List Server section of OSR Online at
—
NTFSD is sponsored by OSR
MONTHLY seminars on crash dump analysis, WDF, Windows internals and software
drivers!
Details at http:
To unsubscribe, visit the List Server section of OSR Online at
http:
—
NTFSD is sponsored by OSR
MONTHLY seminars on crash dump analysis, WDF, Windows internals and software
drivers!
Details at http:
To unsubscribe, visit the List Server section of OSR Online at
http:
—
NTFSD is sponsored by OSR
MONTHLY seminars on crash dump analysis, WDF, Windows internals and software
drivers!
Details at http:
To unsubscribe, visit the List Server section of OSR Online at
http:
—
NTFSD is sponsored by OSR
MONTHLY seminars on crash dump analysis, WDF, Windows internals and software
drivers!
Details at http:
To unsubscribe, visit the List Server section of OSR Online at
http:</http:></http:></http:></http:></http:></http:></http:></http:>