Alexandre Julliard : server: Add some validation of clipboard window handles.
Alexandre Julliard
julliard at winehq.org
Mon Aug 29 11:07:23 CDT 2016
Module: wine
Branch: master
Commit: 19d16a7cb1af82f0515afb10033d56d8ec7856d7
URL: http://source.winehq.org/git/wine.git/?a=commit;h=19d16a7cb1af82f0515afb10033d56d8ec7856d7
Author: Alexandre Julliard <julliard at winehq.org>
Date: Mon Aug 29 20:33:22 2016 +0900
server: Add some validation of clipboard window handles.
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
dlls/user32/clipboard.c | 2 +-
dlls/user32/tests/clipboard.c | 49 ++++++++++++++++++++++++++++++++++++++++++-
server/clipboard.c | 27 +++++++++++++++++++-----
server/trace.c | 1 +
4 files changed, 72 insertions(+), 7 deletions(-)
diff --git a/dlls/user32/clipboard.c b/dlls/user32/clipboard.c
index 6d62dfd..fb10d27 100644
--- a/dlls/user32/clipboard.c
+++ b/dlls/user32/clipboard.c
@@ -147,7 +147,7 @@ BOOL WINAPI OpenClipboard( HWND hwnd )
SERVER_START_REQ( open_clipboard )
{
req->window = wine_server_user_handle( hwnd );
- if ((ret = !wine_server_call( req )))
+ if ((ret = !wine_server_call_err( req )))
{
if (!reply->owner) bCBHasChanged = FALSE;
}
diff --git a/dlls/user32/tests/clipboard.c b/dlls/user32/tests/clipboard.c
index f01af3d..b9b926d 100644
--- a/dlls/user32/tests/clipboard.c
+++ b/dlls/user32/tests/clipboard.c
@@ -26,6 +26,7 @@
#include "winuser.h"
static BOOL (WINAPI *pAddClipboardFormatListener)(HWND hwnd);
+static BOOL (WINAPI *pRemoveClipboardFormatListener)(HWND hwnd);
static DWORD (WINAPI *pGetClipboardSequenceNumber)(void);
static const BOOL is_win64 = sizeof(void *) > sizeof(int);
@@ -565,7 +566,7 @@ static LRESULT CALLBACK clipboard_wnd_proc(HWND hwnd, UINT msg, WPARAM wp, LPARA
static DWORD WINAPI clipboard_thread(void *param)
{
- HWND win = param;
+ HWND ret, win = param;
BOOL r;
HANDLE handle;
UINT count, formats, old_seq = 0, seq;
@@ -577,10 +578,36 @@ static DWORD WINAPI clipboard_thread(void *param)
next_wnd = SetClipboardViewer(win);
ok(GetLastError() == 0xdeadbeef, "GetLastError = %d\n", GetLastError());
LeaveCriticalSection(&clipboard_cs);
+
+ SetLastError( 0xdeadbeef );
+ ret = SetClipboardViewer( (HWND)0xdead );
+ ok( !ret, "SetClipboardViewer succeeded\n" );
+ ok( GetLastError() == ERROR_INVALID_WINDOW_HANDLE, "wrong error %u\n", GetLastError() );
+ SetLastError( 0xdeadbeef );
+ r = ChangeClipboardChain( win, (HWND)0xdead );
+ ok( !r, "ChangeClipboardChain succeeded\n" );
+ ok( GetLastError() == ERROR_INVALID_WINDOW_HANDLE, "wrong error %u\n", GetLastError() );
+ SetLastError( 0xdeadbeef );
+ r = ChangeClipboardChain( (HWND)0xdead, next_wnd );
+ ok( !r, "ChangeClipboardChain succeeded\n" );
+ ok( GetLastError() == ERROR_INVALID_WINDOW_HANDLE, "wrong error %u\n", GetLastError() );
+
if (pAddClipboardFormatListener)
{
r = pAddClipboardFormatListener(win);
ok( r, "AddClipboardFormatListener failed err %d\n", GetLastError());
+ SetLastError( 0xdeadbeef );
+ r = pAddClipboardFormatListener( win );
+ todo_wine ok( !r, "AddClipboardFormatListener succeeded\n" );
+ todo_wine ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
+ SetLastError( 0xdeadbeef );
+ r = pAddClipboardFormatListener( (HWND)0xdead );
+ todo_wine ok( !r, "AddClipboardFormatListener succeeded\n" );
+ todo_wine ok( GetLastError() == ERROR_INVALID_WINDOW_HANDLE, "wrong error %u\n", GetLastError() );
+ r = pAddClipboardFormatListener( GetDesktopWindow() );
+ ok( r, "AddClipboardFormatListener failed err %d\n", GetLastError());
+ r = pRemoveClipboardFormatListener( GetDesktopWindow() );
+ ok( r, "RemoveClipboardFormatListener failed err %d\n", GetLastError());
}
if (pGetClipboardSequenceNumber)
@@ -593,6 +620,11 @@ static DWORD WINAPI clipboard_thread(void *param)
count = SendMessageA( win, WM_USER+2, 0, 0 );
ok( !count, "WM_CLIPBOARDUPDATE received\n" );
+ SetLastError( 0xdeadbeef );
+ r = OpenClipboard( (HWND)0xdead );
+ ok( !r, "OpenClipboard succeeded\n" );
+ ok( GetLastError() == ERROR_INVALID_WINDOW_HANDLE, "wrong error %u\n", GetLastError() );
+
r = OpenClipboard(win);
ok(r, "OpenClipboard failed: %d\n", GetLastError());
@@ -887,6 +919,20 @@ static DWORD WINAPI clipboard_thread(void *param)
r = PostMessageA(win, WM_USER, 0, 0);
ok(r, "PostMessage failed: %d\n", GetLastError());
+
+ if (pRemoveClipboardFormatListener)
+ {
+ r = pRemoveClipboardFormatListener(win);
+ ok( r, "RemoveClipboardFormatListener failed err %d\n", GetLastError());
+ SetLastError( 0xdeadbeef );
+ r = pRemoveClipboardFormatListener(win);
+ todo_wine ok( !r, "RemoveClipboardFormatListener succeeded\n" );
+ todo_wine ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
+ SetLastError( 0xdeadbeef );
+ r = pRemoveClipboardFormatListener( (HWND)0xdead );
+ todo_wine ok( !r, "RemoveClipboardFormatListener succeeded\n" );
+ todo_wine ok( GetLastError() == ERROR_INVALID_WINDOW_HANDLE, "wrong error %u\n", GetLastError() );
+ }
return 0;
}
@@ -1238,6 +1284,7 @@ START_TEST(clipboard)
argv0 = argv[0];
pAddClipboardFormatListener = (void *)GetProcAddress( mod, "AddClipboardFormatListener" );
+ pRemoveClipboardFormatListener = (void *)GetProcAddress( mod, "RemoveClipboardFormatListener" );
pGetClipboardSequenceNumber = (void *)GetProcAddress( mod, "GetClipboardSequenceNumber" );
if (argc == 4 && !strcmp( argv[2], "set_clipboard_data" ))
diff --git a/server/clipboard.c b/server/clipboard.c
index 98df230..a1535b6 100644
--- a/server/clipboard.c
+++ b/server/clipboard.c
@@ -185,14 +185,18 @@ static int get_seqno( struct clipboard *clipboard )
DECL_HANDLER(open_clipboard)
{
struct clipboard *clipboard = get_process_clipboard();
- user_handle_t win;
+ user_handle_t win = req->window;
if (!clipboard) return;
- win = get_user_full_handle( req->window );
+ if (win && !get_user_object_handle( &win, USER_WINDOW ))
+ {
+ set_win32_error( ERROR_INVALID_WINDOW_HANDLE );
+ return;
+ }
if (clipboard->open_thread && clipboard->open_win != win)
{
- set_error( STATUS_WAS_LOCKED );
+ set_error( STATUS_INVALID_LOCK_SEQUENCE );
return;
}
clipboard->open_win = win;
@@ -286,14 +290,27 @@ DECL_HANDLER(get_clipboard_info)
DECL_HANDLER(set_clipboard_viewer)
{
struct clipboard *clipboard = get_process_clipboard();
+ user_handle_t viewer = req->viewer;
+ user_handle_t previous = req->previous;
if (!clipboard) return;
+ if (viewer && !get_user_object_handle( &viewer, USER_WINDOW ))
+ {
+ set_win32_error( ERROR_INVALID_WINDOW_HANDLE );
+ return;
+ }
+ if (previous && !get_user_object_handle( &previous, USER_WINDOW ))
+ {
+ set_win32_error( ERROR_INVALID_WINDOW_HANDLE );
+ return;
+ }
+
reply->old_viewer = clipboard->viewer;
reply->owner = clipboard->owner_win;
- if (!req->previous || clipboard->viewer == get_user_full_handle( req->previous ))
- clipboard->viewer = get_user_full_handle( req->viewer );
+ if (!previous || clipboard->viewer == previous)
+ clipboard->viewer = viewer;
else
set_error( STATUS_PENDING ); /* need to send message instead */
}
diff --git a/server/trace.c b/server/trace.c
index 6c9518e..0e8a9e8 100644
--- a/server/trace.c
+++ b/server/trace.c
@@ -5307,6 +5307,7 @@ static const struct
{ "INVALID_IMAGE_NOT_MZ", STATUS_INVALID_IMAGE_NOT_MZ },
{ "INVALID_IMAGE_PROTECT", STATUS_INVALID_IMAGE_PROTECT },
{ "INVALID_IMAGE_WIN_64", STATUS_INVALID_IMAGE_WIN_64 },
+ { "INVALID_LOCK_SEQUENCE", STATUS_INVALID_LOCK_SEQUENCE },
{ "INVALID_PARAMETER", STATUS_INVALID_PARAMETER },
{ "INVALID_SECURITY_DESCR", STATUS_INVALID_SECURITY_DESCR },
{ "IO_TIMEOUT", STATUS_IO_TIMEOUT },
More information about the wine-cvs
mailing list