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

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

diff --git a/dlls/advapi32/tests/security.c b/dlls/advapi32/tests/security.c
index 41219087421..5f5c59ed100 100644
--- a/dlls/advapi32/tests/security.c
+++ b/dlls/advapi32/tests/security.c
@@ -1494,7 +1494,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/server.c b/dlls/ntdll/server.c
index 1e84fbf418e..f7aca1b07b0 100644
--- a/dlls/ntdll/server.c
+++ b/dlls/ntdll/server.c
@@ -314,9 +314,18 @@ unsigned int server_call_unlocked( void *req_ptr )
  */
 unsigned int 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 ))
+    {
+        ret = STATUS_ACCESS_VIOLATION;
+        return ret;
+    }
+
     pthread_sigmask( SIG_BLOCK, &server_block_set, &old_set );
     ret = server_call_unlocked( req_ptr );
     pthread_sigmask( SIG_SETMASK, &old_set, NULL );
-- 
2.14.1

