https://git.reactos.org/?p=reactos.git;a=commitdiff;h=2c391b1eab5000f793b63…
commit 2c391b1eab5000f793b63db6ee2e90ffb64280fa
Author: Hervé Poussineau <hpoussin(a)reactos.org>
AuthorDate: Mon Apr 18 19:49:31 2022 +0200
Commit: Hervé Poussineau <hpoussin(a)reactos.org>
CommitDate: Mon Apr 18 20:01:37 2022 +0200
[WIN32SS] Fix buffer overflow in MDEVOBJ when having more than 10 display devices
---
win32ss/gdi/eng/mdevobj.c | 20 +++++++++++++++++++-
win32ss/gdi/eng/mdevobj.h | 10 ++++++----
2 files changed, 25 insertions(+), 5 deletions(-)
diff --git a/win32ss/gdi/eng/mdevobj.c b/win32ss/gdi/eng/mdevobj.c
index 2bc3b54d03f..2b6ce26b0ca 100644
--- a/win32ss/gdi/eng/mdevobj.c
+++ b/win32ss/gdi/eng/mdevobj.c
@@ -73,7 +73,7 @@ MDEVOBJ_Create(
pdm ? pdm->dmBitsPerPel : 0,
pdm ? pdm->dmDisplayFrequency : 0);
- pmdev = ExAllocatePoolZero(PagedPool, sizeof(MDEVOBJ), GDITAG_MDEV);
+ pmdev = ExAllocatePoolZero(PagedPool, sizeof(MDEVOBJ) + sizeof(MDEVDISPLAY),
GDITAG_MDEV);
if (!pmdev)
{
ERR("Failed to allocate memory for MDEV\n");
@@ -170,6 +170,24 @@ MDEVOBJ_Create(
if (ppdev)
{
/* Great. We have a found a matching PDEV. Store it in MDEV */
+ if (pmdev->cDev >= 1)
+ {
+ /* We have to reallocate MDEV to add space for the new display */
+ PMDEVOBJ pmdevBigger = ExAllocatePoolZero(PagedPool, sizeof(MDEVOBJ) +
(pmdev->cDev + 1) * sizeof(MDEVDISPLAY), GDITAG_MDEV);
+ if (!pmdevBigger)
+ {
+ WARN("Failed to allocate memory for MDEV. Skipping display
'%S'\n", pGraphicsDevice->szWinDeviceName);
+ continue;
+ }
+ else
+ {
+ /* Copy existing data */
+ RtlCopyMemory(pmdevBigger, pmdev, sizeof(MDEVOBJ) + pmdev->cDev *
sizeof(MDEVDISPLAY));
+ ExFreePoolWithTag(pmdev, GDITAG_MDEV);
+ pmdev = pmdevBigger;
+ }
+ }
+
TRACE("Adding '%S' to MDEV %p\n",
pGraphicsDevice->szWinDeviceName, pmdev);
PDEVOBJ_vReference(ppdev);
pmdev->dev[pmdev->cDev].ppdev = ppdev;
diff --git a/win32ss/gdi/eng/mdevobj.h b/win32ss/gdi/eng/mdevobj.h
index 6dfb7aea4cf..9da0f0a89e9 100644
--- a/win32ss/gdi/eng/mdevobj.h
+++ b/win32ss/gdi/eng/mdevobj.h
@@ -5,14 +5,16 @@
typedef struct _PDEVOBJ *PPDEVOBJ;
+typedef struct _MDEVDISPLAY
+{
+ PPDEVOBJ ppdev;
+} MDEVDISPLAY, *PMDEVDISPLAY;
+
typedef struct _MDEVOBJ
{
ULONG cDev;
PPDEVOBJ ppdevGlobal;
- struct
- {
- PPDEVOBJ ppdev;
- } dev[10]; /* FIXME: max number of displays. Needs dynamic allocation */
+ MDEVDISPLAY dev[0];
} MDEVOBJ, *PMDEVOBJ;
/* Globals ********************************************************************/