[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