Added patch to fix wineserver crash when pipe server object is destroyed before client (fixes Wine Staging Bug #393).

This commit is contained in:
Sebastian Lackner 2015-06-17 13:52:46 +02:00
parent 0bef3b01c4
commit 31bd06cb42
3 changed files with 124 additions and 0 deletions

2
debian/changelog vendored
View File

@ -3,6 +3,8 @@ wine-staging (1.7.46) UNRELEASED; urgency=low
* Added patch to improve IoGetDeviceObjectPointer stub to appease SecuROM 5.x.
* Added patch to globally invalidate key state on changes in other threads.
* Added patch to fix possible use-after-free in wineserver device IPR code.
* Added patch to fix wineserver crash when pipe server object is destroyed
before client (fixes Wine Staging Bug #393).
* Removed patch for implementation of GdipCreateRegionRgnData (accepted
upstream).
* Removed patch to fix output buffer size for IOCTL_DVD_READ_STRUCTURE

View File

@ -0,0 +1,120 @@
From b2a17b581c4d8452a605b494f8ff7884fcb3a481 Mon Sep 17 00:00:00 2001
From: Sebastian Lackner <sebastian@fds-team.de>
Date: Wed, 17 Jun 2015 13:50:59 +0200
Subject: server: Fix wineserver crash when pipe server object is destroyed
before client.
---
dlls/kernel32/tests/pipe.c | 35 +++++++++++++++++++++++++++++++++++
server/named_pipe.c | 14 ++++++++++++--
2 files changed, 47 insertions(+), 2 deletions(-)
diff --git a/dlls/kernel32/tests/pipe.c b/dlls/kernel32/tests/pipe.c
index ddad351..06242aa 100644
--- a/dlls/kernel32/tests/pipe.c
+++ b/dlls/kernel32/tests/pipe.c
@@ -1162,6 +1162,8 @@ static void test_CloseNamedPipe(void)
char ibuf[32];
DWORD written;
DWORD readden;
+ DWORD state;
+ BOOL ret;
hnp = CreateNamedPipeA(PIPENAME, PIPE_ACCESS_DUPLEX,
PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT,
@@ -1196,6 +1198,14 @@ static void test_CloseNamedPipe(void)
ok(readden == sizeof(obuf), "got %d bytes\n", readden);
/* pipe is empty now */
+ ret = GetNamedPipeHandleStateA(hFile, &state, NULL, NULL, NULL, NULL, 0);
+ todo_wine
+ ok(ret, "GetNamedPipeHandleState failed with %d\n", GetLastError());
+ state = PIPE_READMODE_MESSAGE | PIPE_WAIT;
+ ret = SetNamedPipeHandleState(hFile, &state, NULL, NULL);
+ todo_wine
+ ok(ret, "SetNamedPipeHandleState failed with %d\n", GetLastError());
+
SetLastError(0xdeadbeef);
ok(!ReadFile(hFile, ibuf, 0, &readden, NULL), "ReadFile() succeeded\n");
ok(GetLastError() == ERROR_BROKEN_PIPE, "GetLastError() returned %08x, expected ERROR_BROKEN_PIPE\n", GetLastError());
@@ -1233,6 +1243,14 @@ static void test_CloseNamedPipe(void)
ok(readden == 0, "got %d bytes\n", readden);
/* pipe is empty now */
+ ret = GetNamedPipeHandleStateA(hFile, &state, NULL, NULL, NULL, NULL, 0);
+ todo_wine
+ ok(ret, "GetNamedPipeHandleState failed with %d\n", GetLastError());
+ state = PIPE_READMODE_MESSAGE | PIPE_WAIT;
+ ret = SetNamedPipeHandleState(hFile, &state, NULL, NULL);
+ todo_wine
+ ok(ret, "SetNamedPipeHandleState failed with %d\n", GetLastError());
+
SetLastError(0xdeadbeef);
ok(!ReadFile(hFile, ibuf, sizeof(ibuf), &readden, NULL), "ReadFile() succeeded\n");
ok(GetLastError() == ERROR_BROKEN_PIPE, "GetLastError() returned %08x, expected ERROR_BROKEN_PIPE\n", GetLastError());
@@ -1277,6 +1295,14 @@ static void test_CloseNamedPipe(void)
ok(readden == sizeof(obuf), "got %d bytes\n", readden);
/* pipe is empty now */
+ ret = GetNamedPipeHandleStateA(hnp, &state, NULL, NULL, NULL, NULL, 0);
+ ok(ret, "GetNamedPipeHandleState failed with %d\n", GetLastError());
+ SetLastError(0xdeadbeef);
+ state = PIPE_READMODE_MESSAGE | PIPE_WAIT;
+ ret = SetNamedPipeHandleState(hFile, &state, NULL, NULL);
+ ok(!ret, "SetNamedPipeHandleState unexpectedly succeeded\n");
+ ok(GetLastError() == ERROR_INVALID_HANDLE, "GetLastError() returned %08x, expected ERROR_INVALID_HANDLE\n", GetLastError());
+
SetLastError(0xdeadbeef);
ok(!ReadFile(hnp, ibuf, 0, &readden, NULL), "ReadFile() succeeded\n");
ok(GetLastError() == ERROR_BROKEN_PIPE, "GetLastError() returned %08x, expected ERROR_BROKEN_PIPE\n", GetLastError());
@@ -1314,6 +1340,15 @@ static void test_CloseNamedPipe(void)
ok(readden == 0, "got %d bytes\n", readden);
/* pipe is empty now */
+ ret = GetNamedPipeHandleStateA(hnp, &state, NULL, NULL, NULL, NULL, 0);
+ ok(ret, "GetNamedPipeHandleState failed with %d\n", GetLastError());
+ ret = SetNamedPipeHandleState(hFile, &state, NULL, NULL);
+ SetLastError(0xdeadbeef);
+ state = PIPE_READMODE_MESSAGE | PIPE_WAIT;
+ ret = SetNamedPipeHandleState(hFile, &state, NULL, NULL);
+ ok(!ret, "SetNamedPipeHandleState unexpectedly succeeded\n");
+ ok(GetLastError() == ERROR_INVALID_HANDLE, "GetLastError() returned %08x, expected ERROR_INVALID_HANDLE\n", GetLastError());
+
SetLastError(0xdeadbeef);
ok(!ReadFile(hnp, ibuf, sizeof(ibuf), &readden, NULL), "ReadFile() succeeded\n");
ok(GetLastError() == ERROR_BROKEN_PIPE, "GetLastError() returned %08x, expected ERROR_BROKEN_PIPE\n", GetLastError());
diff --git a/server/named_pipe.c b/server/named_pipe.c
index 4718d1b..53bec02 100644
--- a/server/named_pipe.c
+++ b/server/named_pipe.c
@@ -1105,7 +1105,12 @@ DECL_HANDLER(get_named_pipe_info)
client = (struct pipe_client *)get_handle_obj( current->process, req->handle,
0, &pipe_client_ops );
if (!client) return;
- server = client->server;
+ if (!(server = client->server))
+ {
+ release_object( client );
+ set_error( STATUS_INVALID_HANDLE );
+ return;
+ }
}
reply->flags = client ? client->pipe_flags : server->pipe_flags;
@@ -1142,7 +1147,12 @@ DECL_HANDLER(set_named_pipe_info)
client = (struct pipe_client *)get_handle_obj( current->process, req->handle,
0, &pipe_client_ops );
if (!client) return;
- server = client->server;
+ if (!(server = client->server))
+ {
+ release_object( client );
+ set_error( STATUS_INVALID_HANDLE );
+ return;
+ }
}
if ((req->flags & ~(NAMED_PIPE_MESSAGE_STREAM_READ | NAMED_PIPE_NONBLOCKING_MODE)) ||
--
2.4.3

View File

@ -3147,6 +3147,7 @@ if test "$enable_kernel32_Named_Pipe" -eq 1; then
patch_apply kernel32-Named_Pipe/0020-kernel32-tests-Add-tests-for-behaviour-of-WriteFile-.patch
patch_apply kernel32-Named_Pipe/0021-server-Return-correct-error-codes-for-NtWriteFile-wh.patch
patch_apply kernel32-Named_Pipe/0022-ntdll-Pre-cache-file-descriptors-after-opening-a-fil.patch
patch_apply kernel32-Named_Pipe/0023-server-Fix-wineserver-crash-when-pipe-server-object-.patch
(
echo '+ { "Dan Kegel", "kernel32: ConnectNamedPort should return FALSE and set ERROR_PIPE_CONNECTED on success in overlapped mode.", 1 },';
echo '+ { "Sebastian Lackner", "kernel32/tests: Add tests for PeekNamedPipe with partial received messages.", 1 },';
@ -3170,6 +3171,7 @@ if test "$enable_kernel32_Named_Pipe" -eq 1; then
echo '+ { "Sebastian Lackner", "kernel32/tests: Add tests for behaviour of WriteFile on closed pipe.", 1 },';
echo '+ { "Sebastian Lackner", "server: Return correct error codes for NtWriteFile when pipes are closed without disconnecting.", 1 },';
echo '+ { "Sebastian Lackner", "ntdll: Pre-cache file descriptors after opening a file.", 1 },';
echo '+ { "Sebastian Lackner", "server: Fix wineserver crash when pipe server object is destroyed before client.", 1 },';
) >> "$patchlist"
fi