[Wine-patches] [eter-1.0.12] fix eterbug #6900
Alexander Morozov
amorozov на etersoft.ru
Пт Апр 1 21:10:18 MSD 2011
----------- следующая часть -----------
From 4502b8fe8ea9f24ddb2165704332f003a1b0295b Mon Sep 17 00:00:00 2001
From: Alexandre Julliard <julliard на winehq.org>
Date: Wed, 1 Jul 2009 12:11:53 +0200
Subject: [eter-1.0.12 1/4] ntdll: Avoid the close-on-exec race with recvmsg() on kernels that support this.
---
dlls/ntdll/server.c | 8 ++++++--
1 files changed, 6 insertions(+), 2 deletions(-)
diff --git a/dlls/ntdll/server.c b/dlls/ntdll/server.c
index 7651a17..a2ba2cd 100644
--- a/dlls/ntdll/server.c
+++ b/dlls/ntdll/server.c
@@ -81,6 +81,10 @@ WINE_DEFAULT_DEBUG_CHANNEL(server);
#define SCM_RIGHTS 1
#endif
+#ifndef MSG_CMSG_CLOEXEC
+#define MSG_CMSG_CLOEXEC 0
+#endif
+
#define SOCKETNAME "socket" /* name of the socket file */
#define LOCKNAME "lock" /* name of the lock file */
@@ -406,12 +410,12 @@ static int receive_fd( obj_handle_t *handle )
for (;;)
{
- if ((ret = recvmsg( fd_socket, &msghdr, 0 )) > 0)
+ if ((ret = recvmsg( fd_socket, &msghdr, MSG_CMSG_CLOEXEC )) > 0)
{
#ifndef HAVE_STRUCT_MSGHDR_MSG_ACCRIGHTS
fd = cmsg.fd;
#endif
- if (fd != -1) fcntl( fd, F_SETFD, 1 ); /* set close on exec flag */
+ if (fd != -1) fcntl( fd, F_SETFD, FD_CLOEXEC ); /* in case MSG_CMSG_CLOEXEC is not supported */
return fd;
}
if (!ret) break;
--
1.7.4.2
----------- следующая часть -----------
From fc070a5cd9c56f3483bf02a9d39a0f791ffbbccf Mon Sep 17 00:00:00 2001
From: Alexandre Julliard <julliard на winehq.org>
Date: Thu, 30 Sep 2010 11:53:07 +0200
Subject: [eter-1.0.12 2/4] server: Make the fd passing code slightly more portable.
---
dlls/ntdll/server.c | 76 +++++++++++++++++--------------------------
server/request.c | 88 ++++++++++++++++++++++++++++-----------------------
2 files changed, 78 insertions(+), 86 deletions(-)
diff --git a/dlls/ntdll/server.c b/dlls/ntdll/server.c
index a2ba2cd..4cbe790 100644
--- a/dlls/ntdll/server.c
+++ b/dlls/ntdll/server.c
@@ -88,20 +88,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(server);
#define SOCKETNAME "socket" /* name of the socket file */
#define LOCKNAME "lock" /* name of the lock file */
-#ifndef HAVE_STRUCT_MSGHDR_MSG_ACCRIGHTS
-/* data structure used to pass an fd with sendmsg/recvmsg */
-struct cmsg_fd
-{
- struct
- {
- size_t len; /* size of structure */
- int level; /* SOL_SOCKET */
- int type; /* SCM_RIGHTS */
- } header;
- int fd; /* fd to pass */
-};
-#endif /* HAVE_STRUCT_MSGHDR_MSG_ACCRIGHTS */
-
timeout_t server_start_time = 0; /* time of server startup */
sigset_t server_block_set; /* signals to block during server calls */
@@ -329,35 +315,36 @@ void server_leave_uninterrupted_section( RTL_CRITICAL_SECTION *cs, sigset_t *sig
*/
void CDECL wine_server_send_fd( int fd )
{
-#ifndef HAVE_STRUCT_MSGHDR_MSG_ACCRIGHTS
- struct cmsg_fd cmsg;
-#endif
struct send_fd data;
struct msghdr msghdr;
struct iovec vec;
int ret;
- vec.iov_base = (void *)&data;
- vec.iov_len = sizeof(data);
-
- msghdr.msg_name = NULL;
- msghdr.msg_namelen = 0;
- msghdr.msg_iov = &vec;
- msghdr.msg_iovlen = 1;
-
#ifdef HAVE_STRUCT_MSGHDR_MSG_ACCRIGHTS
msghdr.msg_accrights = (void *)&fd;
msghdr.msg_accrightslen = sizeof(fd);
#else /* HAVE_STRUCT_MSGHDR_MSG_ACCRIGHTS */
- cmsg.header.len = sizeof(cmsg.header) + sizeof(fd);
- cmsg.header.level = SOL_SOCKET;
- cmsg.header.type = SCM_RIGHTS;
- cmsg.fd = fd;
- msghdr.msg_control = &cmsg;
- msghdr.msg_controllen = sizeof(cmsg.header) + sizeof(fd);
+ char cmsg_buffer[256];
+ struct cmsghdr *cmsg;
+ msghdr.msg_control = cmsg_buffer;
+ msghdr.msg_controllen = sizeof(cmsg_buffer);
msghdr.msg_flags = 0;
+ cmsg = CMSG_FIRSTHDR( &msghdr );
+ cmsg->cmsg_len = CMSG_LEN( sizeof(fd) );
+ cmsg->cmsg_level = SOL_SOCKET;
+ cmsg->cmsg_type = SCM_RIGHTS;
+ *(int *)CMSG_DATA(cmsg) = fd;
+ msghdr.msg_controllen = cmsg->cmsg_len;
#endif /* HAVE_STRUCT_MSGHDR_MSG_ACCRIGHTS */
+ msghdr.msg_name = NULL;
+ msghdr.msg_namelen = 0;
+ msghdr.msg_iov = &vec;
+ msghdr.msg_iovlen = 1;
+
+ vec.iov_base = (void *)&data;
+ vec.iov_len = sizeof(data);
+
data.tid = GetCurrentThreadId();
data.fd = fd;
@@ -380,24 +367,16 @@ void CDECL wine_server_send_fd( int fd )
static int receive_fd( obj_handle_t *handle )
{
struct iovec vec;
- int ret, fd;
-
-#ifdef HAVE_STRUCT_MSGHDR_MSG_ACCRIGHTS
struct msghdr msghdr;
+ int ret, fd = -1;
- fd = -1;
+#ifdef HAVE_STRUCT_MSGHDR_MSG_ACCRIGHTS
msghdr.msg_accrights = (void *)&fd;
msghdr.msg_accrightslen = sizeof(fd);
#else /* HAVE_STRUCT_MSGHDR_MSG_ACCRIGHTS */
- struct msghdr msghdr;
- struct cmsg_fd cmsg;
-
- cmsg.header.len = sizeof(cmsg.header) + sizeof(fd);
- cmsg.header.level = SOL_SOCKET;
- cmsg.header.type = SCM_RIGHTS;
- cmsg.fd = -1;
- msghdr.msg_control = &cmsg;
- msghdr.msg_controllen = sizeof(cmsg.header) + sizeof(fd);
+ char cmsg_buffer[256];
+ msghdr.msg_control = cmsg_buffer;
+ msghdr.msg_controllen = sizeof(cmsg_buffer);
msghdr.msg_flags = 0;
#endif /* HAVE_STRUCT_MSGHDR_MSG_ACCRIGHTS */
@@ -413,8 +392,13 @@ static int receive_fd( obj_handle_t *handle )
if ((ret = recvmsg( fd_socket, &msghdr, MSG_CMSG_CLOEXEC )) > 0)
{
#ifndef HAVE_STRUCT_MSGHDR_MSG_ACCRIGHTS
- fd = cmsg.fd;
-#endif
+ struct cmsghdr *cmsg;
+ for (cmsg = CMSG_FIRSTHDR( &msghdr ); cmsg; cmsg = CMSG_NXTHDR( &msghdr, cmsg ))
+ {
+ if (cmsg->cmsg_level != SOL_SOCKET) continue;
+ if (cmsg->cmsg_type == SCM_RIGHTS) fd = *(int *)CMSG_DATA(cmsg);
+ }
+#endif /* HAVE_STRUCT_MSGHDR_MSG_ACCRIGHTS */
if (fd != -1) fcntl( fd, F_SETFD, FD_CLOEXEC ); /* in case MSG_CMSG_CLOEXEC is not supported */
return fd;
}
diff --git a/server/request.c b/server/request.c
index 4dd6aea..7c10e6f 100644
--- a/server/request.c
+++ b/server/request.c
@@ -126,23 +126,6 @@ int config_dir_fd = -1; /* file descriptor for the config dir */
static struct master_socket *master_socket; /* the master socket object */
static struct timeout_user *master_timeout;
-/* socket communication static structures */
-static struct iovec myiovec;
-static struct msghdr msghdr;
-#ifndef HAVE_STRUCT_MSGHDR_MSG_ACCRIGHTS
-struct cmsg_fd
-{
- struct
- {
- size_t len; /* size of structure */
- int level; /* SOL_SOCKET */
- int type; /* SCM_RIGHTS */
- } header;
- int fd; /* fd to pass */
-};
-static struct cmsg_fd cmsg = { { sizeof(cmsg.header) + sizeof(cmsg.fd), SOL_SOCKET, SCM_RIGHTS }, -1 };
-#endif /* HAVE_STRUCT_MSGHDR_MSG_ACCRIGHTS */
-
/* complain about a protocol error and terminate the client connection */
void fatal_protocol_error( struct thread *thread, const char *err, ... )
{
@@ -359,25 +342,41 @@ error:
/* receive a file descriptor on the process socket */
int receive_fd( struct process *process )
{
+ struct iovec vec;
struct send_fd data;
- int fd, ret;
+ struct msghdr msghdr;
+ int fd = -1, ret;
#ifdef HAVE_STRUCT_MSGHDR_MSG_ACCRIGHTS
msghdr.msg_accrightslen = sizeof(int);
msghdr.msg_accrights = (void *)&fd;
#else /* HAVE_STRUCT_MSGHDR_MSG_ACCRIGHTS */
- msghdr.msg_control = &cmsg;
- msghdr.msg_controllen = sizeof(cmsg.header) + sizeof(fd);
- cmsg.fd = -1;
+ char cmsg_buffer[256];
+ msghdr.msg_control = cmsg_buffer;
+ msghdr.msg_controllen = sizeof(cmsg_buffer);
+ msghdr.msg_flags = 0;
#endif /* HAVE_STRUCT_MSGHDR_MSG_ACCRIGHTS */
- myiovec.iov_base = (void *)&data;
- myiovec.iov_len = sizeof(data);
+ msghdr.msg_name = NULL;
+ msghdr.msg_namelen = 0;
+ msghdr.msg_iov = &vec;
+ msghdr.msg_iovlen = 1;
+ vec.iov_base = (void *)&data;
+ vec.iov_len = sizeof(data);
ret = recvmsg( get_unix_fd( process->msg_fd ), &msghdr, 0 );
+
#ifndef HAVE_STRUCT_MSGHDR_MSG_ACCRIGHTS
- fd = cmsg.fd;
-#endif
+ if (ret > 0)
+ {
+ struct cmsghdr *cmsg;
+ for (cmsg = CMSG_FIRSTHDR( &msghdr ); cmsg; cmsg = CMSG_NXTHDR( &msghdr, cmsg ))
+ {
+ if (cmsg->cmsg_level != SOL_SOCKET) continue;
+ if (cmsg->cmsg_type == SCM_RIGHTS) fd = *(int *)CMSG_DATA(cmsg);
+ }
+ }
+#endif /* HAVE_STRUCT_MSGHDR_MSG_ACCRIGHTS */
if (ret == sizeof(data))
{
@@ -412,6 +411,7 @@ int receive_fd( struct process *process )
{
fprintf( stderr, "Protocol error: process %04x: partial recvmsg %d for fd\n",
process->id, ret );
+ if (fd != -1) close( fd );
kill_process( process, 1 );
}
else
@@ -429,23 +429,37 @@ int receive_fd( struct process *process )
/* send an fd to a client */
int send_client_fd( struct process *process, int fd, obj_handle_t handle )
{
+ struct iovec vec;
+ struct msghdr msghdr;
int ret;
- if (debug_level)
- fprintf( stderr, "%04x: *fd* %04x -> %d\n",
- current ? current->id : process->id, handle, fd );
-
#ifdef HAVE_STRUCT_MSGHDR_MSG_ACCRIGHTS
msghdr.msg_accrightslen = sizeof(fd);
msghdr.msg_accrights = (void *)&fd;
#else /* HAVE_STRUCT_MSGHDR_MSG_ACCRIGHTS */
- msghdr.msg_control = &cmsg;
- msghdr.msg_controllen = sizeof(cmsg.header) + sizeof(fd);
- cmsg.fd = fd;
+ char cmsg_buffer[256];
+ struct cmsghdr *cmsg;
+ msghdr.msg_control = cmsg_buffer;
+ msghdr.msg_controllen = sizeof(cmsg_buffer);
+ msghdr.msg_flags = 0;
+ cmsg = CMSG_FIRSTHDR( &msghdr );
+ cmsg->cmsg_len = CMSG_LEN( sizeof(fd) );
+ cmsg->cmsg_level = SOL_SOCKET;
+ cmsg->cmsg_type = SCM_RIGHTS;
+ *(int *)CMSG_DATA(cmsg) = fd;
+ msghdr.msg_controllen = cmsg->cmsg_len;
#endif /* HAVE_STRUCT_MSGHDR_MSG_ACCRIGHTS */
- myiovec.iov_base = (void *)&handle;
- myiovec.iov_len = sizeof(handle);
+ msghdr.msg_name = NULL;
+ msghdr.msg_namelen = 0;
+ msghdr.msg_iov = &vec;
+ msghdr.msg_iovlen = 1;
+
+ vec.iov_base = (void *)&handle;
+ vec.iov_len = sizeof(handle);
+
+ if (debug_level)
+ fprintf( stderr, "%04x: *fd* %04x -> %d\n", current ? current->id : process->id, handle, fd );
ret = sendmsg( get_unix_fd( process->msg_fd ), &msghdr, 0 );
@@ -797,12 +811,6 @@ void open_master_socket(void)
acquire_lock();
}
- /* setup msghdr structure constant fields */
- msghdr.msg_name = NULL;
- msghdr.msg_namelen = 0;
- msghdr.msg_iov = &myiovec;
- msghdr.msg_iovlen = 1;
-
/* init the process tracing mechanism */
init_tracing_mechanism();
}
--
1.7.4.2
----------- следующая часть -----------
From dcaf98a2ef6a88ab95e9e088b5de9bdcac3c707e Mon Sep 17 00:00:00 2001
From: Alexandre Julliard <julliard на winehq.org>
Date: Thu, 30 Sep 2010 17:05:13 +0200
Subject: [eter-1.0.12 3/4] ntdll: Add support for retrieving the server pid from the socket credentials.
---
dlls/ntdll/server.c | 20 ++++++++++++++++++++
1 files changed, 20 insertions(+), 0 deletions(-)
diff --git a/dlls/ntdll/server.c b/dlls/ntdll/server.c
index 4cbe790..23cb053 100644
--- a/dlls/ntdll/server.c
+++ b/dlls/ntdll/server.c
@@ -93,6 +93,7 @@ timeout_t server_start_time = 0; /* time of server startup */
sigset_t server_block_set; /* signals to block during server calls */
static int fd_socket = -1; /* socket to exchange file descriptors with the server */
static int terminal_lock;
+static pid_t server_pid;
static RTL_CRITICAL_SECTION fd_cache_section;
static RTL_CRITICAL_SECTION_DEBUG critsect_debug =
@@ -397,6 +398,13 @@ static int receive_fd( obj_handle_t *handle )
{
if (cmsg->cmsg_level != SOL_SOCKET) continue;
if (cmsg->cmsg_type == SCM_RIGHTS) fd = *(int *)CMSG_DATA(cmsg);
+#ifdef SCM_CREDENTIALS
+ else if (cmsg->cmsg_type == SCM_CREDENTIALS)
+ {
+ struct ucred *ucred = (struct ucred *)CMSG_DATA(cmsg);
+ server_pid = ucred->pid;
+ }
+#endif
}
#endif /* HAVE_STRUCT_MSGHDR_MSG_ACCRIGHTS */
if (fd != -1) fcntl( fd, F_SETFD, FD_CLOEXEC ); /* in case MSG_CMSG_CLOEXEC is not supported */
@@ -927,6 +935,7 @@ void server_init_process(void)
obj_handle_t version;
const char *env_socket = getenv( "WINESERVERSOCKET" );
+ server_pid = -1;
if (env_socket)
{
fd_socket = atoi( env_socket );
@@ -948,6 +957,17 @@ void server_init_process(void)
pthread_sigmask( SIG_BLOCK, &server_block_set, NULL );
/* receive the first thread request fd on the main socket */
+#ifdef SO_PASSCRED
+ if (server_pid == -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;
+ 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)
--
1.7.4.2
----------- следующая часть -----------
From 83c334392e76f494fa264d193d8c7920e1007e8e Mon Sep 17 00:00:00 2001
From: Alexandre Julliard <julliard на winehq.org>
Date: Thu, 30 Sep 2010 17:05:35 +0200
Subject: [eter-1.0.12 4/4] ntdll: Add a workaround for Ubuntu's stupid ptrace breakage.
---
dlls/ntdll/server.c | 7 +++++++
1 files changed, 7 insertions(+), 0 deletions(-)
diff --git a/dlls/ntdll/server.c b/dlls/ntdll/server.c
index 23cb053..f1e2eb9 100644
--- a/dlls/ntdll/server.c
+++ b/dlls/ntdll/server.c
@@ -45,6 +45,9 @@
#ifdef HAVE_SYS_MMAN_H
#include <sys/mman.h>
#endif
+#ifdef HAVE_SYS_PRCTL_H
+# include <sys/prctl.h>
+#endif
#ifdef HAVE_SYS_STAT_H
# include <sys/stat.h>
#endif
@@ -980,6 +983,10 @@ void server_init_process(void)
#ifdef __APPLE__
send_server_task_port();
#endif
+#if defined(__linux__) && defined(HAVE_PRCTL)
+ /* work around Ubuntu's ptrace breakage */
+ if (server_pid != -1) prctl( 0x59616d61 /* PR_SET_PTRACER */, server_pid );
+#endif
}
--
1.7.4.2
Подробная информация о списке рассылки Wine-patches