Module: wine Branch: master Commit: f222a1654ea8f84bc678c9043ad3265b97207dde URL: http://source.winehq.org/git/wine.git/?a=commit;h=f222a1654ea8f84bc678c9043a...
Author: Markus Stockhausen markus.stockhausen@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();