server: Add some validation of clipboard window handles.

Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Alexandre Julliard 2016-08-29 20:33:22 +09:00
parent 09f9986ea1
commit 19d16a7cb1
4 changed files with 72 additions and 7 deletions

View File

@ -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;
}

View File

@ -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" ))

View File

@ -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 */
}

View File

@ -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 },