[PATCH 0/1] MR11558: win32u: Fix off-by-one in kbd_tables_init_vsc2vk.
Found by ASan (unix). <details> <summary>ASan report details</summary> ``` ASAN_OPTIONS="halt_on_error=0:detect_leaks=0:log_exe_name=1:log_path=\"/home/bernhard/asan\"" wine cmd ps aux | grep conhost gdb-multiarch -q --pid 364794 b Die cont # pressed d key in the konsole with the running cmd (gdb) bt #0 __sanitizer::Die () at ../../../../src/libsanitizer/sanitizer_common/sanitizer_termination.cpp:50 #1 0x00007fe0358fee3f in __asan::ScopedInErrorReport::~ScopedInErrorReport (this=0x7ffffeead316, __in_chrg=<optimized out>) at ../../../../src/libsanitizer/asan/asan_report.cpp:192 #2 0x00007fe0358fe4a0 in __asan::ReportGenericError (pc=140600888834656, bp=140737470193536, sp=sp@entry=140737470193528, addr=140600890957854, is_write=is_write@entry=false, access_size=2, fatal=true, exp=<optimized out>) at ../../../../src/libsanitizer/asan/asan_report.cpp:497 #3 0x00007fe0358fe60e in __asan::ReportGenericError (pc=<optimized out>, bp=bp@entry=140737470193536, sp=sp@entry=140737470193528, addr=<optimized out>, is_write=is_write@entry=false, access_size=access_size@entry=2, exp=<optimized out>, fatal=true) at ../../../../src/libsanitizer/asan/asan_report.cpp:497 #4 0x00007fe0358ff48c in __asan::__asan_report_load2 (addr=<optimized out>) at ../../../../src/libsanitizer/asan/asan_rtl.cpp:129 #5 0x00007fe03208ba60 in kbd_tables_init_vsc2vk (tables=0x7fe032362380 <kbdus_tables>, vsc2vk=0x7fe0157c4960) at dlls/win32u/input.c:434 #6 0x00007fe03209261a in NtUserMapVirtualKeyEx (code=68, type=<optimized out>, layout=<optimized out>) at dlls/win32u/input.c:1245 #7 0x00007fe032ad4106 in __wine_syscall_dispatcher () from dlls/ntdll/ntdll.so #8 0x00007fe032ace093 in server_init_thread (data=data@entry=0x7ffffeda0000) at dlls/ntdll/unix/server.c:1818 #9 0x00007fe03585b1d6 in asan_thread_start (arg=0x7fe02f003000) at ../../../../src/libsanitizer/asan/asan_interceptors.cpp:234 #10 0x00007fe03569e8bb in start_thread (arg=<optimized out>) at ./nptl/pthread_create.c:448 #11 0x00007fe03571c538 in __GI___clone3 () at ../sysdeps/unix/sysv/linux/x86_64/clone3.S:78 ================================================================= ==wine==364794==ERROR: AddressSanitizer: global-buffer-overflow on address 0x7fe03229201e at pc 0x7fe03208ba60 bp 0x7ffffeeadf80 sp 0x7ffffeeadf78 READ of size 2 at 0x7fe03229201e thread T19 #0 0x7fe03208ba5f in kbd_tables_init_vsc2vk dlls/win32u/input.c:434 #1 0x7fe032092619 in NtUserMapVirtualKeyEx dlls/win32u/input.c:1245 #2 0x7fe032ad4105 in __wine_syscall_dispatcher (dlls/ntdll/ntdll.so+0xcf105) (BuildId: 7bc5cb3f128a1e422fc0ae4549a1c6aa689df369) #3 0x7fe032ace092 in server_init_thread dlls/ntdll/unix/server.c:1818 #4 0x7fe03585b1d5 in asan_thread_start ../../../../src/libsanitizer/asan/asan_interceptors.cpp:234 #5 0x7fe03569e8ba in start_thread nptl/pthread_create.c:448 #6 0x7fe03571c537 in __clone3 ../sysdeps/unix/sysv/linux/x86_64/clone3.S:78 0x7fe03229201e is located 34 bytes before global variable 'vk_to_wchars1' defined in 'dlls/win32u/input.c:219:28' (0x7fe032292040) of size 44 0x7fe03229201e is located 0 bytes after global variable 'vsc_to_vk' defined in 'dlls/win32u/input.c:326:21' (0x7fe032291f20) of size 254 SUMMARY: AddressSanitizer: global-buffer-overflow dlls/win32u/input.c:434 in kbd_tables_init_vsc2vk ``` </details -- https://gitlab.winehq.org/wine/wine/-/merge_requests/11558
From: Bernhard Übelacker <bernhardu@mailbox.org> Found by ASan (unix). --- dlls/win32u/input.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dlls/win32u/input.c b/dlls/win32u/input.c index 71219aed5fe..b8a27083436 100644 --- a/dlls/win32u/input.c +++ b/dlls/win32u/input.c @@ -429,7 +429,7 @@ static void kbd_tables_init_vsc2vk( const KBDTABLES *tables, USHORT vsc2vk[0x300 memset( vsc2vk, 0, 0x300 * sizeof(USHORT) ); - for (vsc = 0; tables->pusVSCtoVK && vsc <= tables->bMaxVSCtoVK; ++vsc) + for (vsc = 0; tables->pusVSCtoVK && vsc < tables->bMaxVSCtoVK; ++vsc) { if (tables->pusVSCtoVK[vsc] == VK__none_) continue; vsc2vk[vsc] = tables->pusVSCtoVK[vsc]; -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/11558
Etaash Mathamsetty (@etaash.mathamsetty) commented about dlls/win32u/input.c:
memset( vsc2vk, 0, 0x300 * sizeof(USHORT) );
- for (vsc = 0; tables->pusVSCtoVK && vsc <= tables->bMaxVSCtoVK; ++vsc) + for (vsc = 0; tables->pusVSCtoVK && vsc < tables->bMaxVSCtoVK; ++vsc)
winewayland sets `bMaxVSCtoVK` to 255 when the size of its vsc2vk array is 256. I think either that should be updated to 256 or win32u should use `ARRAY_SIZE(vsc_to_vk)-1` as its value of bMaxVSCtoVK. EDIT: since bMaxVSCtoVK is a byte win32u should use `ARRAY_SIZE(vsc_to_vk)-1` -- https://gitlab.winehq.org/wine/wine/-/merge_requests/11558#note_147717
participants (3)
-
Bernhard Übelacker -
Bernhard Übelacker (@bernhardu) -
Etaash Mathamsetty (@etaash.mathamsetty)