system thread context

Hello.

I understand that proper way of passing context data into newly created system thread is by allocation of memo and passing it into system thread.

Now, assuming we’re in DeviceIoControl routine that can be processed in context of any process is it ok to pass local variable address as parameter to system thread?

I mean something like this:
ULONG localVar = 129;
Context *pCtx = ExAllocatePoolWithTag(PagedPool, sizeof(Context), ‘aaaa’);
//check
pCtx->field_one = &localVar;

PsCreateSystemThread(…/…/…/ pCtx );

Now inisde thread
Context *pCtx = (Context*)Param;
ULONG loval = *pCtx->field_one; // is it going to be really same as localVar from above code?

Thank you for response.

It will be the same value as localvar … BUT as soon as your DeviceIoControl routine returns and the stack unwinds field_one will now point to invalid memory. At best, you immediately bugcheck when you deref. At worst, you corrupt memory, most possibly another thread’s stack.

d

-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of xxxxx@gmail.com
Sent: Wednesday, April 25, 2012 12:37 PM
To: Windows System Software Devs Interest List
Subject: [ntdev] system thread context

Hello.

I understand that proper way of passing context data into newly created system thread is by allocation of memo and passing it into system thread.

Now, assuming we’re in DeviceIoControl routine that can be processed in context of any process is it ok to pass local variable address as parameter to system thread?

I mean something like this:
ULONG localVar = 129;
Context *pCtx = ExAllocatePoolWithTag(PagedPool, sizeof(Context), ‘aaaa’); //check
pCtx->field_one = &localVar;

PsCreateSystemThread(…/…/…/ pCtx );

Now inisde thread
Context *pCtx = (Context*)Param;
ULONG loval = *pCtx->field_one; // is it going to be really same as localVar from above code?

Thank you for response.


NTDEV is sponsored by OSR

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

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

Doron,

Can you explain a little bit how it is possible?
Since address is passed and you are in context of different process and different proc address space?
Sorry I’m beginner

No, the process context has nothing do with it. you are taking the address of a local. The address of the local is only valid while the function in which the local resides is on the callstack. As soon you return from that function, the local is no longer valid. So now you have a pointer to a local being access by another thread after the function has returned, so the local pointer is no longer good

-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of xxxxx@gmail.com
Sent: Wednesday, April 25, 2012 1:01 PM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] system thread context

Doron,

Can you explain a little bit how it is possible?
Since address is passed and you are in context of different process and different proc address space?
Sorry I’m beginner


NTDEV is sponsored by OSR

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

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

> Can you explain a little bit how it is possible? Since address is passed and you are in context of different >process and different proc address space? Sorry I’m beginner

Well, you seem to be a beginner not only to the kernel but to C language as well…

Have you ever been told by anyone that passing the address of a local variable to ANYTHING that may outlive
this variable’s scope (passing it as a parameter to another thread without providing synchronization mechanism, returning it to the caller,saving it in a global variable, etc) is just a recipe for a disaster???

Anton Bassov

> Hello.

I understand that proper way of passing context data into newly created
system thread is by allocation of memo and passing it into system thread.

Now, assuming we’re in DeviceIoControl routine that can be processed in
context of any process is it ok to pass local variable address as
parameter to system thread?
****

As already pointed out, the LIFETIME of the data is critical; the data
must be valid at the point where you use it.

Local variables can be used corss-thread only in incredibly restricted
ways; for example

{
BYTE buffer[SOMESIZE];
InitiateThread(buffer);
WaitForThreadTermination()
}

will work, and this idiom appears in the old WDM driver examples for
handling PnP messages. But it represents exceptionally poor programming
practice in general (it means you are using the thread as an incredibly
complex and expensive function call), so the advice you have already
received that you must never, ever, under any normal circumstances, pass
the address of a local variable to ANY context where the use of the
pointer exceeds the lifetime of the stack. Another common error is
passing the address of a local in the ISR stack to a DPC (yes, I’ve seen
this done, and it took a lot of explanation to convince the programmer it
could not possibly have ever worked). This is why the heap is used.
Another consideration is that local buffers use up precious stack space,
and you don’t have a lot of it to burn when you are in the kernel (apps
have 1MB stacks by default; I think drivers have something like 8K, and a
good chunk of that is gone by the time your code is called)
****

I mean something like this:
ULONG localVar = 129;
Context *pCtx = ExAllocatePoolWithTag(PagedPool, sizeof(Context), ‘aaaa’);
//check
pCtx->field_one = &localVar;

PsCreateSystemThread(…/…/…/ pCtx );

Now inisde thread
Context *pCtx = (Context*)Param;
ULONG loval = *pCtx->field_one; // is it going to be really same as
localVar from above code?
*****
What you have passed is a pointer to a location in memory. What that
location means at the point where you dereference it in the thread is
problematic. That memory is going to be used for something, or maybe
doesn’t exist at all, or is used by some other driver which needed a stack
from the kernel stack pool, or is some other subroutine stack frame in the
code that initiated the thread (note that the thread can be running and do
the dereference before you return from PsCreateSystemThread, so on a
multicore system you may have the illusion that it worked, but it was
never, ever correct code.)

Essentially, EVERY location you reference in a thread must be valid at the
time of the reference, and you have essentially guaranteed that your code
cannot possibly work correctly.
*****

Thank you for response.


NTDEV is sponsored by OSR

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

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