From a906f13f774ca9fb575cd8cabb48fcb5ac4bf788 Mon Sep 17 00:00:00 2001 From: Brendan Shanks Date: Thu, 3 Mar 2022 10:24:22 -0800 Subject: [PATCH] ntdll: Ensure CONTEXT_EX on exception stack is initialized. On non-AVX CPUs, CONTEXT_EX is not being initialized. In WOW64 mode, this results in invalid exception records when dispatch_wow_exception() uses RtlCopyContext(). Signed-off-by: Brendan Shanks Signed-off-by: Alexandre Julliard --- dlls/ntdll/unix/signal_i386.c | 23 +++++++++++++++++++---- dlls/ntdll/unix/signal_x86_64.c | 23 +++++++++++++++++++---- 2 files changed, 38 insertions(+), 8 deletions(-) diff --git a/dlls/ntdll/unix/signal_i386.c b/dlls/ntdll/unix/signal_i386.c index 6bb5649e2b5..e2a6148d609 100644 --- a/dlls/ntdll/unix/signal_i386.c +++ b/dlls/ntdll/unix/signal_i386.c @@ -581,12 +581,23 @@ static inline void context_init_xstate( CONTEXT *context, void *xstate_buffer ) xctx->Legacy.Length = sizeof(CONTEXT); xctx->Legacy.Offset = -(LONG)sizeof(CONTEXT); - xctx->XState.Length = sizeof(XSTATE); - xctx->XState.Offset = (BYTE *)xstate_buffer - (BYTE *)xctx; + if (xstate_buffer) + { + xctx->XState.Length = sizeof(XSTATE); + xctx->XState.Offset = (BYTE *)xstate_buffer - (BYTE *)xctx; + context->ContextFlags |= CONTEXT_XSTATE; + + xctx->All.Length = sizeof(CONTEXT) + xctx->XState.Offset + xctx->XState.Length; + } + else + { + xctx->XState.Length = 25; + xctx->XState.Offset = 0; + + xctx->All.Length = sizeof(CONTEXT) + 24; /* sizeof(CONTEXT_EX) minus 8 alignment bytes on x64. */ + } - xctx->All.Length = sizeof(CONTEXT) + xctx->XState.Offset + xctx->XState.Length; xctx->All.Offset = -(LONG)sizeof(CONTEXT); - context->ContextFlags |= CONTEXT_XSTATE; } @@ -1456,6 +1467,10 @@ C_ASSERT( (offsetof(struct stack_layout, xstate) == sizeof(struct stack_layout)) memcpy( &dst_xs->YmmContext, &src_xs->YmmContext, sizeof(dst_xs->YmmContext) ); } } + else + { + context_init_xstate( &stack->context, NULL ); + } stack->rec_ptr = &stack->rec; stack->context_ptr = &stack->context; diff --git a/dlls/ntdll/unix/signal_x86_64.c b/dlls/ntdll/unix/signal_x86_64.c index 68855dccacf..34334f72ff0 100644 --- a/dlls/ntdll/unix/signal_x86_64.c +++ b/dlls/ntdll/unix/signal_x86_64.c @@ -411,12 +411,23 @@ static inline void context_init_xstate( CONTEXT *context, void *xstate_buffer ) xctx->Legacy.Length = sizeof(CONTEXT); xctx->Legacy.Offset = -(LONG)sizeof(CONTEXT); - xctx->XState.Length = sizeof(XSTATE); - xctx->XState.Offset = (BYTE *)xstate_buffer - (BYTE *)xctx; + if (xstate_buffer) + { + xctx->XState.Length = sizeof(XSTATE); + xctx->XState.Offset = (BYTE *)xstate_buffer - (BYTE *)xctx; + context->ContextFlags |= CONTEXT_XSTATE; + + xctx->All.Length = sizeof(CONTEXT) + xctx->XState.Offset + xctx->XState.Length; + } + else + { + xctx->XState.Length = 25; + xctx->XState.Offset = 0; + + xctx->All.Length = sizeof(CONTEXT) + 24; /* sizeof(CONTEXT_EX) minus 8 alignment bytes on x64. */ + } - xctx->All.Length = sizeof(CONTEXT) + xctx->XState.Offset + xctx->XState.Length; xctx->All.Offset = -(LONG)sizeof(CONTEXT); - context->ContextFlags |= CONTEXT_XSTATE; } static USHORT cs32_sel; /* selector for %cs in 32-bit mode */ @@ -2195,6 +2206,10 @@ static void setup_raise_exception( ucontext_t *sigcontext, EXCEPTION_RECORD *rec memcpy( &dst_xs->YmmContext, &src_xs->YmmContext, sizeof(dst_xs->YmmContext) ); } } + else + { + context_init_xstate( &stack->context, NULL ); + } CS_sig(sigcontext) = cs64_sel; RIP_sig(sigcontext) = (ULONG_PTR)pKiUserExceptionDispatcher; -- 2.11.4.GIT