SID of the requesting thread

List,

In my FS mini-filter driver, I need to get the SID of the requesting thread.

I’d like for it to be as efficient as possible (of course) but also work on Windows 2000.

I have identified a couple of different ways of doing it:

1-- As per http://www.osronline.com/article.cfm?id=50

ObOpenObjectByPointer(FLT_CALLBACK_DATA.Thread)
ZwOpenThreadToken()
-or-
open the process token
-then-
ZwQueryInformationToken(TokenUser)

2-- Somewhat expensive, and does it work with impersonation?

ObGetObjectSecurity() on thread, process
RtlGetOwnerSecurityDescriptor()

3-- SeCaptureSubjectContext() and working from there

Method number three may be preferable in some cases. However, it is difficult to know in which cases. I have not seen a good reference for the various mini-filter dispatchers that explain the execution context and IRQL. Is there any such document?

It’s a common assertion that pre-op and post-op for IRP_MJ_CREATE run at passive level, in the context of the thread that initiated the request. Are there exceptions to this? I read in some old list thread that the post-op context was questioned.

I’m only interested in handling requests that originate in UserMode. Can you give me some hints about context and IRQL for pre-op dispatchers?

Many thanks,

Otto

> It’s a common assertion that pre-op and post-op for IRP_MJ_CREATE run at

passive level,
in the context of the thread that initiated the request. Are there
exceptions to this? I read
in some old list thread that the post-op context was questioned.

It’s unlikely, but in feasible that lower filters or the FileSystem should
pend a CREATE (and if I was tasked with writing a robust test for filters
that would be the first test I’d add…).

However the for filter manager documentation
(http://msdn.microsoft.com/en-us/library/ff552037(VS.85).aspx) is pretty
unambiguous:

Minifilter drivers should not return FLT_PREOP_SYNCHRONIZE for create
operations, because these
operations are already synchronized by the filter manager.

So in order for the assertion to be false you’d need a strange lower filter
or FSD and a broken FltMgr (always remembering the support levels for W2K).
Whether this is a risk you are willing to take would need to be tested
against the risks that getting it wrong might bring and your threat models.

Thanks for comments.

So in order for the assertion to be false you’d need a strange lower filter
or FSD and a broken FltMgr (always remembering the support levels for W2K).

Do you mean there are problems with the FltMgr on W2K. Or are you speaking more generally about testing on all systems to verify assertions?

> Do you mean there are problems with the FltMgr on W2K. Or are you speaking

more generally about testing on all systems to verify assertions?

No, I’m not aware of any issues with FltMgr under W2K, I was just merely
remarking that I have gathered that Win2k is not a supported platform any
more. I don’t know whether security patches are pushed any more but I’d
seriously doubt whether bug fixes are available except for $serious…

Anyone trying to pend IRP_MJ_CREATEs will probably break very many things
(in the OS itself, I’m not talking about 3rd party filters) so it’s unlikely
you will run into such a product in the field. However, I think
IRP_MJ_CREATE was original designed to allow for pending and as such IO
manager captures the security context of the caller and stores it in the
IRP. Just look at the IO_SECURITY_CONTEXT in the IRP_MJ_CREATE parameters
(IO_STACK_LOCATION.Parameters.Create.SecurityContext), which contains a
pointer to the ACCESS_STATE which should tell you everything you need to
know in terms of security for the current access.

Thanks,
Alex.

Excellent information Alex!

The security information is critical to have during create, I should have known it is provided.

I also found the document “Dispatch Routine IRQL and Thread Context” referenced in a parallel thread here (thanks!). It is available at http://msdn.microsoft.com/en-us/library/ff540124(VS.85).aspx

I guess it is also valid for mini-filter drivers.

Regards,
Otto

“Alex Carp” wrote in message news:xxxxx@ntfsd…

Anyone trying to pend IRP_MJ_CREATEs will probably break very many things
(in the OS itself, I’m not talking about 3rd party filters) so it’s
unlikely
you will run into such a product in the field.

Isn’t the I/O manager just going to wait if pending comes back for the
create? Security context is something you would have to worry about, but I’m
just wondering if there’s anything else.

Thanks,

-scott


Scott Noone
Consulting Associate
OSR Open Systems Resources, Inc.
http://www.osronline.com

Hope to see you at the next OSR kernel debugging class February 14th in
Columbia, MD!

“Alex Carp” wrote in message news:xxxxx@ntfsd…

Anyone trying to pend IRP_MJ_CREATEs will probably break very many things
(in the OS itself, I’m not talking about 3rd party filters) so it’s unlikely
you will run into such a product in the field. However, I think
IRP_MJ_CREATE was original designed to allow for pending and as such IO
manager captures the security context of the caller and stores it in the
IRP. Just look at the IO_SECURITY_CONTEXT in the IRP_MJ_CREATE parameters
(IO_STACK_LOCATION.Parameters.Create.SecurityContext), which contains a
pointer to the ACCESS_STATE which should tell you everything you need to
know in terms of security for the current access.

Thanks,
Alex.

I was wondering about this myself, especially since the later OS’es
support CANCEL of CREATE requests. If you are not able to pend a CREATE
then there is little reason for a cancel.

Don Burn (MVP, Windows DKD)
Windows Filesystem and Driver Consulting
Website: http://www.windrvr.com
Blog: http://msmvps.com/blogs/WinDrvr

“Scott Noone” wrote in message news:xxxxx@ntfsd:

> “Alex Carp” wrote in message news:xxxxx@ntfsd…
> >Anyone trying to pend IRP_MJ_CREATEs will probably break very many things
> >(in the OS itself, I’m not talking about 3rd party filters) so it’s
> >unlikely
> >you will run into such a product in the field.
>
> Isn’t the I/O manager just going to wait if pending comes back for the
> create? Security context is something you would have to worry about, but I’m
> just wondering if there’s anything else.
>
> Thanks,
>
> -scott
>
> –
> Scott Noone
> Consulting Associate
> OSR Open Systems Resources, Inc.
> http://www.osronline.com
>
> Hope to see you at the next OSR kernel debugging class February 14th in
> Columbia, MD!
>
> “Alex Carp” wrote in message news:xxxxx@ntfsd…
>
> Anyone trying to pend IRP_MJ_CREATEs will probably break very many things
> (in the OS itself, I’m not talking about 3rd party filters) so it’s unlikely
> you will run into such a product in the field. However, I think
> IRP_MJ_CREATE was original designed to allow for pending and as such IO
> manager captures the security context of the caller and stores it in the
> IRP. Just look at the IO_SECURITY_CONTEXT in the IRP_MJ_CREATE parameters
> (IO_STACK_LOCATION.Parameters.Create.SecurityContext), which contains a
> pointer to the ACCESS_STATE which should tell you everything you need to
> know in terms of security for the current access.
>
> Thanks,
> Alex.

No, you both right, the IO manager will wait if a create is pended and will
try to cancel the request if it needs to. I was remembering having to
investigate some failure that turned out to have something to do with
pending creates but I can’t remember if it was in another OS component or
one of the inbox minifilters…

So I guess I was wrong (or it may have been a bug somewhere that got fixed
:))…

Still I would recommend against pending creates at least for the reason that
some filters may expect a create to arrive in the initiator’s context (at
least going by the pretty frequent advice on OSR’s forum).

Thanks,
Alex.

As a part of “Vista - no hang” initiative, redirectors can pend Create IRP, so it can be cancelled. There were also introduced new APIs for cancelable waiting (FsRtlCancellableWaitForSingleObject(),
FsRtlCancellableWaitForMultipleObjects()). It is always more safe to take context from IRP and don’t rely on the current process context, even if preCreate is always called in this context, I am not sure about postCreate. It must be enforced by FltManager, so mini-filters are called in requestor process context.

Bronislav Gabrhelik

AFAIK FltMgr doesn’t actually guarantee that the minifilters are called in
the context of the requestor process. The guarantee is that the postCreate
callback will be called in the same context as the preCreate (in a way
FltMgr converts the FLT_PREOP_SUCCESS_WITH_CALLBACK return status from a
filter to a FLT_PREOP_SYNCHRONIZE). And since pending a create is somewhat
unusual in most cases the preCreate callback (and implicitly the postCreate
callback) will be called in the context of the original request.

However, if a minifilter pends a create operation and then lets it continue
(by calling FltCompletePendedPreOperation with a status other than
FLT_PREOP_COMPLETE) then the minifilters below that one will be called in
the context of the thread where the minifilter continued the operation.
There is no mechanism to get back to the original thread… The same goes
for legacy filters pending creates.

Thanks,
Alex.

Sorry to add to this old thread but I just saw Alex’s last reply (very informative!). Looking at e.g. FltCancelFileOpen the last part of the comments section:

QUOTE

Callers of FltCancelFileOpen must be running at IRQL PASSIVE_LEVEL. However, it is safe for minifilter drivers to call this routine from a post-create callback routine, because post-create callback routines are guaranteed to be called at IRQL PASSIVE_LEVEL, in the context of the thread that originated the IRP_MJ_CREATE request.

END QUOTE

Here, it is quite easy to interpret “originated” to mean “original requestor”. My general feeling is that documentation regarding this topic is worded in a similar manner. Having just read what Alex wrote it is easier to interpret it correctly, but for the future, it would be great if documentation could be more clear on this point.

Regards,
Otto