question about PsCreateSystemThread and kernel stack

my code like this:

void myfunc()
{
mystruct p;

// create a thread , and pass the pointer of local variable “p” to the new thread
PsCreateSystemThread(…,&p);

//wait until the new thread terminates
KeWaitForSingleObject(…,NULL);

}

thread code like this:

void thread (pvoid pContext)
{
xxx(p); // windbg displays BSOD occurred on this line
}

sometimes, I got BUGCHECK with page_fault_in_nonpaged_area(0x50).

when BSOD occurred ? pContext = 0x8400xxxx ?then I execute “dd 0x8400xxxx " ? it shows " ??? ??? ??? …”

documents says the system thread runs on PASSIVE_LEVEL. and I have not raise IRQL in my thread ?so I think even the variable ?p? is paged out, it 's also safe to access it. But actually, it?s not.

I don’t understand how the BSOD occurred…

I had two questions?

1?is it possible to the local variable in kernel stack will be paged out?

  1. If I had ensure the LiveTime of local variables , is it safe to pass the pointer of local variable to another system thread?

thanks!

FIX: there is a mistake on my description

thrad code like this?

void thread (pvoid pContext)
{
xxx(p->xx); // windbg displays BSOD occurred on this line
}

I searched on google and find this:

https://msdn.microsoft.com/en-us/library/windows/hardware/ff553262(v=vs.85).aspx

It says “Stack swapping can occur only if the thread is in a wait state that was caused by a request from a user-mode application.”

this can expain my first question.

but , system threads runs on PASSIVE_LEVEL , so even the stack is paged out , it can safely access the paged out memory. why the BSOD happened?

unless when thread entering wait state,and it’s stack space paged out, the stack space can’t be “PAGED IN” before thread leave wait state. is it this?

Please post the !analyze -v output

On Sat, Jan 9, 2016 at 12:42 PM, wrote:

> I searched on google and find this:
>
>
> https://msdn.microsoft.com/en-us/library/windows/hardware/ff553262(v=vs.85).aspx
>
> It says “Stack swapping can occur only if the thread is in a wait state
> that was caused by a request from a user-mode application.”
>
> this can expain my first question.
>
> but , system threads runs on PASSIVE_LEVEL , so even the stack is paged
> out , it can safely access the paged out memory. why the BSOD happened?
>
>
> unless when thread entering wait state,and it’s stack space paged out,
> the stack space can’t be “PAGED IN” before thread leave wait state. is it
> this?
>
>
> —
> NTDEV is sponsored by OSR
>
> Visit the list online at: <
> http://www.osronline.com/showlists.cfm?list=ntdev&gt;
>
> 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://www.osronline.com/page.cfm?name=ListServer&gt;
></http:>

to dhananjay kr:

it’s hardly to reappear. I’m testing with driver verifier enabled.

kd> !analyze -v
*******************************************************************************
* *
* Bugcheck Analysis *
* *
*******************************************************************************

PAGE_FAULT_IN_NONPAGED_AREA (50)
Invalid system memory was referenced. This cannot be protected by try-except,
it must be protected by a Probe. Typically the address is just plain bad or it
is pointing at freed memory.
Arguments:
Arg1: fffff8800380a538, memory referenced.
Arg2: 0000000000000000, value 0 = read operation, 1 = write operation.
Arg3: fffff88002d203af, If non-zero, the instruction address which referenced the bad memory
address.
Arg4: 0000000000000000, (reserved)

Debugging Details:

READ_ADDRESS: fffff8800380a538

FAULTING_IP:
DllLoadCheck!t+1f [d:\2015\dllloadcheck\dllloadcheck\dllloadcheck.c @ 398]
fffff880`02d203af 488b5208 mov rdx,qword ptr [rdx+8]

MM_INTERNAL_CODE: 0

IMAGE_NAME: DllLoadCheck.sys

DEBUG_FLR_IMAGE_TIMESTAMP: 5690ccc0

MODULE_NAME: DllLoadCheck

FAULTING_MODULE: fffff88002d1f000 DllLoadCheck

DEFAULT_BUCKET_ID: VISTA_DRIVER_FAULT

BUGCHECK_STR: 0x50

PROCESS_NAME: System

CURRENT_IRQL: 2

TRAP_FRAME: fffff880036cdb40 – (.trap 0xfffff880036cdb40)
NOTE: The trap frame does not contain all registers.
Some register values may be zeroed or incorrect.
rax=0000000000000000 rbx=0000000000000000 rcx=9a78d654450f0000
rdx=fffff8800380a530 rsi=0000000000000000 rdi=0000000000000000
rip=fffff88002d203af rsp=fffff880036cdcd0 rbp=0000000000000080
r8=0000000000000065 r9=0000000000000003 r10=0000000000000000
r11=000000000000000c r12=0000000000000000 r13=0000000000000000
r14=0000000000000000 r15=0000000000000000
iopl=0 nv up ei ng nz na pe nc
DllLoadCheck!t+0x1f:
fffff88002d203af 488b5208 mov rdx,qword ptr [rdx+8] ds:0001:fffff8800380a538=???
Resetting default scope

LAST_CONTROL_TRANSFER: from fffff80003f846d2 to fffff80003e86f60

STACK_TEXT:
fffff880036cd268 fffff80003f846d2 : fffff8800380a538 fffffa800295a060 0000000000000065 fffff80003ecd314 : nt!DbgBreakPointWithStatus
fffff880036cd270 fffff80003f854be : fffff88000000003 fffff880036cdb40 fffff80003ec9f30 fffff880036cd8d0 : nt!KiBugCheckDebugBreak+0x12
fffff880036cd2d0 fffff80003e8f004 : fffff80004007e80 fffff80003e86f85 0000000000000010 0000000000000291 : nt!KeBugCheck2+0x71e
fffff880036cd9a0 fffff80003f0e1e4 : 0000000000000050 fffff8800380a538 0000000000000000 fffff880036cdb40 : nt!KeBugCheckEx+0x104
fffff880036cd9e0 fffff80003e8cfee : 0000000000000000 fffffa800295a060 0000000000000000 0000000000000000 : nt! ?? ::FNODOBFM::string'+0x42907 fffff880036cdb40 fffff88002d203af : fffff88002d23020 fffff8800380a530 fffffa8000cd9278 0000000000000000 : nt!KiPageFault+0x16e fffff880036cdcd0 fffff80004132166 : fffff8800380a530 0000000000000000 0000000000000000 0000000000000000 : DllLoadCheck!t+0x1f [d:\2015\dllloadcheck\dllloadcheck\dllloadcheck.c @ 398] fffff880036cdd00 fffff80003e6d486 : fffff80004007e80 fffffa800295a060 fffffa8000daeb60 0000000000000206 : nt!PspSystemThreadStartup+0x5a fffff880036cdd40 0000000000000000 : fffff880036ce000 fffff880036c8000 fffff880036cdd00 00000000`00000000 : nt!KxStartSystemThread+0x16

STACK_COMMAND: kb

FOLLOWUP_IP:
DllLoadCheck!t+1f [d:\2015\dllloadcheck\dllloadcheck\dllloadcheck.c @ 398]
fffff880`02d203af 488b5208 mov rdx,qword ptr [rdx+8]

FAULTING_SOURCE_CODE:
394: {
395: __try
396: {
397: DbgPrint(“img:%p\n”,pImage);

398: if(MzfGetFileFullPathPreCreate(pImage->fileobject,pImage->path))
399: {
400: MD5File(pImage->path,pImage->md5);
401: }
402:
403: }__except(1)

SYMBOL_STACK_INDEX: 6

SYMBOL_NAME: DllLoadCheck!t+1f

FOLLOWUP_NAME: MachineOwner

FAILURE_BUCKET_ID: X64_0x50_DllLoadCheck!t+1f

BUCKET_ID: X64_0x50_DllLoadCheck!t+1f

Followup: MachineOwner

kd> kp
Child-SP RetAddr Call Site
fffff880036cd268 fffff80003f846d2 nt!DbgBreakPointWithStatus
fffff880036cd270 fffff80003f854be nt!KiBugCheckDebugBreak+0x12
fffff880036cd2d0 fffff80003e8f004 nt!KeBugCheck2+0x71e
fffff880036cd9a0 fffff80003f0e1e4 nt!KeBugCheckEx+0x104
fffff880036cd9e0 fffff80003e8cfee nt! ?? ::FNODOBFM::string'+0x42907 fffff880036cdb40 fffff88002d203af nt!KiPageFault+0x16e fffff880036cdcd0 fffff80004132166 DllLoadCheck!t(struct _IMAGEINFO_ \* pImage = 0xfffff8800380a530)+0x1f [d:\2015\dllloadcheck\dllloadcheck\dllloadcheck.c @ 398]
fffff880036cdd00 fffff80003e6d486 nt!PspSystemThreadStartup+0x5a
fffff880036cdd40 0000000000000000 nt!KxStartSystemThread+0x16
kd> dd 0xfffff8800380a530 fffff8800380a530 ??? ??? ??? ???
fffff8800380a540 ???????? ???????? ???????? ???????? fffff8800380a550 ??? ??? ??? ???
fffff8800380a560 ???????? ???????? ???????? ???????? fffff8800380a570 ??? ??? ??? ???
fffff8800380a580 ???????? ???????? ???????? ???????? fffff8800380a590 ??? ??? ??? ???
fffff8800380a5a0 ???????? ???????? ???????? ???????? kd\> dd 0xfffff8800380a538
fffff8800380a538 ???????? ???????? ???????? ???????? fffff8800380a548 ??? ??? ??? ???
fffff8800380a558 ???????? ???????? ???????? ???????? fffff8800380a568 ??? ??? ??? ???
fffff8800380a578 ???????? ???????? ???????? ???????? fffff8800380a588 ??? ??? ??? ???
fffff8800380a598 ???????? ???????? ???????? ???????? fffff8800380a5a8 ??? ??? ??? ???

code which created the thread:

// all local variables
UCHAR pMd5[33]={0};
UNICODE_STRING Path={0};

Image_Info imginfo;

//need check return
Path.Buffer = ExAllocatePool(NonPagedPool,1024);
Path.MaximumLength = 1024;
Path.Length = 0;
RtlZeroMemory(Path.Buffer,1024);

imginfo.path = &Path;
imginfo.md5 = &pMd5;
imginfo.fileobject = fileObject;

//need check return
PsCreateSystemThread(&hThread,THREAD_ALL_ACCESS,NULL,NULL,&cid,t,&imginfo);

PsLookupThreadByThreadId(cid.UniqueThread,&threadObj);

KeWaitForSingleObject(threadObj,Executive,KernelMode,TRUE,0);
ObDereferenceObject(threadObj);
ZwClose(hThread);

DbgPrint(“%wZ–%s\n”,&Path,pMd5);
ExFreePool(Path.Buffer);

thread code:

void t(Image_Info* pImage)
{
__try
{
DbgPrint(“img:%p\n”,pImage);
if(MzfGetFileFullPathPreCreate(pImage->fileobject,pImage->path))
{
MD5File(pImage->path,pImage->md5);
}

}__except(1)
{
DbgPrint(“except\n”);
}

PsTerminateSystemThread(STATUS_SUCCESS);

}

struct:

typedef struct IMAGEINFO
{
PFILE_OBJECT fileobject;
PUNICODE_STRING path;
PCHAR md5;
}Image_Info;

according to stack:
fffff880036cdcd0 fffff80004132166 DllLoadCheck!t(struct IMAGEINFO * pImage = 0xfffff880`0380a530)+0x1f [d:\2015\dllloadcheck\dllloadcheck\dllloadcheck.c @ 398]

we can know , the pImage = 0xfffff8800380a530 , &pImage-\>path = 0xfffff8800380a538

before calling MzfGetFileFullPathPreCreate , 0xfffff880`0380a530 (pImage) is already paged out.

I tried KeSetKernelStackSwapEnable , it did’nt work,got bugcheck too.

may be I should allocate nonpagedpool for struct Image_Info but not putting it in stack;

!analyze -v displays CURRENT_IRQL: 2 , why the system thread runs on IRQL 2 ? because of the “__try?”

what sense create thread and than wait for it termination ? why in this case not direct call thread func ?

because in this context, some times irql is too high ,such as APC_LEVEL,even DISPATCH_LEVEL.

so I decided do my work in system thread

Well then, there’s your problem: PsCreateSystemThread should only be called
on PASSIVE_LEVEL IRQL. Your solution isn’t actually a solution.

You could create a system thread when your driver starts and use a queue to
pend work items to be processed by your worker thread.
Also you cannot use KeWaitFor* functions with NULL timeout at
DISPATCH_LEVEL.

On 9 January 2016 at 16:08, wrote:

> because in this context, some times irql is too high ,such as
> APC_LEVEL,even DISPATCH_LEVEL.
>
> so I decided do my work in system thread
>
> —
> NTDEV is sponsored by OSR
>
> Visit the list online at: <
> http://www.osronline.com/showlists.cfm?list=ntdev&gt;
>
> 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://www.osronline.com/page.cfm?name=ListServer&gt;
></http:>

You haven’t said what the context is or for that matter what type of driver
it is. A typical case for this is an I/O request that comes to the driver
and can potentially be called at DISPATCH_LEVEL but you need to do work at
PASSIVE_LEVEL. For this the best approach is to queue the request and then
let a thread do the work and complete the IRP.

You can either create a thread that does the work or consider using a work
item
https://msdn.microsoft.com/en-us/library/windows/hardware/ff564587(v=vs.85
%29.aspx?f=255&MSPPError=-2147217396 to do this.

Don Burn
Windows Driver Consulting
Website: http://www.windrvr.com

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of
xxxxx@gmail.com
Sent: Saturday, January 09, 2016 9:08 AM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] question about PsCreateSystemThread and kernel stack

because in this context, some times irql is too high ,such as APC_LEVEL,even
DISPATCH_LEVEL.

so I decided do my work in system thread


NTDEV is sponsored by OSR

Visit the list online at:
http:

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:>

You are not checking a single one of your APIs for error codes. In particular, you are making an alertable wait on the thread. I don’t think you understand what this implies.

#YOLO

Best Regards,

Matthieu Suiche

*This transmission is intended only for the use of the addressee and may
contain information that is privileged, confidential and exempt from
disclosure under applicable law. If you are not the intended recipient, you
are hereby notified that any dissemination, distribution or copying of this
communication is strictly prohibited. If you have received this
communication in error, please notify us immediately.*

On Wed, Jan 13, 2016 at 10:16 PM, wrote:

> You are not checking a single one of your APIs for error codes. In
> particular, you are making an alertable wait on the thread. I don’t think
> you understand what this implies.
>
> —
> NTDEV is sponsored by OSR
>
> Visit the list online at: <
> http://www.osronline.com/showlists.cfm?list=ntdev&gt;
>
> 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://www.osronline.com/page.cfm?name=ListServer&gt;
></http:>