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