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

commit b783b16cef2e2573b04327678eac73129bffcf44
Author:     Jérôme Gardou <[email protected]>
AuthorDate: Fri Jul 30 15:44:57 2021 +0200
Commit:     Jérôme Gardou <[email protected]>
CommitDate: Tue Aug 3 23:13:19 2021 +0200

    [WIN32K:USER] Fix potential use after free when painting child windows
---
 win32ss/user/ntuser/painting.c | 24 ++++++++++++++++++------
 1 file changed, 18 insertions(+), 6 deletions(-)

diff --git a/win32ss/user/ntuser/painting.c b/win32ss/user/ntuser/painting.c
index eb2815c6442..e0e4893a4b0 100644
--- a/win32ss/user/ntuser/painting.c
+++ b/win32ss/user/ntuser/painting.c
@@ -369,14 +369,26 @@ IntSendNCPaint(PWND pWnd, HRGN hRgn)
 VOID FASTCALL
 IntSendChildNCPaint(PWND pWnd)
 {
-    for (pWnd = pWnd->spwndChild; pWnd; pWnd = pWnd->spwndNext)
+    pWnd = pWnd->spwndChild;
+    while (pWnd)
     {
         if ((pWnd->hrgnUpdate == NULL) && (pWnd->state & WNDS_SENDNCPAINT))
         {
+            PWND Next;
             USER_REFERENCE_ENTRY Ref;
+
+            /* Reference, IntSendNCPaint leaves win32k */
             UserRefObjectCo(pWnd, &Ref);
             IntSendNCPaint(pWnd, HRGN_WINDOW);
+
+            /* Make sure to grab next one before dereferencing/freeing */
+            Next = pWnd->spwndNext;
             UserDerefObjectCo(pWnd);
+            pWnd = Next;
+        }
+        else
+        {
+            pWnd = pWnd->spwndNext;
         }
     }
 }
@@ -530,7 +542,7 @@ co_IntUpdateWindows(PWND Wnd, ULONG Flags, BOOL Recurse)
       Wnd->state &= ~WNDS_UPDATEDIRTY;
 
       Wnd->state2 |= WNDS2_WMPAINTSENT;
-      co_IntSendMessage(hWnd, WM_PAINT, 0, 0); 
+      co_IntSendMessage(hWnd, WM_PAINT, 0, 0);
 
       if (Wnd->state & WNDS_PAINTNOTPROCESSED)
       {
@@ -548,7 +560,7 @@ co_IntUpdateWindows(PWND Wnd, ULONG Flags, BOOL Recurse)
    * Update child windows.
    */
 
-   if (!(Flags & RDW_NOCHILDREN)  && 
+   if (!(Flags & RDW_NOCHILDREN)  &&
         (Flags & RDW_ALLCHILDREN) &&
         !UserIsDesktopWindow(Wnd))
    {
@@ -814,7 +826,7 @@ IntInvalidateWindows(PWND Wnd, PREGION Rgn, ULONG Flags)
    if (!(Flags & RDW_NOCHILDREN) &&
        !(Wnd->style & WS_MINIMIZE) &&
          ((Flags & RDW_ALLCHILDREN) || !(Wnd->style & WS_CLIPCHILDREN)))
-   { 
+   {
       PWND Child;
 
       for (Child = Wnd->spwndChild; Child; Child = Child->spwndNext)
@@ -928,7 +940,7 @@ co_UserRedrawWindow(
             if (Window == UserGetDesktopWindow())
             {
                TmpRgn = IntSysCreateRectpRgnIndirect(UpdateRect);
-            }          
+            }
             else
             {
                TmpRgn = IntSysCreateRectpRgn(Window->rcClient.left + 
UpdateRect->left,
@@ -2164,7 +2176,7 @@ UserDrawCaptionText(
                 (RECTL *)&r,
                  DT_END_ELLIPSIS|DT_SINGLELINE|DT_VCENTER|DT_NOPREFIX|DT_LEFT);
    }
- 
+
    IntGdiSetTextColor(hDc, OldTextColor);
 
    if (hOldFont)

Reply via email to