https://git.reactos.org/?p=reactos.git;a=commitdiff;h=b783b16cef2e2573b0432…
commit b783b16cef2e2573b04327678eac73129bffcf44
Author: Jérôme Gardou <jerome.gardou(a)reactos.org>
AuthorDate: Fri Jul 30 15:44:57 2021 +0200
Commit: Jérôme Gardou <zefklop(a)users.noreply.github.com>
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)