From 69e8cb635ae8cabc78fd95fa4012ffc6827a1865 Mon Sep 17 00:00:00 2001 From: Timo Kreuzer Date: Wed, 21 Mar 2018 10:33:31 +0100 Subject: [PATCH] [NTOS:KE] Fix stack alignment issues --- ntoskrnl/ke/amd64/trap.S | 20 ++++++++++++++++++-- ntoskrnl/ke/amd64/usercall.c | 9 ++++++--- 2 files changed, 24 insertions(+), 5 deletions(-) diff --git a/ntoskrnl/ke/amd64/trap.S b/ntoskrnl/ke/amd64/trap.S index db7684d9b96..d0d1ab16edf 100644 --- a/ntoskrnl/ke/amd64/trap.S +++ b/ntoskrnl/ke/amd64/trap.S @@ -600,7 +600,19 @@ PUBLIC KiApcInterrupt ExitTrap (TF_VOLATILES or TF_IRQL) .ENDP +/* + * VOID + * KiRetireDpcList( + * PKPRCB Prcb); + */ EXTERN KiRetireDpcList:PROC + +/* + * VOID + * KiRetireDpcListInDpcStack( + * PKPRCB Prcb, + * PVOID DpcStack); + */ PUBLIC KiRetireDpcListInDpcStack .PROC KiRetireDpcListInDpcStack push rbp @@ -609,9 +621,13 @@ PUBLIC KiRetireDpcListInDpcStack .setframe rbp, 0 .endprolog - /* Switch stack and call the function */ + /* Switch to the DpcStack */ mov rsp, rdx - sub rsp, 40 + + /* The stack is 16 byte aligned, allocate 32 bytes home space */ + sub rsp, 32 + + /* Call KiRetireDpcList on the given stack */ call KiRetireDpcList /* Restore stack, cleanup and return */ diff --git a/ntoskrnl/ke/amd64/usercall.c b/ntoskrnl/ke/amd64/usercall.c index 42976d340ef..8eb059ccd54 100644 --- a/ntoskrnl/ke/amd64/usercall.c +++ b/ntoskrnl/ke/amd64/usercall.c @@ -66,7 +66,7 @@ KiInitializeUserApc( _SEH2_TRY { /* Probe the context */ - ProbeForWrite(Context, sizeof(CONTEXT), 16); + ProbeForWrite(Context, sizeof(CONTEXT), 16); /* Convert the current trap frame to a context */ Context->ContextFlags = CONTEXT_FULL | CONTEXT_DEBUG_REGISTERS; @@ -253,8 +253,11 @@ KeUserModeCallback( /* Enter a SEH Block */ _SEH2_TRY { - /* Calculate and align the stack size */ - UserArguments = (PUCHAR)ALIGN_DOWN_POINTER_BY(OldStack - ArgumentLength, sizeof(PVOID)); + /* Calculate and align the stack. This is unaligned by 8 bytes, since the following + UCALLOUT_FRAME compensates for that and on entry we already have a full stack + frame with home space for the next call, i.e. we are already inside the function + body and the stack needs to be 16 byte aligned. */ + UserArguments = (PUCHAR)ALIGN_DOWN_POINTER_BY(OldStack - ArgumentLength, 16) - 8; /* The callout frame is below the arguments */ CalloutFrame = ((PUCALLOUT_FRAME)UserArguments) - 1;