From 967a59e4a02f5aa9a607e52b3cbc91a0d268c064 Mon Sep 17 00:00:00 2001
From: Sebastian Lackner <sebastian@fds-team.de>
Date: Sat, 4 Oct 2014 02:35:44 +0200
Subject: [PATCH] ntdll: Trigger write watches before passing userdata pointer
 to wait_reply.

---
 dlls/advapi32/tests/security.c | 1 -
 dlls/ntdll/unix/server.c       | 8 ++++++++
 2 files changed, 8 insertions(+), 1 deletion(-)

diff --git a/dlls/advapi32/tests/security.c b/dlls/advapi32/tests/security.c
index ab572421a735..01f7a8783b18 100644
--- a/dlls/advapi32/tests/security.c
+++ b/dlls/advapi32/tests/security.c
@@ -1557,7 +1557,6 @@ todo_wine
        "failed with ERROR_INSUFFICIENT_BUFFER, instead of %d\n", err);
 todo_wine
     ok(PrivSetLen == sizeof(PRIVILEGE_SET), "PrivSetLen returns %d\n", PrivSetLen);
-todo_wine
     ok(Access == 0x1abe11ed && AccessStatus == 0x1abe11ed,
        "Access and/or AccessStatus were changed!\n");
 
diff --git a/dlls/ntdll/unix/server.c b/dlls/ntdll/unix/server.c
index 452094ff5dc0..3c0d29a00624 100644
--- a/dlls/ntdll/unix/server.c
+++ b/dlls/ntdll/unix/server.c
@@ -282,9 +282,17 @@ unsigned int server_call_unlocked( void *req_ptr )
  */
 unsigned int CDECL wine_server_call( void *req_ptr )
 {
+    struct __server_request_info * const req = req_ptr;
     sigset_t old_set;
     unsigned int ret;
 
+    /* trigger write watches, otherwise read() might return EFAULT */
+    if (req->u.req.request_header.reply_size &&
+        !virtual_check_buffer_for_write( req->reply_data, req->u.req.request_header.reply_size ))
+    {
+        return STATUS_ACCESS_VIOLATION;
+    }
+
     pthread_sigmask( SIG_BLOCK, &server_block_set, &old_set );
     ret = server_call_unlocked( req_ptr );
     pthread_sigmask( SIG_SETMASK, &old_set, NULL );
-- 
2.20.1

