From: Paul Gofman pgofman@codeweavers.com
Signed-off-by: Paul Gofman pgofman@codeweavers.com --- dlls/ntdll/unix/signal_i386.c | 4 +--- dlls/ntdll/unix/signal_x86_64.c | 4 +--- dlls/ntdll/unix/thread.c | 17 +++++++++++++++++ dlls/ntdll/unix/unix_private.h | 1 + 4 files changed, 20 insertions(+), 6 deletions(-)
diff --git a/dlls/ntdll/unix/signal_i386.c b/dlls/ntdll/unix/signal_i386.c index 7be0c39c424..a515b21cc2e 100644 --- a/dlls/ntdll/unix/signal_i386.c +++ b/dlls/ntdll/unix/signal_i386.c @@ -1098,9 +1098,7 @@ NTSTATUS WINAPI NtGetContextThread( HANDLE handle, CONTEXT *context ) XSTATE *xstate = (XSTATE *)((char *)context_ex + context_ex->XState.Offset); unsigned int mask;
- if (context_ex->XState.Length < offsetof(XSTATE, YmmContext) - || context_ex->XState.Length > sizeof(XSTATE)) - return STATUS_INVALID_PARAMETER; + if (!validate_context_xstate( context )) return STATUS_INVALID_PARAMETER;
mask = (xstate_compaction_enabled ? xstate->CompactionMask : xstate->Mask) & XSTATE_MASK_GSSE; xstate->Mask = frame->xstate.Mask & mask; diff --git a/dlls/ntdll/unix/signal_x86_64.c b/dlls/ntdll/unix/signal_x86_64.c index 6c87e347eac..3aac1bc3e75 100644 --- a/dlls/ntdll/unix/signal_x86_64.c +++ b/dlls/ntdll/unix/signal_x86_64.c @@ -1918,9 +1918,7 @@ NTSTATUS WINAPI NtGetContextThread( HANDLE handle, CONTEXT *context ) XSTATE *xstate = (XSTATE *)((char *)context_ex + context_ex->XState.Offset); unsigned int mask;
- if (context_ex->XState.Length < offsetof(XSTATE, YmmContext) - || context_ex->XState.Length > sizeof(XSTATE)) - return STATUS_INVALID_PARAMETER; + if (!validate_context_xstate( context )) return STATUS_INVALID_PARAMETER;
mask = (xstate_compaction_enabled ? xstate->CompactionMask : xstate->Mask) & XSTATE_MASK_GSSE; xstate->Mask = frame->xstate.Mask & mask; diff --git a/dlls/ntdll/unix/thread.c b/dlls/ntdll/unix/thread.c index ad47a5fce74..6289b8eadca 100644 --- a/dlls/ntdll/unix/thread.c +++ b/dlls/ntdll/unix/thread.c @@ -152,6 +152,23 @@ void fpu_to_fpux( XMM_SAVE_AREA32 *fpux, const I386_FLOATING_SAVE_AREA *fpu ) }
+/*********************************************************************** + * validate_context_xstate + */ +BOOL validate_context_xstate( CONTEXT *context ) +{ + CONTEXT_EX *context_ex; + + context_ex = (CONTEXT_EX *)(context + 1); + + if (context_ex->XState.Length < offsetof(XSTATE, YmmContext) + || context_ex->XState.Length > sizeof(XSTATE)) + return FALSE; + + return TRUE; +} + + /*********************************************************************** * get_server_context_flags */ diff --git a/dlls/ntdll/unix/unix_private.h b/dlls/ntdll/unix/unix_private.h index 795fc148479..5e101bbe363 100644 --- a/dlls/ntdll/unix/unix_private.h +++ b/dlls/ntdll/unix/unix_private.h @@ -185,6 +185,7 @@ extern void DECLSPEC_NORETURN abort_process( int status ) DECLSPEC_HIDDEN; extern void DECLSPEC_NORETURN exit_process( int status ) DECLSPEC_HIDDEN; extern void wait_suspend( CONTEXT *context ) DECLSPEC_HIDDEN; extern NTSTATUS send_debug_event( EXCEPTION_RECORD *rec, CONTEXT *context, BOOL first_chance ) DECLSPEC_HIDDEN; +extern BOOL validate_context_xstate( CONTEXT *context ) DECLSPEC_HIDDEN; extern NTSTATUS set_thread_context( HANDLE handle, const void *context, BOOL *self, USHORT machine ) DECLSPEC_HIDDEN; extern NTSTATUS get_thread_context( HANDLE handle, void *context, BOOL *self, USHORT machine ) DECLSPEC_HIDDEN; extern NTSTATUS alloc_object_attributes( const OBJECT_ATTRIBUTES *attr, struct object_attributes **ret,