ASan gets triggered in `test_read_write` because an APC gets executed while `test_async_file_errors` is already left, and therefore the `ovl` variable in is no longer at the stack.
This patch tries to flush the APC before leaving the function `test_async_file_errors`. Also closes two handles opened inside this function.
``` ================================================================= ==508==ERROR: AddressSanitizer: stack-use-after-scope on address 0x7ffffe1ea7f8 at pc 0x0001401a4933 bp 0x7ffffe1e2a80 sp 0x7ffffe1e2ac8 READ of size 8 at 0x7ffffe1ea7f8 thread T0 0208:fixme:file:server_get_file_info Unsupported info class e #0 0x0001401a4932 in FileIOComplete .../wine/dlls/kernel32/tests/file.c:3337:24 #1 0x6ffffacef75f in KiUserApcDispatcher (C:\windows\system32\ntdll.dll+0x17000f75f) #2 0x6ffffacedf53 in NtDelayExecution (C:\windows\system32\ntdll.dll+0x17000df53) #3 0x6ffffa6eec5f in SleepEx .../wine/dlls/kernelbase\sync.c:346:14 #4 0x00014015a0e3 in test_read_write .../wine/dlls/kernel32/tests/file.c:3451:5 #5 0x00014015a0e3 in func_file .../wine/dlls/kernel32/tests/file.c:6348:5 #6 0x0001404d7fa1 in run_test .../wine/include/wine/test.h:765:5 #7 0x0001404d7fa1 in main .../wine/include/wine/test.h:884:12 #8 0x0001404d9f8f in mainCRTStartup .../wine/dlls/msvcrt/crt_main.c:58:11 #9 0x6ffffbfd4808 in BaseThreadInitThunk .../wine/dlls/kernel32\thread.c:61:5 #10 0x6ffffacefa1a in RtlUserThreadStart (C:\windows\system32\ntdll.dll+0x17000fa1a)
Address 0x7ffffe1ea7f8 is located in stack of thread T0 at offset 30232 in frame #0 0x00014013223f in func_file .../wine/dlls/kernel32/tests/file.c:6296
This frame has 205 object(s): [32, 292) 'cwd.i6426' (line 6001) [368, 628) 'temp_dir.i6427' (line 6001) [704, 964) 'cwd.i' (line 5922) ... [29536, 29796) 'filename.i2304' (line 3395) [29872, 30132) 'szFile.i' (line 3343) [30208, 30240) 'ovl.i' (line 3347) <== Memory access at offset 30232 is inside this variable [30272, 30276) 'count.i' (line 3364) [30288, 30296) 'h.i' (line 3246) ... [116896, 117156) 'temp_path' (line 6297) HINT: this may be a false positive if your program uses some custom stack unwind mechanism, swapcontext or vfork (longjmp, SEH and C++ exceptions *are* supported) SUMMARY: AddressSanitizer: stack-use-after-scope .../wine/dlls/kernel32/tests/file.c:3337:24 in FileIOComplete Shadow bytes around the buggy address: 0x7ffffe1ea500: f2 f2 f2 f2 f2 f2 f2 f2 00 00 00 00 00 00 00 00 0x7ffffe1ea580: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x7ffffe1ea600: 00 00 00 00 00 00 00 00 04 f2 f2 f2 f2 f2 f2 f2 0x7ffffe1ea680: f2 f2 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 0x7ffffe1ea700: f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 =>0x7ffffe1ea780: f8 f8 f8 f2 f2 f2 f2 f2 f2 f2 f2 f2 f8 f8 f8[f8] 0x7ffffe1ea800: f2 f2 f2 f2 f8 f2 f8 f2 f2 f2 f8 f2 f2 f2 f8 f8 0x7ffffe1ea880: f8 f8 f2 f2 f2 f2 f8 f2 f8 f8 f8 f8 f8 f8 f8 f8 0x7ffffe1ea900: f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 0x7ffffe1ea980: f8 f8 f8 f8 f8 f8 f8 f8 f2 f2 f2 f2 f2 f2 f2 f2 0x7ffffe1eaa00: f8 f2 f2 f2 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 Shadow byte legend (one shadow byte represents 8 application bytes): Addressable: 00 Partially addressable: 01 02 03 04 05 06 07 Heap left redzone: fa Freed heap region: fd Stack left redzone: f1 Stack mid redzone: f2 Stack right redzone: f3 Stack after return: f5 Stack use after scope: f8 Global redzone: f9 Global init order: f6 Poisoned by user: f7 Container overflow: fc Array cookie: ac Intra object redzone: bb ASan internal: fe Left alloca redzone: ca Right alloca redzone: cb ==508==ABORTING ```
From: Bernhard Übelacker bernhardu@mailbox.org
--- dlls/kernel32/tests/file.c | 4 ++++ 1 file changed, 4 insertions(+)
diff --git a/dlls/kernel32/tests/file.c b/dlls/kernel32/tests/file.c index 68b9f53700e..1a1505060cd 100644 --- a/dlls/kernel32/tests/file.c +++ b/dlls/kernel32/tests/file.c @@ -3376,6 +3376,10 @@ static void test_async_file_errors(void) } ok(completion_count == 0, "completion routine should only be called when ReadFileEx succeeds (this rule was violated %d times)\n", completion_count); /*printf("Error = %ld\n", GetLastError());*/ + + SleepEx(0, TRUE); /* Flush pending APCs */ + ok(CloseHandle(hFile), "CloseHandle: error %ld\n", GetLastError()); + ok(CloseHandle(hSem), "CloseHandle: error %ld\n", GetLastError()); HeapFree(GetProcessHeap(), 0, lpBuffer); }