[PATCH] ntdll: set SO_PASSCRED before connecting to eliminate a race condition in obtaining server_pid

Maarten Lankhorst m.b.lankhorst at gmail.com
Tue Oct 16 07:11:45 CDT 2012


From: Maarten Lankhorst <maarten.lankhorst at canonical.com>

---
 dlls/kernel32/process.c |  9 +++++++++
 dlls/ntdll/server.c     | 20 +++++++++++++-------
 2 files changed, 22 insertions(+), 7 deletions(-)

diff --git a/dlls/kernel32/process.c b/dlls/kernel32/process.c
index 1b10f9e..cf8e5ec 100644
--- a/dlls/kernel32/process.c
+++ b/dlls/kernel32/process.c
@@ -1920,6 +1920,15 @@ static BOOL create_process( HANDLE hFile, LPCWSTR filename, LPWSTR cmd_line, LPW
         return FALSE;
     }
 
+#ifdef SO_PASSCRED
+    if (1)
+    {
+        /* prevent a race, and set SO_PASSCRED before passing the socket */
+        int enable = 1;
+        setsockopt( socketfd[0], SOL_SOCKET, SO_PASSCRED, &enable, sizeof(enable) );
+    }
+#endif
+
     if (exec_only)  /* things are much simpler in this case */
     {
         wine_server_send_fd( socketfd[1] );
diff --git a/dlls/ntdll/server.c b/dlls/ntdll/server.c
index 218c6eb..69fba50 100644
--- a/dlls/ntdll/server.c
+++ b/dlls/ntdll/server.c
@@ -881,6 +881,14 @@ static int server_connect(void)
         addr.sun_len = slen;
 #endif
         if ((s = socket( AF_UNIX, SOCK_STREAM, 0 )) == -1) fatal_perror( "socket" );
+#ifdef SO_PASSCRED
+        if (1)
+        {
+            /* prevent a race, and set SO_PASSCRED before connecting socket */
+            int enable = 1;
+            setsockopt( s, SOL_SOCKET, SO_PASSCRED, &enable, sizeof(enable) );
+        }
+#endif
         if (connect( s, (struct sockaddr *)&addr, slen ) != -1)
         {
             /* switch back to the starting directory */
@@ -1004,18 +1012,16 @@ void server_init_process(void)
     pthread_sigmask( SIG_BLOCK, &server_block_set, NULL );
 
     /* receive the first thread request fd on the main socket */
+    ntdll_get_thread_data()->request_fd = receive_fd( &version );
+
 #ifdef SO_PASSCRED
-    if (server_pid == -1)
+    /* now that we hopefully received the server_pid, disable SO_PASSCRED */
+    if (1)
     {
-        int enable = 1;
-        setsockopt( fd_socket, SOL_SOCKET, SO_PASSCRED, &enable, sizeof(enable) );
-        ntdll_get_thread_data()->request_fd = receive_fd( &version );
-        enable = 0;
+        int enable = 0;
         setsockopt( fd_socket, SOL_SOCKET, SO_PASSCRED, &enable, sizeof(enable) );
     }
-    else
 #endif
-    ntdll_get_thread_data()->request_fd = receive_fd( &version );
 
     if (version != SERVER_PROTOCOL_VERSION)
         server_protocol_error( "version mismatch %d/%d.\n"
-- 
1.7.11.3




More information about the wine-patches mailing list