-- v3: win32u: Avoid invalid access when registered device alloc failed. (Coverity) win32u: Send the total number of registered devices to the server. win32u: Avoid reallocating rawinput device array with zero size. server: Avoid reallocating rawinput device array with zero size.
From: R��mi Bernon rbernon@codeweavers.com
It actually frees the pointer. --- server/queue.c | 8 ++++++++ 1 file changed, 8 insertions(+)
diff --git a/server/queue.c b/server/queue.c index d98d645065f..01fe8d6c060 100644 --- a/server/queue.c +++ b/server/queue.c @@ -3380,6 +3380,14 @@ DECL_HANDLER(update_rawinput_devices) size_t size = device_count * sizeof(*devices); struct process *process = current->process;
+ if (!size) + { + process->rawinput_device_count = 0; + process->rawinput_mouse = NULL; + process->rawinput_kbd = NULL; + return; + } + if (!(tmp = realloc( process->rawinput_devices, size ))) { set_error( STATUS_NO_MEMORY );
From: R��mi Bernon rbernon@codeweavers.com
It actually frees the pointer. --- dlls/win32u/rawinput.c | 6 ++++++ 1 file changed, 6 insertions(+)
diff --git a/dlls/win32u/rawinput.c b/dlls/win32u/rawinput.c index 8e3f3ace15a..44951522442 100644 --- a/dlls/win32u/rawinput.c +++ b/dlls/win32u/rawinput.c @@ -856,6 +856,12 @@ BOOL WINAPI NtUserRegisterRawInputDevices( const RAWINPUTDEVICE *devices, UINT d
pthread_mutex_lock( &rawinput_mutex );
+ if (!registered_device_count && !device_count) + { + pthread_mutex_unlock( &rawinput_mutex ); + return TRUE; + } + size = (SIZE_T)device_size * (registered_device_count + device_count); registered_devices = realloc( registered_devices, size ); if (registered_devices) for (i = 0; i < device_count; ++i) register_rawinput_device( devices + i );
From: R��mi Bernon rbernon@codeweavers.com
Instead of device_count which is the number of registration updates, and execute the request within the rawinput_mutex to ensure atomicity of the update and consistency between the client and the server state.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=53468 Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=53487 --- dlls/win32u/rawinput.c | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-)
diff --git a/dlls/win32u/rawinput.c b/dlls/win32u/rawinput.c index 44951522442..2dc03e7fe2d 100644 --- a/dlls/win32u/rawinput.c +++ b/dlls/win32u/rawinput.c @@ -866,8 +866,15 @@ BOOL WINAPI NtUserRegisterRawInputDevices( const RAWINPUTDEVICE *devices, UINT d registered_devices = realloc( registered_devices, size ); if (registered_devices) for (i = 0; i < device_count; ++i) register_rawinput_device( devices + i );
- server_devices = malloc( registered_device_count * sizeof(*server_devices) ); - if (server_devices) for (i = 0; i < registered_device_count; ++i) + if (!(device_count = registered_device_count)) server_devices = NULL; + else if (!(server_devices = malloc( device_count * sizeof(*server_devices) ))) + { + pthread_mutex_unlock( &rawinput_mutex ); + SetLastError( ERROR_OUTOFMEMORY ); + return FALSE; + } + + for (i = 0; i < device_count; ++i) { server_devices[i].usage_page = registered_devices[i].usUsagePage; server_devices[i].usage = registered_devices[i].usUsage; @@ -875,14 +882,6 @@ BOOL WINAPI NtUserRegisterRawInputDevices( const RAWINPUTDEVICE *devices, UINT d server_devices[i].target = wine_server_user_handle( registered_devices[i].hwndTarget ); }
- pthread_mutex_unlock( &rawinput_mutex ); - - if (!registered_devices || !server_devices) - { - SetLastError( ERROR_OUTOFMEMORY ); - return FALSE; - } - SERVER_START_REQ( update_rawinput_devices ) { wine_server_add_data( req, server_devices, device_count * sizeof(*server_devices) ); @@ -892,6 +891,14 @@ BOOL WINAPI NtUserRegisterRawInputDevices( const RAWINPUTDEVICE *devices, UINT d
free( server_devices );
+ pthread_mutex_unlock( &rawinput_mutex ); + + if (!registered_devices) + { + SetLastError( ERROR_OUTOFMEMORY ); + return FALSE; + } + return ret; }
From: R��mi Bernon rbernon@codeweavers.com
--- dlls/win32u/rawinput.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-)
diff --git a/dlls/win32u/rawinput.c b/dlls/win32u/rawinput.c index 2dc03e7fe2d..cf150b60a8c 100644 --- a/dlls/win32u/rawinput.c +++ b/dlls/win32u/rawinput.c @@ -821,6 +821,7 @@ static void register_rawinput_device( const RAWINPUTDEVICE *device ) BOOL WINAPI NtUserRegisterRawInputDevices( const RAWINPUTDEVICE *devices, UINT device_count, UINT device_size ) { struct rawinput_device *server_devices; + RAWINPUTDEVICE *new_registered_devices; SIZE_T size; BOOL ret; UINT i; @@ -863,8 +864,15 @@ BOOL WINAPI NtUserRegisterRawInputDevices( const RAWINPUTDEVICE *devices, UINT d }
size = (SIZE_T)device_size * (registered_device_count + device_count); - registered_devices = realloc( registered_devices, size ); - if (registered_devices) for (i = 0; i < device_count; ++i) register_rawinput_device( devices + i ); + if (!(new_registered_devices = realloc( registered_devices, size ))) + { + pthread_mutex_unlock( &rawinput_mutex ); + SetLastError( ERROR_OUTOFMEMORY ); + return FALSE; + } + + registered_devices = new_registered_devices; + for (i = 0; i < device_count; ++i) register_rawinput_device( devices + i );
if (!(device_count = registered_device_count)) server_devices = NULL; else if (!(server_devices = malloc( device_count * sizeof(*server_devices) ))) @@ -893,12 +901,6 @@ BOOL WINAPI NtUserRegisterRawInputDevices( const RAWINPUTDEVICE *devices, UINT d
pthread_mutex_unlock( &rawinput_mutex );
- if (!registered_devices) - { - SetLastError( ERROR_OUTOFMEMORY ); - return FALSE; - } - return ret; }
v3: Make the checks more explicit.