[PATCH 0/1] MR9870: iccvid/tests: Reserve enough memory for input in test_formats (ASan).
ASan got triggered by the new iccvid test. In `ICCVID_DecompressGetFormat` the input pointer gets read 484 (40+111*4) bytes, but variable `in` gets just the size of `BITMAPINFOHEADER`, 40 bytes allocated. CC: @zfigura [Testbot run with this patch](https://testbot.winehq.org/JobDetails.pl?Key=161448) <details> <summary>ASan details [link](https://gitlab.winehq.org/bernhardu/wine/-/jobs/220743#L5427-L5452)</summary> ``` ==iccvid_test.exe==1720==ERROR: AddressSanitizer: stack-buffer-overflow on address 0x0022f8e8 at pc 0x784543e2 bp 0x0022f1f0 sp 0x0022edc0 READ of size 484 at 0x0022f8e8 thread T0 #0 0x784543e1 in __asan_memcpy /home/runner/work/llvm-mingw/llvm-mingw/llvm-project/compiler-rt/lib/asan/asan_interceptors_memintrinsics.cpp:65:3 #1 0x77fd22aa in ICCVID_DecompressGetFormat /builds/bernhardu/wine/build64/../dlls/iccvid/iccvid.c:836:9 #2 0x77fd1351 in ICCVID_DriverProc /builds/bernhardu/wine/build64/../dlls/iccvid/iccvid.c:1015:16 #3 0x78e92cf3 in DRIVER_SendMessage /builds/bernhardu/wine/build64/../dlls/winmm/driver.c:130:11 #4 0x78e92ba8 in SendDriverMessage /builds/bernhardu/wine/build64/../dlls/winmm/driver.c:150:11 #5 0x7902d7e0 in MSVIDEO_SendMessage /builds/bernhardu/wine/build64/../dlls/msvfw32/msvideo_main.c:198:15 #6 0x7902db20 in ICSendMessage /builds/bernhardu/wine/build64/../dlls/msvfw32/msvideo_main.c:1163:12 #7 0x0040190d in test_formats /builds/bernhardu/wine/build64/../dlls/iccvid/tests/iccvid.c:62:11 #8 0x004010d9 in func_iccvid /builds/bernhardu/wine/build64/../dlls/iccvid/tests/iccvid.c:196:5 #9 0x00404f51 in run_test /builds/bernhardu/wine/build64/../include/wine/test.h:780:5 #10 0x00404a6b in main /builds/bernhardu/wine/build64/../include/wine/test.h #11 0x00405f05 in mainCRTStartup /builds/bernhardu/wine/build64/../dlls/msvcrt/crt_main.c:62:11 #12 0x7bcd367f in BaseThreadInitThunk (C:\windows\system32\kernel32.dll+0x7b82367f) #13 0x7be4680a in call_thread_func_wrapper (C:\windows\system32\ntdll.dll+0x7bc4680a) #14 0x7be4717a in call_thread_func /builds/bernhardu/wine/build64/../dlls/ntdll/signal_i386.c:503:9 Address 0x0022f8e8 is located in stack of thread T0 at offset 1256 in frame #0 0x0040149f in test_formats /builds/bernhardu/wine/build64/../dlls/iccvid/tests/iccvid.c:25 This frame has 3 object(s): [16, 1080) 'buffer' (line 26) [1216, 1256) 'in' (line 27) [1296, 1864) 'info' (line 30) <== Memory access at offset 1256 partially underflows this variable 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-buffer-overflow /builds/bernhardu/wine/build64/../dlls/iccvid/iccvid.c:836:9 in ICCVID_DecompressGetFormat ``` </details> -- https://gitlab.winehq.org/wine/wine/-/merge_requests/9870
From: Bernhard Übelacker <bernhardu@mailbox.org> --- dlls/iccvid/tests/iccvid.c | 82 +++++++++++++++++++------------------- 1 file changed, 42 insertions(+), 40 deletions(-) diff --git a/dlls/iccvid/tests/iccvid.c b/dlls/iccvid/tests/iccvid.c index d957858b16b..d534b0db021 100644 --- a/dlls/iccvid/tests/iccvid.c +++ b/dlls/iccvid/tests/iccvid.c @@ -23,16 +23,18 @@ static void test_formats(void) { - char buffer[offsetof(BITMAPINFO, bmiColors[256])]; - BITMAPINFOHEADER in = {.biSize = sizeof(BITMAPINFOHEADER)}; + char in_buffer[offsetof(BITMAPINFO, bmiColors[111])] = {0}; + char buffer[offsetof(BITMAPINFO, bmiColors[111])]; + BITMAPINFOHEADER *in = (BITMAPINFOHEADER *)in_buffer; BITMAPINFO *out = (BITMAPINFO *)buffer; LRESULT ret; ICINFO info; HIC hic; - in.biCompression = mmioFOURCC('c','v','i','d'); + in->biSize = sizeof(BITMAPINFOHEADER); + in->biCompression = mmioFOURCC('c','v','i','d'); - hic = ICLocate(ICTYPE_VIDEO, mmioFOURCC('c','v','i','d'), &in, NULL, ICMODE_DECOMPRESS); + hic = ICLocate(ICTYPE_VIDEO, mmioFOURCC('c','v','i','d'), in, NULL, ICMODE_DECOMPRESS); ok(!!hic, "Failed to open codec.\n"); ret = ICGetInfo(hic, &info, sizeof(info)); @@ -45,21 +47,21 @@ static void test_formats(void) todo_wine ok(info.dwVersion == 0x10000, "Got version %#lx.\n", info.dwVersion); ok(info.dwVersionICM == ICVERSION, "Got ICM version %#lx.\n", info.dwVersionICM); - ret = ICDecompressQuery(hic, &in, NULL); + ret = ICDecompressQuery(hic, in, NULL); ok(ret == ICERR_OK, "Got %Id.\n", ret); - ret = ICDecompressGetFormat(hic, &in, NULL); + ret = ICDecompressGetFormat(hic, in, NULL); ok(ret == sizeof(BITMAPINFOHEADER), "Got %Id.\n", ret); - in.biWidth = 320; - in.biHeight = 240; - in.biXPelsPerMeter = 12; - in.biYPelsPerMeter = 34; - in.biClrUsed = 111; - in.biClrImportant = 111; + in->biWidth = 320; + in->biHeight = 240; + in->biXPelsPerMeter = 12; + in->biYPelsPerMeter = 34; + in->biClrUsed = 111; + in->biClrImportant = 111; memset(buffer, 0xcc, sizeof(buffer)); - ret = ICDecompressGetFormat(hic, &in, out); + ret = ICDecompressGetFormat(hic, in, out); ok(ret == ICERR_OK, "Got %Id.\n", ret); ok(out->bmiHeader.biSize == sizeof(BITMAPINFOHEADER), "Got size %lu.\n", out->bmiHeader.biSize); ok(out->bmiHeader.biWidth == 320, "Got width %ld.\n", out->bmiHeader.biWidth); @@ -74,65 +76,65 @@ static void test_formats(void) todo_wine ok(!out->bmiHeader.biClrImportant, "Got %lu important colours.\n", out->bmiHeader.biClrImportant); todo_wine ok(out->bmiColors[0].rgbRed == 0xcc, "Expected colours to be unmodified.\n"); - ret = ICDecompressQuery(hic, &in, out); + ret = ICDecompressQuery(hic, in, out); ok(ret == ICERR_OK, "Got %Id.\n", ret); out->bmiHeader.biHeight = -240; out->bmiHeader.biSizeImage = 0; - ret = ICDecompressQuery(hic, &in, out); + ret = ICDecompressQuery(hic, in, out); ok(ret == ICERR_OK, "Got %Id.\n", ret); out->bmiHeader.biPlanes = 0; - ret = ICDecompressQuery(hic, &in, out); + ret = ICDecompressQuery(hic, in, out); todo_wine ok(ret == ICERR_BADFORMAT, "Got %Id.\n", ret); out->bmiHeader.biPlanes = 1; out->bmiHeader.biHeight = -480; - ret = ICDecompressQuery(hic, &in, out); + ret = ICDecompressQuery(hic, in, out); ok(ret == ICERR_BADFORMAT, "Got %Id.\n", ret); out->bmiHeader.biHeight = -240; out->bmiHeader.biWidth = 640; out->bmiHeader.biHeight = 480; - ret = ICDecompressQuery(hic, &in, out); + ret = ICDecompressQuery(hic, in, out); ok(ret == ICERR_BADFORMAT, "Got %Id.\n", ret); out->bmiHeader.biWidth = 160; out->bmiHeader.biHeight = 120; - ret = ICDecompressQuery(hic, &in, out); + ret = ICDecompressQuery(hic, in, out); ok(ret == ICERR_BADFORMAT, "Got %Id.\n", ret); out->bmiHeader.biWidth = 320; out->bmiHeader.biHeight = 240; out->bmiHeader.biBitCount = 8; - ret = ICDecompressQuery(hic, &in, out); + ret = ICDecompressQuery(hic, in, out); todo_wine ok(ret == ICERR_OK, "Got %Id.\n", ret); out->bmiHeader.biBitCount = 16; - ret = ICDecompressQuery(hic, &in, out); + ret = ICDecompressQuery(hic, in, out); ok(ret == ICERR_OK, "Got %Id.\n", ret); out->bmiHeader.biBitCount = 32; - ret = ICDecompressQuery(hic, &in, out); + ret = ICDecompressQuery(hic, in, out); ok(ret == ICERR_OK, "Got %Id.\n", ret); out->bmiHeader.biBitCount = 16; out->bmiHeader.biCompression = BI_BITFIELDS; - ret = ICDecompressQuery(hic, &in, out); + ret = ICDecompressQuery(hic, in, out); ok(ret == ICERR_BADFORMAT, "Got %Id.\n", ret); ((DWORD *)&out->bmiColors[0])[0] = 0xf800; ((DWORD *)&out->bmiColors[0])[1] = 0x07e0; ((DWORD *)&out->bmiColors[0])[2] = 0x001f; - ret = ICDecompressQuery(hic, &in, out); + ret = ICDecompressQuery(hic, in, out); ok(ret == ICERR_OK, "Got %Id.\n", ret); out->bmiHeader.biCompression = mmioFOURCC('C','L','J','R'); out->bmiHeader.biBitCount = 8; - ret = ICDecompressQuery(hic, &in, out); + ret = ICDecompressQuery(hic, in, out); ok(ret == ICERR_BADFORMAT, "Got %Id.\n", ret); out->bmiHeader.biBitCount = 16; out->bmiHeader.biCompression = mmioFOURCC('U','Y','V','Y'); - ret = ICDecompressQuery(hic, &in, out); + ret = ICDecompressQuery(hic, in, out); ok(ret == ICERR_BADFORMAT, "Got %Id.\n", ret); out->bmiHeader.biCompression = mmioFOURCC('Y','U','Y','2'); - ret = ICDecompressQuery(hic, &in, out); + ret = ICDecompressQuery(hic, in, out); ok(ret == ICERR_BADFORMAT, "Got %Id.\n", ret); ret = ICDecompressEnd(hic); @@ -140,39 +142,39 @@ static void test_formats(void) out->bmiHeader.biCompression = BI_RGB; out->bmiHeader.biBitCount = 24; - ret = ICDecompressBegin(hic, &in, out); + ret = ICDecompressBegin(hic, in, out); ok(ret == ICERR_OK, "Got %Id.\n", ret); ret = ICDecompressEnd(hic); ok(ret == ICERR_OK, "Got %Id.\n", ret); - ret = ICDecompressExQuery(hic, 0, &in, NULL, 0, 0, 320, 240, NULL, NULL, 0, 0, 0, 0); + ret = ICDecompressExQuery(hic, 0, in, NULL, 0, 0, 320, 240, NULL, NULL, 0, 0, 0, 0); ok(ret == ICERR_OK, "Got %Id.\n", ret); - ret = ICDecompressExQuery(hic, 0, &in, NULL, 0, 0, 32, 24, NULL, NULL, 0, 0, 0, 0); + ret = ICDecompressExQuery(hic, 0, in, NULL, 0, 0, 32, 24, NULL, NULL, 0, 0, 0, 0); ok(ret == ICERR_BADPARAM, "Got %Id.\n", ret); - ret = ICDecompressExQuery(hic, 0, &in, NULL, 0, 0, 0, 0, NULL, NULL, 0, 0, 0, 0); + ret = ICDecompressExQuery(hic, 0, in, NULL, 0, 0, 0, 0, NULL, NULL, 0, 0, 0, 0); ok(ret == ICERR_BADPARAM, "Got %Id.\n", ret); - ret = ICDecompressExQuery(hic, 0, &in, NULL, 20, 0, 320, 240, NULL, NULL, 0, 0, 0, 0); + ret = ICDecompressExQuery(hic, 0, in, NULL, 20, 0, 320, 240, NULL, NULL, 0, 0, 0, 0); ok(ret == ICERR_BADPARAM, "Got %Id.\n", ret); - ret = ICDecompressExQuery(hic, 0, &in, NULL, 0, 20, 320, 240, NULL, NULL, 0, 0, 0, 0); + ret = ICDecompressExQuery(hic, 0, in, NULL, 0, 20, 320, 240, NULL, NULL, 0, 0, 0, 0); ok(ret == ICERR_BADPARAM, "Got %Id.\n", ret); - ret = ICDecompressExQuery(hic, 0, &in, NULL, 0, 0, 320, 240, &out->bmiHeader, NULL, 0, 0, 0, 0); + ret = ICDecompressExQuery(hic, 0, in, NULL, 0, 0, 320, 240, &out->bmiHeader, NULL, 0, 0, 0, 0); ok(ret == ICERR_BADFORMAT, "Got %Id.\n", ret); - ret = ICDecompressExQuery(hic, 0, &in, NULL, 0, 0, 320, 240, &out->bmiHeader, NULL, 0, 0, 320, 240); + ret = ICDecompressExQuery(hic, 0, in, NULL, 0, 0, 320, 240, &out->bmiHeader, NULL, 0, 0, 320, 240); ok(ret == ICERR_OK, "Got %Id.\n", ret); - ret = ICDecompressExQuery(hic, 0, &in, NULL, 0, 0, 320, 240, &out->bmiHeader, NULL, 0, 0, 160, 120); + ret = ICDecompressExQuery(hic, 0, in, NULL, 0, 0, 320, 240, &out->bmiHeader, NULL, 0, 0, 160, 120); ok(ret == ICERR_BADFORMAT, "Got %Id.\n", ret); out->bmiHeader.biWidth = 640; - ret = ICDecompressExQuery(hic, 0, &in, NULL, 0, 0, 320, 240, &out->bmiHeader, NULL, 0, 0, 640, 240); + ret = ICDecompressExQuery(hic, 0, in, NULL, 0, 0, 320, 240, &out->bmiHeader, NULL, 0, 0, 640, 240); ok(ret == ICERR_BADFORMAT, "Got %Id.\n", ret); out->bmiHeader.biHeight = 480; - ret = ICDecompressExQuery(hic, 0, &in, NULL, 0, 0, 320, 240, &out->bmiHeader, NULL, 0, 0, 640, 480); + ret = ICDecompressExQuery(hic, 0, in, NULL, 0, 0, 320, 240, &out->bmiHeader, NULL, 0, 0, 640, 480); ok(ret == ICERR_BADFORMAT, "Got %Id.\n", ret); - ret = ICDecompressExQuery(hic, 0, &in, NULL, 0, 0, 320, 240, &out->bmiHeader, NULL, 20, 20, 320, 240); + ret = ICDecompressExQuery(hic, 0, in, NULL, 0, 0, 320, 240, &out->bmiHeader, NULL, 20, 20, 320, 240); ok(ret == ICERR_OK, "Got %Id.\n", ret); - ret = ICDecompressExBegin(hic, 0, &in, NULL, 0, 0, 320, 240, &out->bmiHeader, NULL, 20, 20, 320, 240); + ret = ICDecompressExBegin(hic, 0, in, NULL, 0, 0, 320, 240, &out->bmiHeader, NULL, 20, 20, 320, 240); ok(ret == ICERR_OK, "Got %Id.\n", ret); ret = ICDecompressExEnd(hic); ok(ret == ICERR_OK, "Got %Id.\n", ret); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/9870
participants (2)
-
Bernhard Übelacker -
Bernhard Übelacker (@bernhardu)