Rebase against b34ea10112227a0d8554c81fc093c0cf6e1bc1b7.

This commit is contained in:
Sebastian Lackner 2017-10-05 03:48:24 +02:00
parent 788e74086e
commit 48c730f761
7 changed files with 9 additions and 405 deletions

View File

@ -1,4 +1,4 @@
From 0d98f9a1ea69511f6bb2901e71c72ac715bffd27 Mon Sep 17 00:00:00 2001
From 6444094c9ef4f30a253bcee9e873ed511bda222c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michael=20M=C3=BCller?= <michael@fds-team.de>
Date: Sat, 5 Aug 2017 01:45:29 +0200
Subject: ntdll: Add function to create new tokens for elevation purposes.
@ -13,12 +13,12 @@ Subject: ntdll: Add function to create new tokens for elevation purposes.
6 files changed, 117 insertions(+)
diff --git a/dlls/ntdll/ntdll.spec b/dlls/ntdll/ntdll.spec
index 30dfa60b1a0..69bfe923234 100644
index c814f405017..eb84cc97bf8 100644
--- a/dlls/ntdll/ntdll.spec
+++ b/dlls/ntdll/ntdll.spec
@@ -1480,6 +1480,9 @@
@ cdecl wine_server_send_fd(long)
@ cdecl __wine_make_process_system()
@@ -1483,6 +1483,9 @@
# Virtual memory
@ cdecl __wine_locked_recvmsg(long ptr long)
+# Token
+@ cdecl __wine_create_default_token(long)
@ -27,7 +27,7 @@ index 30dfa60b1a0..69bfe923234 100644
@ cdecl wine_get_version() NTDLL_wine_get_version
@ cdecl wine_get_patches() NTDLL_wine_get_patches
diff --git a/dlls/ntdll/ntdll_misc.h b/dlls/ntdll/ntdll_misc.h
index c97b1e1f73f..030704e1727 100644
index 907bbdd2d95..a7810f716ad 100644
--- a/dlls/ntdll/ntdll_misc.h
+++ b/dlls/ntdll/ntdll_misc.h
@@ -77,6 +77,9 @@ extern void virtual_init_threading(void) DECLSPEC_HIDDEN;
@ -70,10 +70,10 @@ index f615ce2fea7..77048003ace 100644
#define UNIMPLEMENTED_INFO_CLASS(c) \
diff --git a/server/protocol.def b/server/protocol.def
index b5b2650c8ed..9140feee717 100644
index c8ab4bf8c36..59fe9aec7a8 100644
--- a/server/protocol.def
+++ b/server/protocol.def
@@ -3615,6 +3615,14 @@ struct handle_info
@@ -3628,6 +3628,14 @@ struct handle_info
@END

View File

@ -52,7 +52,7 @@ usage()
# Get the upstream commit sha
upstream_commit()
{
echo "e9c69fde09f0aca171652aaa2e26db2ef075d243"
echo "b34ea10112227a0d8554c81fc093c0cf6e1bc1b7"
}
# Show version information
@ -350,10 +350,8 @@ patch_enable_all ()
enable_server_Signal_Thread="$1"
enable_server_Stored_ACLs="$1"
enable_server_Timestamp_Compat="$1"
enable_server_create_ranges="$1"
enable_server_device_manager_destroy="$1"
enable_server_free_async_queue="$1"
enable_server_open_mapping_file="$1"
enable_server_send_hardware_message="$1"
enable_server_shared_mapping="$1"
enable_setupapi_CM_Get_Parent="$1"
@ -517,7 +515,6 @@ patch_enable_all ()
enable_ws2_32_Tests="$1"
enable_ws2_32_TransmitFile="$1"
enable_ws2_32_WSACleanup="$1"
enable_ws2_32_WriteWatches="$1"
enable_ws2_32_getaddrinfo="$1"
enable_ws2_32_getsockopt="$1"
enable_ws2_32_setsockopt="$1"
@ -1337,18 +1334,12 @@ patch_enable ()
server-Timestamp_Compat)
enable_server_Timestamp_Compat="$2"
;;
server-create_ranges)
enable_server_create_ranges="$2"
;;
server-device_manager_destroy)
enable_server_device_manager_destroy="$2"
;;
server-free_async_queue)
enable_server_free_async_queue="$2"
;;
server-open_mapping_file)
enable_server_open_mapping_file="$2"
;;
server-send_hardware_message)
enable_server_send_hardware_message="$2"
;;
@ -1838,9 +1829,6 @@ patch_enable ()
ws2_32-WSACleanup)
enable_ws2_32_WSACleanup="$2"
;;
ws2_32-WriteWatches)
enable_ws2_32_WriteWatches="$2"
;;
ws2_32-getaddrinfo)
enable_ws2_32_getaddrinfo="$2"
;;
@ -7969,18 +7957,6 @@ if test "$enable_server_Timestamp_Compat" -eq 1; then
) >> "$patchlist"
fi
# Patchset server-create_ranges
# |
# | Modified files:
# | * server/mapping.c
# |
if test "$enable_server_create_ranges" -eq 1; then
patch_apply server-create_ranges/0001-server-Fix-size-of-allocated-ranges-block-Coverity.patch
(
printf '%s\n' '+ { "Sebastian Lackner", "server: Fix size of allocated ranges block (Coverity).", 1 },';
) >> "$patchlist"
fi
# Patchset server-device_manager_destroy
# |
# | Modified files:
@ -8005,21 +7981,6 @@ if test "$enable_server_free_async_queue" -eq 1; then
) >> "$patchlist"
fi
# Patchset server-open_mapping_file
# |
# | This patchset fixes the following Wine bugs:
# | * [#43830] Backport for regression caused by virtual memory management changes
# |
# | Modified files:
# | * server/debugger.c, server/file.h, server/mapping.c
# |
if test "$enable_server_open_mapping_file" -eq 1; then
patch_apply server-open_mapping_file/0001-server-Use-the-correct-process-when-looking-for-a-ma.patch
(
printf '%s\n' '+ { "Alexandre Julliard", "server: Use the correct process when looking for a mapped dll.", 1 },';
) >> "$patchlist"
fi
# Patchset server-send_hardware_message
# |
# | This patchset fixes the following Wine bugs:
@ -10797,18 +10758,6 @@ if test "$enable_ws2_32_WSACleanup" -eq 1; then
) >> "$patchlist"
fi
# Patchset ws2_32-WriteWatches
# |
# | Modified files:
# | * dlls/ntdll/ntdll.spec, dlls/ntdll/virtual.c, dlls/ws2_32/socket.c, dlls/ws2_32/tests/sock.c
# |
if test "$enable_ws2_32_WriteWatches" -eq 1; then
patch_apply ws2_32-WriteWatches/0002-ws2_32-Avoid-race-conditions-of-async-WSARecv-operat.patch
(
printf '%s\n' '+ { "Sebastian Lackner", "ws2_32: Avoid race-conditions of async WSARecv() operations with write watches.", 2 },';
) >> "$patchlist"
fi
# Patchset ws2_32-getaddrinfo
# |
# | Modified files:

View File

@ -1,25 +0,0 @@
From 9a80755fe1afdfabb07a53fb58f858cc0ab3634c Mon Sep 17 00:00:00 2001
From: Sebastian Lackner <sebastian@fds-team.de>
Date: Sat, 30 Sep 2017 16:25:21 +0200
Subject: server: Fix size of allocated ranges block (Coverity).
---
server/mapping.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/server/mapping.c b/server/mapping.c
index 8459c316559..22cd5c2064d 100644
--- a/server/mapping.c
+++ b/server/mapping.c
@@ -682,7 +682,7 @@ static struct ranges *create_ranges(void)
if (!ranges) return NULL;
ranges->count = 0;
ranges->max = 8;
- if (!(ranges->ranges = mem_alloc( ranges->max * sizeof(ranges->ranges) )))
+ if (!(ranges->ranges = mem_alloc( ranges->max * sizeof(*ranges->ranges) )))
{
release_object( ranges );
return NULL;
--
2.14.1

View File

@ -1,111 +0,0 @@
From ec824c32fee6c70d993cb245fc8a9f72e54a06ec Mon Sep 17 00:00:00 2001
From: Alexandre Julliard <julliard@winehq.org>
Date: Tue, 3 Oct 2017 11:59:20 +0200
Subject: server: Use the correct process when looking for a mapped dll.
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
---
server/debugger.c | 18 ++++++++++++++----
server/file.h | 4 ++--
server/mapping.c | 15 +++++----------
3 files changed, 21 insertions(+), 16 deletions(-)
diff --git a/server/debugger.c b/server/debugger.c
index 4d4f0035c2f..d658fc0625f 100644
--- a/server/debugger.c
+++ b/server/debugger.c
@@ -149,6 +149,7 @@ static int fill_create_process_event( struct debug_event *event, const void *arg
struct process *process = thread->process;
struct process_dll *exe_module = get_process_exe_module( process );
const client_ptr_t *entry = arg;
+ struct file *file;
obj_handle_t handle;
/* documented: PROCESS_VM_READ | PROCESS_VM_WRITE */
@@ -172,8 +173,12 @@ static int fill_create_process_event( struct debug_event *event, const void *arg
event->data.create_process.unicode = 1;
/* the doc says write access too, but this doesn't seem a good idea */
- event->data.create_process.file = open_mapping_file( debugger, exe_module->base, GENERIC_READ,
- FILE_SHARE_READ | FILE_SHARE_WRITE );
+ if ((file = get_mapping_file( process, exe_module->base, GENERIC_READ,
+ FILE_SHARE_READ | FILE_SHARE_WRITE )))
+ {
+ event->data.create_process.file = alloc_handle( debugger, file, GENERIC_READ, 0 );
+ release_object( file );
+ }
return 1;
}
@@ -193,8 +198,10 @@ static int fill_exit_process_event( struct debug_event *event, const void *arg )
static int fill_load_dll_event( struct debug_event *event, const void *arg )
{
+ struct process *process = event->sender->process;
struct process *debugger = event->debugger->process;
const struct process_dll *dll = arg;
+ struct file *file;
event->data.load_dll.handle = 0;
event->data.load_dll.base = dll->base;
@@ -202,8 +209,11 @@ static int fill_load_dll_event( struct debug_event *event, const void *arg )
event->data.load_dll.dbg_size = dll->dbg_size;
event->data.load_dll.name = dll->name;
event->data.load_dll.unicode = 1;
- event->data.load_dll.handle = open_mapping_file( debugger, dll->base, GENERIC_READ,
- FILE_SHARE_READ | FILE_SHARE_WRITE );
+ if ((file = get_mapping_file( process, dll->base, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE )))
+ {
+ event->data.load_dll.handle = alloc_handle( debugger, file, GENERIC_READ, 0 );
+ release_object( file );
+ }
return 1;
}
diff --git a/server/file.h b/server/file.h
index 27c5d198e81..17bfdda9990 100644
--- a/server/file.h
+++ b/server/file.h
@@ -150,8 +150,8 @@ extern struct security_descriptor *get_file_sd( struct object *obj, struct fd *f
extern struct mapping *get_mapping_obj( struct process *process, obj_handle_t handle,
unsigned int access );
-extern obj_handle_t open_mapping_file( struct process *process, client_ptr_t base,
- unsigned int access, unsigned int sharing );
+extern struct file *get_mapping_file( struct process *process, client_ptr_t base,
+ unsigned int access, unsigned int sharing );
extern void free_mapped_views( struct process *process );
extern int get_page_size(void);
diff --git a/server/mapping.c b/server/mapping.c
index 22cd5c2064d..5db03f8861a 100644
--- a/server/mapping.c
+++ b/server/mapping.c
@@ -815,19 +815,14 @@ struct mapping *get_mapping_obj( struct process *process, obj_handle_t handle, u
return (struct mapping *)get_handle_obj( process, handle, access, &mapping_ops );
}
-/* open a new file handle to the file backing the mapping */
-obj_handle_t open_mapping_file( struct process *process, client_ptr_t base,
- unsigned int access, unsigned int sharing )
+/* open a new file for the file descriptor backing the mapping */
+struct file *get_mapping_file( struct process *process, client_ptr_t base,
+ unsigned int access, unsigned int sharing )
{
- obj_handle_t handle;
struct memory_view *view = find_mapped_view( process, base );
- struct file *file;
- if (!view || !view->fd) return 0;
- if (!(file = create_file_for_fd_obj( view->fd, access, sharing ))) return 0;
- handle = alloc_handle( process, file, access, 0 );
- release_object( file );
- return handle;
+ if (!view || !view->fd) return NULL;
+ return create_file_for_fd_obj( view->fd, access, sharing );
}
static void mapping_dump( struct object *obj, int verbose )
--
2.14.1

View File

@ -1 +0,0 @@
Fixes: [43830] Backport for regression caused by virtual memory management changes

View File

@ -1,205 +0,0 @@
From cab68a82435dfc0cd55f65dca6febae250681f14 Mon Sep 17 00:00:00 2001
From: Sebastian Lackner <sebastian@fds-team.de>
Date: Fri, 21 Nov 2014 12:22:46 +0100
Subject: ws2_32: Avoid race-conditions of async WSARecv() operations with
write watches. (try 2)
Under specific circumstances Silverlight resets the write watch while the async
WSARecv() operation is still pending:
23723.867:003a:Call ws2_32.WSARecv(00000400,018eac80,00000001,0815df24,0815df28,0196132c,00000000) ret=7a3a8197
[...]
23723.868:003a:Call KERNEL32.IsBadWritePtr(028f3368,00015554) ret=205465c4
23723.868:003a:Ret KERNEL32.IsBadWritePtr() retval=00000000 ret=205465c4
[...]
23723.868:003a:Ret ws2_32.WSARecv() retval=ffffffff ret=7a3a8197
23723.868:003a:Call KERNEL32.GetLastError() ret=792be2fd
23723.868:003a:Ret KERNEL32.GetLastError() retval=00000102 ret=79259875
[...]
23723.874:003d:Call KERNEL32.ResetWriteWatch(028d1000,0009ce00) ret=792ca021
23723.875:003d:Ret KERNEL32.ResetWriteWatch() retval=00000000 ret=792ca021
[...]
23723.966:003a:Call ntdll.wine_server_handle_to_fd(00000400,00000001,0815de9c,00000000) ret=2053ec7c
23723.966:003a:Ret ntdll.wine_server_handle_to_fd() retval=00000000 ret=2053ec7c
23723.966:003a:Call ntdll.wine_server_release_fd(00000400,00000081) ret=2053eca4
23723.966:003a:Ret ntdll.wine_server_release_fd() retval=00000000 ret=2053eca4
23723.966:003a:warn:winsock:wsaErrStatus errno 14, (Bad address).
This seems to work fine on Windows, most likely because the kernel handles write
watches directly, without involving usermode. To workaround this issue we repeat
recvmsg(...) when it looks like it might have failed because of write watches.
Based on the Linux kernel code it seems to be save to assume, that on EFAULT
no actually important data was lost:
http://lxr.free-electrons.com/source/net/ipv4/tcp.c#L1940
Based on the code it looks like we could savely remove the write-watch check
at the beginning of WS2_recv_base, which might make the application think
that data is immediately available.
---
dlls/ntdll/ntdll.spec | 3 +++
dlls/ntdll/virtual.c | 45 +++++++++++++++++++++++++++++++++++++++++++++
dlls/ws2_32/socket.c | 4 +++-
dlls/ws2_32/tests/sock.c | 11 +++--------
4 files changed, 54 insertions(+), 9 deletions(-)
diff --git a/dlls/ntdll/ntdll.spec b/dlls/ntdll/ntdll.spec
index 68d7f22b192..b4acd5e6feb 100644
--- a/dlls/ntdll/ntdll.spec
+++ b/dlls/ntdll/ntdll.spec
@@ -1491,6 +1491,9 @@
# signal handling
@ cdecl __wine_set_signal_handler(long ptr)
+# Virtal memory management
+@ cdecl wine_virtual_locked_recvmsg(long ptr long)
+
# Filesystem
@ cdecl wine_nt_to_unix_file_name(ptr ptr long long)
@ cdecl wine_unix_to_nt_file_name(ptr ptr)
diff --git a/dlls/ntdll/virtual.c b/dlls/ntdll/virtual.c
index 2cdcca8a599..7e22a8a9bcf 100644
--- a/dlls/ntdll/virtual.c
+++ b/dlls/ntdll/virtual.c
@@ -41,6 +41,9 @@
#ifdef HAVE_SYS_SYSINFO_H
# include <sys/sysinfo.h>
#endif
+#ifdef HAVE_SYS_SOCKET_H
+# include <sys/socket.h>
+#endif
#ifdef HAVE_VALGRIND_VALGRIND_H
# include <valgrind/valgrind.h>
#endif
@@ -1913,6 +1916,48 @@ ssize_t virtual_locked_pread( int fd, void *addr, size_t size, off_t offset )
}
+/***********************************************************************
+ * virtual_locked_recvmsg
+ */
+ssize_t CDECL wine_virtual_locked_recvmsg( int sockfd, struct msghdr *msg, int flags )
+{
+ sigset_t sigset;
+ BOOL has_write_watch = FALSE;
+ int err = EFAULT;
+ int i;
+
+ ssize_t size, ret = recvmsg( sockfd, msg, flags );
+ if (ret != -1 || errno != EFAULT) return ret;
+
+ server_enter_uninterrupted_section( &csVirtual, &sigset );
+
+ for (i = 0; i < msg->msg_iovlen; i++)
+ {
+ struct iovec *iov = &msg->msg_iov[i];
+ if (check_write_access( iov->iov_base, iov->iov_len, &has_write_watch ))
+ {
+ while (i--) update_write_watches( msg->msg_iov[i].iov_base, msg->msg_iov[i].iov_len, 0 );
+ goto done;
+ }
+ }
+
+ size = ret = recvmsg( sockfd, msg, flags );
+ err = errno;
+
+ if (!has_write_watch) goto done;
+ for (i = 0; i < msg->msg_iovlen; i++)
+ {
+ struct iovec *iov = &msg->msg_iov[i];
+ update_write_watches( iov->iov_base, iov->iov_len, min( max( 0, size ), iov->iov_len ));
+ size -= iov->iov_len;
+ }
+
+done:
+ server_leave_uninterrupted_section( &csVirtual, &sigset );
+ errno = err;
+ return ret;
+}
+
/***********************************************************************
* virtual_is_valid_code_address
diff --git a/dlls/ws2_32/socket.c b/dlls/ws2_32/socket.c
index 681f340bc6d..e97b8ebfe69 100644
--- a/dlls/ws2_32/socket.c
+++ b/dlls/ws2_32/socket.c
@@ -263,6 +263,8 @@ static int WS2_recv_base( SOCKET s, LPWSABUF lpBuffers, DWORD dwBufferCount,
LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine,
LPWSABUF lpControlBuffer );
+extern ssize_t CDECL wine_virtual_locked_recvmsg( int sockfd, struct msghdr *msg, int flags );
+
/* critical section to protect some non-reentrant net function */
static CRITICAL_SECTION csWSgetXXXbyYYY;
static CRITICAL_SECTION_DEBUG critsect_debug =
@@ -2356,7 +2358,7 @@ static int WS2_recv( int fd, struct ws2_async *wsa, int flags )
hdr.msg_flags = 0;
#endif
- while ((n = recvmsg(fd, &hdr, flags)) == -1)
+ while ((n = wine_virtual_locked_recvmsg(fd, &hdr, flags)) == -1)
{
if (errno != EINTR)
return -1;
diff --git a/dlls/ws2_32/tests/sock.c b/dlls/ws2_32/tests/sock.c
index 7b0cc322dad..12b90e979f9 100644
--- a/dlls/ws2_32/tests/sock.c
+++ b/dlls/ws2_32/tests/sock.c
@@ -6963,18 +6963,15 @@ static void test_write_watch(void)
send(src, "test message", sizeof("test message"), 0);
ret = GetOverlappedResult( (HANDLE)dest, &ov, &bytesReturned, TRUE );
- todo_wine
- {
ok( ret, "GetOverlappedResult failed %u\n", GetLastError() );
ok( bytesReturned == sizeof("test message"), "wrong size %u\n", bytesReturned );
ok( !memcmp( base, "test ", 5 ), "wrong data %s\n", base );
ok( !memcmp( base + 0x4000, "message", 8 ), "wrong data %s\n", base + 0x4000 );
- }
count = 64;
ret = pGetWriteWatch( WRITE_WATCH_FLAG_RESET, base, size, results, &count, &pagesize );
ok( !ret, "GetWriteWatch failed %u\n", GetLastError() );
- ok( count == 0, "wrong count %lu\n", count );
+ todo_wine ok( count == 0, "wrong count %lu\n", count );
memset( base, 0, size );
count = 64;
@@ -6985,7 +6982,6 @@ static void test_write_watch(void)
bufs[1].len = 0x4000;
bufs[1].buf = base + 0x2000;
ret = WSARecvFrom( dest, bufs, 2, NULL, &flags, &addr, &addr_len, &ov, NULL);
- todo_wine
ok(ret == SOCKET_ERROR && GetLastError() == ERROR_IO_PENDING,
"WSARecv failed - %d error %d\n", ret, GetLastError());
@@ -6993,7 +6989,6 @@ static void test_write_watch(void)
ret = pGetWriteWatch( WRITE_WATCH_FLAG_RESET, base, size, results, &count, &pagesize );
ok( !ret, "GetWriteWatch failed %u\n", GetLastError() );
ok( count == 5, "wrong count %lu\n", count );
- todo_wine
ok( !base[0], "data set\n" );
send(src, "test message", sizeof("test message"), 0);
@@ -7007,7 +7002,7 @@ static void test_write_watch(void)
count = 64;
ret = pGetWriteWatch( WRITE_WATCH_FLAG_RESET, base, size, results, &count, &pagesize );
ok( !ret, "GetWriteWatch failed %u\n", GetLastError() );
- ok( count == 0, "wrong count %lu\n", count );
+ todo_wine ok( count == 0, "wrong count %lu\n", count );
memset( base, 0, size );
count = 64;
@@ -7036,7 +7031,7 @@ static void test_write_watch(void)
count = 64;
ret = pGetWriteWatch( WRITE_WATCH_FLAG_RESET, base, size, results, &count, &pagesize );
ok( !ret, "GetWriteWatch failed %u\n", GetLastError() );
- ok( count == 0, "wrong count %lu\n", count );
+ todo_wine ok( count == 0, "wrong count %lu\n", count );
}
WSACloseEvent( event );
closesocket( dest );
--
2.14.1

View File

@ -1,3 +0,0 @@
Fixes: Avoid race-conditions of async WSARecv() operations with write watches.
Fixes: Avoid race-conditions with write watches in WS2_async_accept.
Fixes: Basic handling of write watches triggered while we're on the signal stack.