If `KeUserModeCallback` fails, `ret_ptr` and `ret_len` might be left uninitialized. Since the returned status isn't checked in `dispatch_win_proc_params`, it can access uninitialized memory.
* * *
One way this could actually happen is if on x86_64 `KeUserModeCallback` returned `STATUS_STACK_OVERFLOW`.
From: Yuxuan Shui yshui@codeweavers.com
If `KeUserModeCallback` fails, `ret_ptr` and `ret_len` might be left uninitialized. Since the returned status isn't checked in `dispatch_win_proc_params`, it can access uninitialized memory. --- dlls/win32u/message.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/dlls/win32u/message.c b/dlls/win32u/message.c index fd137f58660..a6fa5c3c0ba 100644 --- a/dlls/win32u/message.c +++ b/dlls/win32u/message.c @@ -420,12 +420,15 @@ static LRESULT dispatch_win_proc_params( struct win_proc_params *params, size_t LRESULT result = 0; void *ret_ptr; ULONG ret_len; + NTSTATUS status;
if (thread_info->recursion_count > MAX_WINPROC_RECURSION) return 0; thread_info->recursion_count++; - KeUserModeCallback( NtUserCallWinProc, params, size, &ret_ptr, &ret_len ); + status = KeUserModeCallback( NtUserCallWinProc, params, size, &ret_ptr, &ret_len ); thread_info->recursion_count--;
+ if (status) return result; + if (ret_len >= sizeof(result)) { result = *(LRESULT *)ret_ptr;