Avoid crash in CURSORICON_GetFileEntry due to invalid memory access.

Bernhard Übelacker bernhardu at mailbox.org
Sun Jan 28 12:15:44 CST 2018


https://bugs.winehq.org/show_bug.cgi?id=42789

For some reason Qemu or Gtk tries to LoadImageW for "X11 cursor"
share/icons/Adwaita/cursors/00008160000006810000408080010102.

Mapped file has just a size of 69120 bytes.
Unfortunately in function CURSORICON_GetFileEntry entry->dwDIBOffset
contains 1638397.

info = (const BITMAPINFOHEADER *)((const char *)dir + entry->dwDIBOffset);

That way the info variable points to memory outside of the mapped file
while qemu manages to have that memory not available.

Signed-off-by: Bernhard Übelacker <bernhardu at mailbox.org>
---
 dlls/user32/cursoricon.c       | 2 ++
 dlls/user32/tests/cursoricon.c | 8 ++++++++
 2 files changed, 10 insertions(+)

diff --git a/dlls/user32/cursoricon.c b/dlls/user32/cursoricon.c
index 1203250565..1ea1523b61 100644
--- a/dlls/user32/cursoricon.c
+++ b/dlls/user32/cursoricon.c
@@ -678,6 +678,8 @@ static BOOL CURSORICON_GetFileEntry( LPCVOID dir, DWORD size, int n,
     if ((const char *)&filedir->idEntries[n + 1] - (const char *)dir > size)
         return FALSE;
     entry = &filedir->idEntries[n];
+    if (entry->dwDIBOffset + FIELD_OFFSET( BITMAPINFOHEADER, biSize ) + sizeof(info->biSize) > size)
+        return FALSE;
     info = (const BITMAPINFOHEADER *)((const char *)dir + entry->dwDIBOffset);
     if (info->biSize != sizeof(BITMAPCOREHEADER))
     {
diff --git a/dlls/user32/tests/cursoricon.c b/dlls/user32/tests/cursoricon.c
index 211376b180..5099c08d70 100644
--- a/dlls/user32/tests/cursoricon.c
+++ b/dlls/user32/tests/cursoricon.c
@@ -1031,6 +1031,12 @@ static const unsigned char gif4pixel[42] = {
 0x02,0x00,0x00,0x02,0x03,0x14,0x16,0x05,0x00,0x3b
 };
 
+/* An invalid cursor with an invalid dwDIBOffset */
+static const unsigned char invalid_dwDIBOffset[] = {
+  0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00
+};
+
 static const DWORD biSize_tests[] = {
     0,
     sizeof(BITMAPCOREHEADER) - 1,
@@ -1320,6 +1326,8 @@ static void test_LoadImage(void)
         test_LoadImageFile("BMP (broken biSize)", bmpimage, sizeof(bmpimage), "bmp", 0);
     }
     bitmap_header->biSize = sizeof(BITMAPINFOHEADER);
+
+    test_LoadImageFile("Cursor (invalid dwDIBOffset)", invalid_dwDIBOffset, sizeof(invalid_dwDIBOffset), "cur", 0);
 }
 
 #undef ARRAY_SIZE
-- 
2.15.1




More information about the wine-devel mailing list