Markus Stockhausen : ddraw: Avoid memory overwrite in GetDeviceIdentifier() .

Alexandre Julliard julliard at winehq.org
Fri Oct 30 11:04:35 CDT 2009


Module: wine
Branch: master
Commit: f222a1654ea8f84bc678c9043ad3265b97207dde
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=f222a1654ea8f84bc678c9043ad3265b97207dde

Author: Markus Stockhausen <markus.stockhausen at collogia.de>
Date:   Mon Oct 26 15:17:40 2009 +0100

ddraw: Avoid memory overwrite in GetDeviceIdentifier().

---

 dlls/ddraw/ddraw.c            |    6 ++++--
 dlls/ddraw/tests/ddrawmodes.c |   37 +++++++++++++++++++++++++++++++++++++
 2 files changed, 41 insertions(+), 2 deletions(-)

diff --git a/dlls/ddraw/ddraw.c b/dlls/ddraw/ddraw.c
index 726ce7b..351ebda 100644
--- a/dlls/ddraw/ddraw.c
+++ b/dlls/ddraw/ddraw.c
@@ -1543,10 +1543,12 @@ IDirectDrawImpl_GetDeviceIdentifier(IDirectDraw7 *iface,
 
     /* The DDGDI_GETHOSTIDENTIFIER returns the information about the 2D
      * host adapter, if there's a secondary 3D adapter. This doesn't apply
-     * to any modern hardware, nor is it interesting for Wine, so ignore it
+     * to any modern hardware, nor is it interesting for Wine, so ignore it.
+     * Size of DDDEVICEIDENTIFIER2 may be aligned to 8 bytes and thus 4
+     * bytes too long. So only copy the relevant part of the structure
      */
 
-    *DDDI = deviceidentifier;
+    memcpy(DDDI, &deviceidentifier, FIELD_OFFSET(DDDEVICEIDENTIFIER2, dwWHQLLevel) + sizeof(DWORD));
     return DD_OK;
 }
 
diff --git a/dlls/ddraw/tests/ddrawmodes.c b/dlls/ddraw/tests/ddrawmodes.c
index bd8bec7..d8026ef 100644
--- a/dlls/ddraw/tests/ddrawmodes.c
+++ b/dlls/ddraw/tests/ddrawmodes.c
@@ -645,6 +645,42 @@ static void testddraw3(void)
     if(SUCCEEDED(hr) && dd3) IDirectDraw3_Release(dd3);
 }
 
+static void testddraw7(void)
+{
+    IDirectDraw7 *dd7;
+    HRESULT hr;
+    DDDEVICEIDENTIFIER2 *pdddi2;
+    DWORD dddi2Bytes;
+    DWORD *pend;
+
+    hr = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw7, (void **) &dd7);
+    ok(hr==DD_OK, "IDirectDraw7_QueryInterface returned %08x\n", hr);
+
+    if (hr==DD_OK)
+    {
+         dddi2Bytes = FIELD_OFFSET(DDDEVICEIDENTIFIER2, dwWHQLLevel) + sizeof(DWORD);
+
+         pdddi2 = HeapAlloc( GetProcessHeap(), 0, dddi2Bytes + sizeof(DWORD) );
+         pend = (DWORD *)((char *)pdddi2 + dddi2Bytes);
+         *pend = 0xdeadbeef;
+
+         hr = IDirectDraw7_GetDeviceIdentifier(dd7, pdddi2, 0);
+         ok(hr==DD_OK, "get device identifier failed with %08x\n", hr);
+
+         if (hr==DD_OK)
+         {
+             /* check how strings are copied into the structure */
+             ok(pdddi2->szDriver[MAX_DDDEVICEID_STRING - 1]==0, "szDriver not cleared\n");
+             ok(pdddi2->szDescription[MAX_DDDEVICEID_STRING - 1]==0, "szDescription not cleared\n");
+             /* verify that 8 byte structure size alignment will not overwrite memory */
+             ok(*pend==0xdeadbeef, "memory beyond DDDEVICEIDENTIFIER2 overwritten\n");
+         }
+
+         IDirectDraw_Release(dd7);
+         HeapFree( GetProcessHeap(), 0, pdddi2 );
+    }
+}
+
 START_TEST(ddrawmodes)
 {
     init_function_pointers();
@@ -663,6 +699,7 @@ START_TEST(ddrawmodes)
         testdisplaymodes();
     flushdisplaymodes();
     testddraw3();
+    testddraw7();
     releasedirectdraw();
 
     createdirectdraw();




More information about the wine-cvs mailing list