https://git.reactos.org/?p=reactos.git;a=commitdiff;h=2c391b1eab5000f793b63db6ee2e90ffb64280fa

commit 2c391b1eab5000f793b63db6ee2e90ffb64280fa
Author:     Hervé Poussineau <[email protected]>
AuthorDate: Mon Apr 18 19:49:31 2022 +0200
Commit:     Hervé Poussineau <[email protected]>
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 
********************************************************************/

Reply via email to