[PATCH 1/2] ntdll: Set signal stack before calling getenv.

Jefferson Carpenter jeffersoncarpenter2 at gmail.com
Sun Dec 27 05:05:57 CST 2020


Figured out what was causing the Segmentation Fault running the 
exception tests.  Since the AC bit was left on, an exception was thrown 
inside of a glibc function in server_init_thread, and the current TEB 
was mis-identified leading to the crash.  This commit re-orders the code 
in server_init_thread so that the TEB is correctly identified should an 
exception be thrown from inside it.

thanks,
Jefferson
-------------- next part --------------
From 230f21bc04cfcd70d387b418b99acc2b6bedee72 Mon Sep 17 00:00:00 2001
From: Jefferson Carpenter <jeffersoncarpenter2 at gmail.com>
Date: Sun, 27 Dec 2020 12:22:20 +0000
Subject: [PATCH 1/2] ntdll: Set signal stack before calling getenv.

Depending on CPU flags, getenv may raise an exception.  Specifically,
if Align Check is on (as it was left on in ntdll/tests/exception.c) an
exception is thrown during this call.

The exception is handled by segv_handler (ntdll/unix/signal_i386.c)
and this function uses get_current_teb to get the TEB from the stack
pointer.  Since segv_handler is run before sigaltstack is called,
get_current_teb is unable to return the correct TEB.

This patch causes any exceptions thrown at least in the getenv call to
be handled on the allocated signal stack, so that get_current_teb
returns the memory location of the current TEB.

Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=49771
Signed-off-by: Jefferson Carpenter <jeffersoncarpenter2 at gmail.com>
---
 dlls/ntdll/unix/server.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/dlls/ntdll/unix/server.c b/dlls/ntdll/unix/server.c
index a9608abfb73..44f26c1db77 100644
--- a/dlls/ntdll/unix/server.c
+++ b/dlls/ntdll/unix/server.c
@@ -1530,7 +1530,7 @@ void server_init_process_done(void)
 size_t server_init_thread( void *entry_point, BOOL *suspend )
 {
     static const char *cpu_names[] = { "x86", "x86_64", "PowerPC", "ARM", "ARM64" };
-    const char *arch = getenv( "WINEARCH" );
+    const char *arch;
     int ret;
     int reply_pipe[2];
     struct sigaction sig_act;
@@ -1548,6 +1548,8 @@ size_t server_init_thread( void *entry_point, BOOL *suspend )
     ss.ss_flags = 0;
     sigaltstack( &ss, NULL );
 
+    arch = getenv( "WINEARCH" );
+
     /* create the server->client communication pipes */
     if (server_pipe( reply_pipe ) == -1) server_protocol_perror( "pipe" );
     if (server_pipe( ntdll_get_thread_data()->wait_fd ) == -1) server_protocol_perror( "pipe" );
-- 
2.26.2



More information about the wine-devel mailing list