Added patch to avoid stack protector frame in signal handler functions.

This commit is contained in:
Sebastian Lackner 2017-08-20 17:27:22 +02:00
parent f09e1db3cc
commit 5adb9710aa
3 changed files with 214 additions and 49 deletions

View File

@ -0,0 +1,138 @@
From b27c92f6d5f212307e291eac1b2abd376399366c Mon Sep 17 00:00:00 2001
From: Sebastian Lackner <sebastian@fds-team.de>
Date: Sun, 20 Aug 2017 17:22:20 +0200
Subject: ntdll: Avoid stack protector frame in signal handler functions.
---
dlls/ntdll/signal_i386.c | 31 +++++++++++++++++++------------
1 file changed, 19 insertions(+), 12 deletions(-)
diff --git a/dlls/ntdll/signal_i386.c b/dlls/ntdll/signal_i386.c
index c46d50eb271..8a637f23825 100644
--- a/dlls/ntdll/signal_i386.c
+++ b/dlls/ntdll/signal_i386.c
@@ -96,6 +96,13 @@ typedef struct
BYTE Reserved4[96];
} XMM_SAVE_AREA32;
+#ifdef __GNUC__
+/* It is not valid to access %gs before init_handler has been called. */
+#define SIGNALFUNC __attribute__((__optimize__("-fno-stack-protector")))
+#else
+#define SIGNALFUNC
+#endif
+
/***********************************************************************
* signal context platform-specific definitions
*/
@@ -663,7 +670,7 @@ static inline void *get_signal_stack(void)
*
* Get the current teb based on the stack pointer.
*/
-static inline TEB *get_current_teb(void)
+static inline TEB * SIGNALFUNC get_current_teb(void)
{
unsigned long esp;
__asm__("movl %%esp,%0" : "=g" (esp) );
@@ -1023,7 +1030,7 @@ __ASM_GLOBAL_FUNC( clear_alignment_flag,
* Handler initialization when the full context is not needed.
* Return the stack pointer to use for pushing the exception data.
*/
-static inline void *init_handler( const ucontext_t *sigcontext, WORD *fs, WORD *gs )
+static inline void * SIGNALFUNC init_handler( const ucontext_t *sigcontext, WORD *fs, WORD *gs )
{
TEB *teb = get_current_teb();
@@ -2032,7 +2039,7 @@ static EXCEPTION_RECORD *setup_exception_record( ucontext_t *sigcontext, void *s
* sigcontext so that the return from the signal handler will call
* the raise function.
*/
-static EXCEPTION_RECORD *setup_exception( ucontext_t *sigcontext, raise_func func )
+static EXCEPTION_RECORD * SIGNALFUNC setup_exception( ucontext_t *sigcontext, raise_func func )
{
WORD fs, gs;
void *stack = init_handler( sigcontext, &fs, &gs );
@@ -2231,7 +2238,7 @@ done:
* immediately set VIP_FLAG, causing pending events to be handled
* as early as possible.
*/
-static void usr2_handler( int signal, siginfo_t *siginfo, void *sigcontext )
+static void SIGNALFUNC usr2_handler( int signal, siginfo_t *siginfo, void *sigcontext )
{
EXCEPTION_RECORD *rec = setup_exception( sigcontext, raise_vm86_sti_exception );
rec->ExceptionCode = EXCEPTION_VM86_STI;
@@ -2245,7 +2252,7 @@ static void usr2_handler( int signal, siginfo_t *siginfo, void *sigcontext )
* Handler for SIGSEGV and related errors. Used only during the initialization
* of the process to handle virtual faults.
*/
-static void segv_handler_early( int signal, siginfo_t *siginfo, void *sigcontext )
+static void SIGNALFUNC segv_handler_early( int signal, siginfo_t *siginfo, void *sigcontext )
{
WORD fs, gs;
ucontext_t *context = sigcontext;
@@ -2269,7 +2276,7 @@ static void segv_handler_early( int signal, siginfo_t *siginfo, void *sigcontext
*
* Handler for SIGSEGV and related errors.
*/
-static void segv_handler( int signal, siginfo_t *siginfo, void *sigcontext )
+static void SIGNALFUNC segv_handler( int signal, siginfo_t *siginfo, void *sigcontext )
{
WORD fs, gs;
EXCEPTION_RECORD *rec;
@@ -2363,7 +2370,7 @@ static void segv_handler( int signal, siginfo_t *siginfo, void *sigcontext )
*
* Handler for SIGTRAP.
*/
-static void trap_handler( int signal, siginfo_t *siginfo, void *sigcontext )
+static void SIGNALFUNC trap_handler( int signal, siginfo_t *siginfo, void *sigcontext )
{
ucontext_t *context = sigcontext;
EXCEPTION_RECORD *rec = setup_exception( context, raise_trap_exception );
@@ -2392,7 +2399,7 @@ static void trap_handler( int signal, siginfo_t *siginfo, void *sigcontext )
*
* Handler for SIGFPE.
*/
-static void fpe_handler( int signal, siginfo_t *siginfo, void *sigcontext )
+static void SIGNALFUNC fpe_handler( int signal, siginfo_t *siginfo, void *sigcontext )
{
CONTEXT *win_context;
ucontext_t *context = sigcontext;
@@ -2441,7 +2448,7 @@ static void fpe_handler( int signal, siginfo_t *siginfo, void *sigcontext )
*
* FIXME: should not be calling external functions on the signal stack.
*/
-static void int_handler( int signal, siginfo_t *siginfo, void *sigcontext )
+static void SIGNALFUNC int_handler( int signal, siginfo_t *siginfo, void *sigcontext )
{
WORD fs, gs;
init_handler( sigcontext, &fs, &gs );
@@ -2457,7 +2464,7 @@ static void int_handler( int signal, siginfo_t *siginfo, void *sigcontext )
*
* Handler for SIGABRT.
*/
-static void abrt_handler( int signal, siginfo_t *siginfo, void *sigcontext )
+static void SIGNALFUNC abrt_handler( int signal, siginfo_t *siginfo, void *sigcontext )
{
EXCEPTION_RECORD *rec = setup_exception( sigcontext, raise_generic_exception );
rec->ExceptionCode = EXCEPTION_WINE_ASSERTION;
@@ -2470,7 +2477,7 @@ static void abrt_handler( int signal, siginfo_t *siginfo, void *sigcontext )
*
* Handler for SIGQUIT.
*/
-static void quit_handler( int signal, siginfo_t *siginfo, void *sigcontext )
+static void SIGNALFUNC quit_handler( int signal, siginfo_t *siginfo, void *sigcontext )
{
WORD fs, gs;
init_handler( sigcontext, &fs, &gs );
@@ -2483,7 +2490,7 @@ static void quit_handler( int signal, siginfo_t *siginfo, void *sigcontext )
*
* Handler for SIGUSR1, used to signal a thread that it got suspended.
*/
-static void usr1_handler( int signal, siginfo_t *siginfo, void *sigcontext )
+static void SIGNALFUNC usr1_handler( int signal, siginfo_t *siginfo, void *sigcontext )
{
CONTEXT context;
WORD fs, gs;
--
2.14.1

View File

@ -0,0 +1 @@
Depends: ntdll-WRITECOPY

View File

@ -282,6 +282,7 @@ patch_enable_all ()
enable_ntdll_RtlQueryPackageIdentity="$1"
enable_ntdll_RunlevelInformationInActivationContext="$1"
enable_ntdll_Serial_Port_Detection="$1"
enable_ntdll_Signal_Handler="$1"
enable_ntdll_Stack_Guard_Page="$1"
enable_ntdll_Stack_Overflow="$1"
enable_ntdll_Status_Mapping="$1"
@ -1117,6 +1118,9 @@ patch_enable ()
ntdll-Serial_Port_Detection)
enable_ntdll_Serial_Port_Detection="$2"
;;
ntdll-Signal_Handler)
enable_ntdll_Signal_Handler="$2"
;;
ntdll-Stack_Guard_Page)
enable_ntdll_Stack_Guard_Page="$2"
;;
@ -2499,13 +2503,6 @@ if test "$enable_ntdll_WriteWatches" -eq 1; then
enable_ws2_32_WriteWatches=1
fi
if test "$enable_ntdll_WRITECOPY" -eq 1; then
if test "$enable_ws2_32_WriteWatches" -gt 1; then
abort "Patchset ws2_32-WriteWatches disabled, but ntdll-WRITECOPY depends on that."
fi
enable_ws2_32_WriteWatches=1
fi
if test "$enable_ntdll_SystemRoot_Symlink" -eq 1; then
if test "$enable_ntdll_Exception" -gt 1; then
abort "Patchset ntdll-Exception disabled, but ntdll-SystemRoot_Symlink depends on that."
@ -2513,6 +2510,20 @@ if test "$enable_ntdll_SystemRoot_Symlink" -eq 1; then
enable_ntdll_Exception=1
fi
if test "$enable_ntdll_Signal_Handler" -eq 1; then
if test "$enable_ntdll_WRITECOPY" -gt 1; then
abort "Patchset ntdll-WRITECOPY disabled, but ntdll-Signal_Handler depends on that."
fi
enable_ntdll_WRITECOPY=1
fi
if test "$enable_ntdll_WRITECOPY" -eq 1; then
if test "$enable_ws2_32_WriteWatches" -gt 1; then
abort "Patchset ws2_32-WriteWatches disabled, but ntdll-WRITECOPY depends on that."
fi
enable_ws2_32_WriteWatches=1
fi
if test "$enable_ntdll_RtlIpStringToAddress_Tests" -eq 1; then
if test "$enable_ntdll_RtlQueryPackageIdentity" -gt 1; then
abort "Patchset ntdll-RtlQueryPackageIdentity disabled, but ntdll-RtlIpStringToAddress_Tests depends on that."
@ -6758,6 +6769,63 @@ if test "$enable_ntdll_Serial_Port_Detection" -eq 1; then
) >> "$patchlist"
fi
# Patchset ws2_32-WriteWatches
# |
# | Modified files:
# | * dlls/ntdll/ntdll.spec, dlls/ntdll/ntdll_misc.h, dlls/ntdll/signal_i386.c, dlls/ntdll/virtual.c, dlls/ws2_32/socket.c,
# | include/winternl.h
# |
if test "$enable_ws2_32_WriteWatches" -eq 1; then
patch_apply ws2_32-WriteWatches/0001-ntdll-Expose-wine_uninterrupted_-read-write-_memory-.patch
patch_apply ws2_32-WriteWatches/0002-ws2_32-Avoid-race-conditions-of-async-WSARecv-operat.patch
(
printf '%s\n' '+ { "Sebastian Lackner", "ntdll: Expose wine_uninterrupted_[read|write]_memory as exports.", 1 },';
printf '%s\n' '+ { "Sebastian Lackner", "ws2_32: Avoid race-conditions of async WSARecv() operations with write watches.", 2 },';
) >> "$patchlist"
fi
# Patchset ntdll-WRITECOPY
# |
# | This patchset has the following (direct or indirect) dependencies:
# | * ws2_32-WriteWatches
# |
# | This patchset fixes the following Wine bugs:
# | * [#29384] Voobly expects correct handling of WRITECOPY memory protection
# | * [#35561] MSYS2 expects correct handling of WRITECOPY memory protection
# |
# | Modified files:
# | * dlls/advapi32/crypt.c, dlls/advapi32/tests/security.c, dlls/ntdll/ntdll_misc.h, dlls/ntdll/server.c,
# | dlls/ntdll/signal_arm.c, dlls/ntdll/signal_arm64.c, dlls/ntdll/signal_i386.c, dlls/ntdll/signal_powerpc.c,
# | dlls/ntdll/signal_x86_64.c, dlls/ntdll/thread.c, dlls/ntdll/virtual.c
# |
if test "$enable_ntdll_WRITECOPY" -eq 1; then
patch_apply ntdll-WRITECOPY/0001-ntdll-Trigger-write-watches-before-passing-userdata-.patch
patch_apply ntdll-WRITECOPY/0002-advapi-Trigger-write-watches-before-passing-userdata.patch
patch_apply ntdll-WRITECOPY/0003-ntdll-Setup-a-temporary-signal-handler-during-proces.patch
patch_apply ntdll-WRITECOPY/0004-ntdll-Properly-handle-PAGE_WRITECOPY-protection.-try.patch
(
printf '%s\n' '+ { "Sebastian Lackner", "ntdll: Trigger write watches before passing userdata pointer to wait_reply.", 1 },';
printf '%s\n' '+ { "Sebastian Lackner", "advapi: Trigger write watches before passing userdata pointer to read syscall.", 1 },';
printf '%s\n' '+ { "Michael Müller", "ntdll: Setup a temporary signal handler during process startup to handle page faults.", 2 },';
printf '%s\n' '+ { "Michael Müller", "ntdll: Properly handle PAGE_WRITECOPY protection.", 5 },';
) >> "$patchlist"
fi
# Patchset ntdll-Signal_Handler
# |
# | This patchset has the following (direct or indirect) dependencies:
# | * ws2_32-WriteWatches, ntdll-WRITECOPY
# |
# | Modified files:
# | * dlls/ntdll/signal_i386.c
# |
if test "$enable_ntdll_Signal_Handler" -eq 1; then
patch_apply ntdll-Signal_Handler/0001-ntdll-Avoid-stack-protector-frame-in-signal-handler-.patch
(
printf '%s\n' '+ { "Sebastian Lackner", "ntdll: Avoid stack protector frame in signal handler functions.", 1 },';
) >> "$patchlist"
fi
# Patchset ntdll-Stack_Guard_Page
# |
# | Modified files:
@ -6848,48 +6916,6 @@ if test "$enable_ntdll_Threading" -eq 1; then
) >> "$patchlist"
fi
# Patchset ws2_32-WriteWatches
# |
# | Modified files:
# | * dlls/ntdll/ntdll.spec, dlls/ntdll/ntdll_misc.h, dlls/ntdll/signal_i386.c, dlls/ntdll/virtual.c, dlls/ws2_32/socket.c,
# | include/winternl.h
# |
if test "$enable_ws2_32_WriteWatches" -eq 1; then
patch_apply ws2_32-WriteWatches/0001-ntdll-Expose-wine_uninterrupted_-read-write-_memory-.patch
patch_apply ws2_32-WriteWatches/0002-ws2_32-Avoid-race-conditions-of-async-WSARecv-operat.patch
(
printf '%s\n' '+ { "Sebastian Lackner", "ntdll: Expose wine_uninterrupted_[read|write]_memory as exports.", 1 },';
printf '%s\n' '+ { "Sebastian Lackner", "ws2_32: Avoid race-conditions of async WSARecv() operations with write watches.", 2 },';
) >> "$patchlist"
fi
# Patchset ntdll-WRITECOPY
# |
# | This patchset has the following (direct or indirect) dependencies:
# | * ws2_32-WriteWatches
# |
# | This patchset fixes the following Wine bugs:
# | * [#29384] Voobly expects correct handling of WRITECOPY memory protection
# | * [#35561] MSYS2 expects correct handling of WRITECOPY memory protection
# |
# | Modified files:
# | * dlls/advapi32/crypt.c, dlls/advapi32/tests/security.c, dlls/ntdll/ntdll_misc.h, dlls/ntdll/server.c,
# | dlls/ntdll/signal_arm.c, dlls/ntdll/signal_arm64.c, dlls/ntdll/signal_i386.c, dlls/ntdll/signal_powerpc.c,
# | dlls/ntdll/signal_x86_64.c, dlls/ntdll/thread.c, dlls/ntdll/virtual.c
# |
if test "$enable_ntdll_WRITECOPY" -eq 1; then
patch_apply ntdll-WRITECOPY/0001-ntdll-Trigger-write-watches-before-passing-userdata-.patch
patch_apply ntdll-WRITECOPY/0002-advapi-Trigger-write-watches-before-passing-userdata.patch
patch_apply ntdll-WRITECOPY/0003-ntdll-Setup-a-temporary-signal-handler-during-proces.patch
patch_apply ntdll-WRITECOPY/0004-ntdll-Properly-handle-PAGE_WRITECOPY-protection.-try.patch
(
printf '%s\n' '+ { "Sebastian Lackner", "ntdll: Trigger write watches before passing userdata pointer to wait_reply.", 1 },';
printf '%s\n' '+ { "Sebastian Lackner", "advapi: Trigger write watches before passing userdata pointer to read syscall.", 1 },';
printf '%s\n' '+ { "Michael Müller", "ntdll: Setup a temporary signal handler during process startup to handle page faults.", 2 },';
printf '%s\n' '+ { "Michael Müller", "ntdll: Properly handle PAGE_WRITECOPY protection.", 5 },';
) >> "$patchlist"
fi
# Patchset ntdll-Wait_User_APC
# |
# | This patchset fixes the following Wine bugs: