Other calls to `d3d9_device_DrawPrimitiveUP` use just the size of one dimension of the `quad` array as parameter `stride`.
Therefore using the size of the whole `quad` variable causes the function call with `D3DPT_TRIANGLESTRIP` and `primitive_count=2` to read "64 * (2+2) = 256 bytes" which overflows the allocated "64 bytes".
[Testbot run with this patch](https://testbot.winehq.org/JobDetails.pl?Key=160603)
<details> <summary>ASan report details</summary>
``` ================================================================= ==312==ERROR: AddressSanitizer: global-buffer-overflow on address 0x0001401c8540 at pc 0x6ffffe8dc03b bp 0x7ffffe1fe930 sp 0x7ffffe1fe978 READ of size 256 at 0x0001401c8540 thread T0 #0 0x6ffffe8dc03a in __asan_memcpy /home/runner/work/llvm-mingw/llvm-mingw/llvm-project/compiler-rt/lib/asan/asan_interceptors_memintrinsics.cpp:65:3 #1 0x6ffff97c7abb in wined3d_streaming_buffer_upload .../wine/dlls/wined3d/buffer.c:1438 #2 0x6ffffdd4519d in d3d9_device_DrawPrimitiveUP .../wine/dlls/d3d9/device.c:3345 #3 0x0001400b55f0 in clear_test .../wine/dlls/d3d9/tests/visual.c:1464 #4 0x0001400a900c in func_visual .../wine/dlls/d3d9/tests/visual.c:28886 #5 0x00014017ada2 in run_test .../wine/include/wine/test.h:768 #6 0x00014017a7ab in main .../wine/include/wine/test.h:888 #7 0x00014017ca7a in mainCRTStartup .../wine/dlls/msvcrt/crt_main.c:62 #8 0x6fffffc67a74 in BaseThreadInitThunk (C:\windows\system32\kernel32.dll+0x178027a74) #9 0x6fffffde06a6 in RtlUserThreadStart (C:\windows\system32\ntdll.dll+0x1700506a6)
0x0001401c8540 is located 32 bytes before global variable '"Clear rectangle 3(pos, neg) has "...' defined in '.../wine/dlls/d3d9/tests/visual.c:1230' (0x0001401c8560) of size 44 '"Clear rectangle 3(pos, neg) has "...' is ascii string 'Clear rectangle 3(pos, neg) has color %08x ' 0x0001401c8540 is located 0 bytes after global variable 'clear_test.quad' defined in '.../wine/dlls/d3d9/tests/visual.c:1168' (0x0001401c8500) of size 64 SUMMARY: AddressSanitizer: global-buffer-overflow .../wine/dlls/wined3d/buffer.c:1438 in wined3d_streaming_buffer_upload Shadow bytes around the buggy address: 0x0001401c8280: f9 f9 f9 f9 00 00 00 00 00 06 f9 f9 f9 f9 f9 f9 0x0001401c8300: 00 00 00 00 00 02 f9 f9 f9 f9 f9 f9 00 00 00 00 0x0001401c8380: 00 04 f9 f9 f9 f9 f9 f9 00 00 00 00 02 f9 f9 f9 0x0001401c8400: f9 f9 f9 f9 00 00 00 00 00 00 00 00 02 f9 f9 f9 0x0001401c8480: f9 f9 f9 f9 00 00 00 00 00 00 00 00 f9 f9 f9 f9 =>0x0001401c8500: 00 00 00 00 00 00 00 00[f9]f9 f9 f9 00 00 00 00 0x0001401c8580: 00 04 f9 f9 f9 f9 f9 f9 00 00 00 00 00 04 f9 f9 0x0001401c8600: f9 f9 f9 f9 00 00 00 00 00 f9 f9 f9 f9 f9 f9 f9 0x0001401c8680: 00 00 00 00 00 04 f9 f9 f9 f9 f9 f9 00 00 00 02 0x0001401c8700: f9 f9 f9 f9 00 00 00 02 f9 f9 f9 f9 00 00 00 02 0x0001401c8780: f9 f9 f9 f9 00 00 00 02 f9 f9 f9 f9 00 00 00 02 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 ```
</details>
From: Bernhard Übelacker bernhardu@mailbox.org
--- dlls/d3d9/tests/visual.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/dlls/d3d9/tests/visual.c b/dlls/d3d9/tests/visual.c index cc2b60d0d48..1c60e18b083 100644 --- a/dlls/d3d9/tests/visual.c +++ b/dlls/d3d9/tests/visual.c @@ -1461,7 +1461,7 @@ static void clear_test(void) ok(SUCCEEDED(hr), "Failed to set FVF, hr %#lx.\n", hr); hr = IDirect3DDevice9_BeginScene(device); ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr); - hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad)); + hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad)); ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr); hr = IDirect3DDevice9_EndScene(device); ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr); @@ -1507,7 +1507,7 @@ static void clear_test(void)
hr = IDirect3DDevice9_BeginScene(device); ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr); - hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad)); + hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad)); ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr); hr = IDirect3DDevice9_EndScene(device); ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
This merge request was approved by Elizabeth Figura.