diff --git a/patches/ntdll-Signal_Handler/0001-ntdll-Avoid-stack-protector-frame-in-signal-handler-.patch b/patches/ntdll-Signal_Handler/0001-ntdll-Avoid-stack-protector-frame-in-signal-handler-.patch new file mode 100644 index 00000000..e9cd2cb3 --- /dev/null +++ b/patches/ntdll-Signal_Handler/0001-ntdll-Avoid-stack-protector-frame-in-signal-handler-.patch @@ -0,0 +1,138 @@ +From b27c92f6d5f212307e291eac1b2abd376399366c Mon Sep 17 00:00:00 2001 +From: Sebastian Lackner +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 + diff --git a/patches/ntdll-Signal_Handler/definition b/patches/ntdll-Signal_Handler/definition new file mode 100644 index 00000000..ee1b4c0d --- /dev/null +++ b/patches/ntdll-Signal_Handler/definition @@ -0,0 +1 @@ +Depends: ntdll-WRITECOPY diff --git a/patches/patchinstall.sh b/patches/patchinstall.sh index 9cc01eb1..c4dcc796 100755 --- a/patches/patchinstall.sh +++ b/patches/patchinstall.sh @@ -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: