advice on closing handle from user context

Hi,

I have a driver which creates a system thread. In the system thread context
it squirrels away a registry key handle in FILE_OBJECT->FsContext field for
a particular IRP. The driver does not pass any IRPs down.

When IRP_MJ_CLOSE is received, I tried to call ZwClose directly (on handle
stored in FILE_OBJECT->FsContext field) in dispatch routine and occasionally
I get a Bug Check 0x93(INVALID_KERNEL_HANDLE). I guessed this could be due
to the fact the original handle is obtained in system process context
whereas IRP_MJ_CLOSE is called in user context (under normal cases off
course when IRP is not cancelled).

I came up with the following pseudo-code for closing system context handle
in IRP_MJ_CLOSE dispatch :

if(NOT running in system process context)
{
KeStackAttachProcess(SystemProcess, …)
ZwClose(IRP->FILE_OBJECT->FsContext)
KeUnstackDetachProcess()
}
else
{
ZwClose(IRP->FILE_OBJECT->FsContext)
}

Are there any issues with above approach? I know using
KeStackAttachProcess()/keAttachProcess() are not generally recommended but
that’s the best solution I can think of.

Are there any better solutions to the problem scenario I described above?

Thanks
Chandra

How about specifying OBJ_KERNEL_HANDLE in the OBJECT_ATTRIBUTES when you
open the key. This way the handle is valid in all contexts.

d

From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of chandra97 97
Sent: Monday, July 02, 2007 9:55 PM
To: Windows System Software Devs Interest List
Cc: xxxxx@gmail.com
Subject: [ntdev] advice on closing handle from user context

Hi,

I have a driver which creates a system thread. In the system thread
context it squirrels away a registry key handle in
FILE_OBJECT->FsContext field for a particular IRP. The driver does not
pass any IRPs down.

When IRP_MJ_CLOSE is received, I tried to call ZwClose directly (on
handle stored in FILE_OBJECT->FsContext field) in dispatch routine and
occasionally I get a Bug Check 0x93(INVALID_KERNEL_HANDLE). I guessed
this could be due to the fact the original handle is obtained in system
process context whereas IRP_MJ_CLOSE is called in user context (under
normal cases off course when IRP is not cancelled).

I came up with the following pseudo-code for closing system context
handle in IRP_MJ_CLOSE dispatch :

if(NOT running in system process context)
{
KeStackAttachProcess(SystemProcess, …)
ZwClose(IRP->FILE_OBJECT->FsContext)
KeUnstackDetachProcess()
}
else
{
ZwClose(IRP->FILE_OBJECT->FsContext)
}

Are there any issues with above approach? I know using
KeStackAttachProcess()/keAttachProcess() are not generally recommended
but that’s the best solution I can think of.

Are there any better solutions to the problem scenario I described
above?

Thanks
Chandra
— Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256 To unsubscribe, visit the
List Server section of OSR Online at
http://www.osronline.com/page.cfm?name=ListServer

I had already done that to start with when I first noticed the bug check
x93. In the situation I presented, the handle is already opened in system
context so using OBJ_KERNEL_HANDLE may not have any impact.

Chandra

On 7/3/07, Doron Holan wrote:
>
> How about specifying OBJ_KERNEL_HANDLE in the OBJECT_ATTRIBUTES when you
> open the key. This way the handle is valid in all contexts.
>
>
>
> d
>
>
>
> From: xxxxx@lists.osr.com [mailto:
> xxxxx@lists.osr.com] *On Behalf Of *chandra97 97
> Sent: Monday, July 02, 2007 9:55 PM
> To: Windows System Software Devs Interest List
> Cc: xxxxx@gmail.com
> Subject: [ntdev] advice on closing handle from user context
>
>
>
> Hi,
>
> I have a driver which creates a system thread. In the system thread
> context it squirrels away a registry key handle in FILE_OBJECT->FsContext
> field for a particular IRP. The driver does not pass any IRPs down.
>
> When IRP_MJ_CLOSE is received, I tried to call ZwClose directly (on handle
> stored in FILE_OBJECT->FsContext field) in dispatch routine and occasionally
> I get a Bug Check 0x93(INVALID_KERNEL_HANDLE). I guessed this could be due
> to the fact the original handle is obtained in system process context
> whereas IRP_MJ_CLOSE is called in user context (under normal cases off
> course when IRP is not cancelled).
>
> I came up with the following pseudo-code for closing system context handle
> in IRP_MJ_CLOSE dispatch :
>
> if(NOT running in system process context)
> {
> KeStackAttachProcess(SystemProcess, …)
> ZwClose(IRP->FILE_OBJECT->FsContext)
> KeUnstackDetachProcess()
> }
> else
> {
> ZwClose(IRP->FILE_OBJECT->FsContext)
> }
>
> Are there any issues with above approach? I know using
> KeStackAttachProcess()/keAttachProcess() are not generally recommended but
> that’s the best solution I can think of.
>
> Are there any better solutions to the problem scenario I described above?
>
> Thanks
> Chandra
> — Questions? First check the Kernel Driver FAQ at
> http://www.osronline.com/article.cfm?id=256 To unsubscribe, visit the List
> Server section of OSR Online at
> http://www.osronline.com/page.cfm?name=ListServer
>
>
> —
> Questions? First check the Kernel Driver FAQ at
> http://www.osronline.com/article.cfm?id=256
>
> To unsubscribe, visit the List Server section of OSR Online at
> http://www.osronline.com/page.cfm?name=ListServer
>

Perhaps your original problem is not what you think it is, because what
Doron said should make an otherwise valid handle valid in any context.
Your dispatch routine is probably called in the context of the caller,
which is what OBJ_KERNEL_HANDLE should address.

This may not be a major issue, but the
KeStackAttachProcess(SystemProcess, …) will be quite slow.

mm


From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of chandra97 97
Sent: Tuesday, July 03, 2007 09:24
To: Windows System Software Devs Interest List
Subject: Re: [ntdev] advice on closing handle from user context

I had already done that to start with when I first noticed the bug check
x93. In the situation I presented, the handle is already opened in
system context so using OBJ_KERNEL_HANDLE may not have any impact.

Chandra

On 7/3/07, Doron Holan wrote:

How about specifying OBJ_KERNEL_HANDLE in the OBJECT_ATTRIBUTES when you
open the key. This way the handle is valid in all contexts.

d

From: xxxxx@lists.osr.com [mailto:
xxxxx@lists.osr.com
mailto:xxxxx] On Behalf Of chandra97 97
Sent: Monday, July 02, 2007 9:55 PM
To: Windows System Software Devs Interest List
Cc: xxxxx@gmail.com
Subject: [ntdev] advice on closing handle from user context

Hi,

I have a driver which creates a system thread. In the system thread
context it squirrels away a registry key handle in
FILE_OBJECT->FsContext field for a particular IRP. The driver does not
pass any IRPs down.

When IRP_MJ_CLOSE is received, I tried to call ZwClose directly (on
handle stored in FILE_OBJECT->FsContext field) in dispatch routine and
occasionally I get a Bug Check 0x93(INVALID_KERNEL_HANDLE). I guessed
this could be due to the fact the original handle is obtained in system
process context whereas IRP_MJ_CLOSE is called in user context (under
normal cases off course when IRP is not cancelled).

I came up with the following pseudo-code for closing system context
handle in IRP_MJ_CLOSE dispatch :

if(NOT running in system process context)
{
KeStackAttachProcess(SystemProcess, …)
ZwClose(IRP->FILE_OBJECT->FsContext)
KeUnstackDetachProcess()
}
else
{
ZwClose(IRP->FILE_OBJECT->FsContext)
}

Are there any issues with above approach? I know using
KeStackAttachProcess()/keAttachProcess() are not generally recommended
but that’s the best solution I can think of.

Are there any better solutions to the problem scenario I described
above?

Thanks
Chandra

— Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256 To unsubscribe, visit the
List Server section of OSR Online at
http://www.osronline.com/page.cfm?name=ListServer


Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256

To unsubscribe, visit the List Server section of OSR Online at
http://www.osronline.com/page.cfm?name=ListServer

— Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256 To unsubscribe, visit the
List Server section of OSR Online at
http://www.osronline.com/page.cfm?name=ListServer</mailto:xxxxx>

There is a difference between opening a handle in the system context and
opening a handle with OBJ_KERNEL_HANDLE. Without the flag, you are
opening the handle in the system handle table which is only valid when
you are in the context of the system (e.g. not an application context).
With the flag, the handle is placed in a global handle table which is
valid in all process contexts, regardless of what context the handle was
opened in.

d

From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of chandra97 97
Sent: Tuesday, July 03, 2007 6:24 AM
To: Windows System Software Devs Interest List
Subject: Re: [ntdev] advice on closing handle from user context

I had already done that to start with when I first noticed the bug check
x93. In the situation I presented, the handle is already opened in
system context so using OBJ_KERNEL_HANDLE may not have any impact.

Chandra

On 7/3/07, Doron Holan wrote:

How about specifying OBJ_KERNEL_HANDLE in the OBJECT_ATTRIBUTES when you
open the key. This way the handle is valid in all contexts.

d

From: xxxxx@lists.osr.com [mailto:
xxxxx@lists.osr.com
mailto:xxxxx] On Behalf Of chandra97 97
Sent: Monday, July 02, 2007 9:55 PM
To: Windows System Software Devs Interest List
Cc: xxxxx@gmail.com
Subject: [ntdev] advice on closing handle from user context

Hi,

I have a driver which creates a system thread. In the system thread
context it squirrels away a registry key handle in
FILE_OBJECT->FsContext field for a particular IRP. The driver does not
pass any IRPs down.

When IRP_MJ_CLOSE is received, I tried to call ZwClose directly (on
handle stored in FILE_OBJECT->FsContext field) in dispatch routine and
occasionally I get a Bug Check 0x93(INVALID_KERNEL_HANDLE). I guessed
this could be due to the fact the original handle is obtained in system
process context whereas IRP_MJ_CLOSE is called in user context (under
normal cases off course when IRP is not cancelled).

I came up with the following pseudo-code for closing system context
handle in IRP_MJ_CLOSE dispatch :

if(NOT running in system process context)
{
KeStackAttachProcess(SystemProcess, …)
ZwClose(IRP->FILE_OBJECT->FsContext)
KeUnstackDetachProcess()
}
else
{
ZwClose(IRP->FILE_OBJECT->FsContext)
}

Are there any issues with above approach? I know using
KeStackAttachProcess()/keAttachProcess() are not generally recommended
but that’s the best solution I can think of.

Are there any better solutions to the problem scenario I described
above?

Thanks
Chandra

— Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256 To unsubscribe, visit the
List Server section of OSR Online at
http://www.osronline.com/page.cfm?name=ListServer


Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256

To unsubscribe, visit the List Server section of OSR Online at
http://www.osronline.com/page.cfm?name=ListServer

— Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256 To unsubscribe, visit the
List Server section of OSR Online at
http://www.osronline.com/page.cfm?name=ListServer</mailto:xxxxx>

Use OBJ_KERNEL_HANDLE in InitializeObjectAttributes when opening the
handle.


Maxim Shatskih, Windows DDK MVP
StorageCraft Corporation
xxxxx@storagecraft.com
http://www.storagecraft.com

“chandra97 97” wrote in message news:xxxxx@ntdev…
> Hi,
>
> I have a driver which creates a system thread. In the system thread context
> it squirrels away a registry key handle in FILE_OBJECT->FsContext field for
> a particular IRP. The driver does not pass any IRPs down.
>
> When IRP_MJ_CLOSE is received, I tried to call ZwClose directly (on handle
> stored in FILE_OBJECT->FsContext field) in dispatch routine and occasionally
> I get a Bug Check 0x93(INVALID_KERNEL_HANDLE). I guessed this could be due
> to the fact the original handle is obtained in system process context
> whereas IRP_MJ_CLOSE is called in user context (under normal cases off
> course when IRP is not cancelled).
>
> I came up with the following pseudo-code for closing system context handle
> in IRP_MJ_CLOSE dispatch :
>
> if(NOT running in system process context)
> {
> KeStackAttachProcess(SystemProcess, …)
> ZwClose(IRP->FILE_OBJECT->FsContext)
> KeUnstackDetachProcess()
> }
> else
> {
> ZwClose(IRP->FILE_OBJECT->FsContext)
> }
>
> Are there any issues with above approach? I know using
> KeStackAttachProcess()/keAttachProcess() are not generally recommended but
> that’s the best solution I can think of.
>
> Are there any better solutions to the problem scenario I described above?
>
> Thanks
> Chandra
>

In the DDK help it states:

“If the driver called PsCreateSystemThread, the Unload routine also must cause the driver-created thread to be run so that the thread itself can call PsTerminateSystemThread before the driver is unloaded. A driver cannot release a driver-created system thread by calling ZwClose with the ThreadHandle returned by PsCreateSystemThread.”

So it looks like PsTerminateSystemThread should be used not ZwClose

> In the DDK help it states:

“If the driver called PsCreateSystemThread, the Unload routine also must cause
the driver-created thread to be run so that the thread itself can call
PsTerminateSystemThread before the driver is unloaded. A driver cannot release a
driver-created system thread by calling ZwClose with the ThreadHandle returned
by PsCreateSystemThread.”

So it looks like PsTerminateSystemThread should be used not ZwClose

Actually, PsTerminateSystemThread() and ZwClose() are totally different things that have nothing to do with one another, so that the very idea of “PsTerminateSystemThread vs ZwClose” is just ridiculous.

ZwClose() is related to the Object Manager and deals with the reference count - it decrements reference count on the object that handle refers to (a pointer to the actual object that handle refers to is available from the handle table of the calling process. ZwClose() is not related to thread termination in any possible way, which is thread dispatcher’s responsibility. Therefore, I really have no idea why you mentioned PsTerminateSystemThread() here, especially taking into account the fact that the OP speaks about a handle that refers to a * registry key* and not to ETHREAD.

What the excerpt that you have quoted actually says is that, unlike HANDLE that ZwCreateThread() returns, the one returned by PsCreateSystemThread() is not related to referencing the target ETHREAD via the handle table of the calling process, and, hence, should not be used as an argument in calls to ZwClose().

Anton Bassov

xxxxx@hotmail.com wrote:

> In the DDK help it states:
>
> “If the driver called PsCreateSystemThread, the Unload routine also must cause
> the driver-created thread to be run so that the thread itself can call
> PsTerminateSystemThread before the driver is unloaded. A driver cannot release a
> driver-created system thread by calling ZwClose with the ThreadHandle returned
> by PsCreateSystemThread.”
>
> So it looks like PsTerminateSystemThread should be used not ZwClose
>


What the excerpt that you have quoted actually says is that, unlike HANDLE that ZwCreateThread() returns, the one returned by PsCreateSystemThread() is not related to referencing the target ETHREAD via the handle table of the calling process, and, hence, should not be used as an argument in calls to ZwClose().

I’m not exactly sure what you meant to say here, but I’m pretty sure
that wasn’t it. Quoting from the DDK on PsCreateSystemThread:

Parameters

ThreadHandle
Points to a variable that will receive the handle. The driver
must close the handle with ZwClose once the handle is no longer in use.

It’s true that PsTerminateSystemThread and ZwClose have unrelated
functions, but it’s also true that BOTH must be called in order to
properly clean up after PsCreateSystemThread.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

> I’m not exactly sure what you meant to say here…

I just explained what MSDN statement that Mark had provided actually *says*. Please note that I did not make any comments on its correctness, because it seems to be wrong. I just showed that this statement in itself is all about reference counting, so that it has nothing to do with thread termination. The statement stands as following:

[begin quote]

A driver cannot release a driver-created system thread by calling ZwClose with the ThreadHandle returned by PsCreateSystemThread.

[end quote]

The above statement says that a driver cannot decrement outstanding refcount on underlying ETHREAD by passing a handle to ZwClose() - after all, the term ‘releasing object’ means decrementing its refcount.

The quoted statement in itself seems to be wrong - after all, it just contradicts the very idea of handle management. I think that this is just one more inconsistency that may be found on MSDN. Apparently, what MSDN *wanted* to say here is that a system thread cannot be terminated by anyone, apart from the thread itself, but *in actuality * it said something that is totally different (and, apparently, wrong)…

Anton Bassov