Skip to content

Commit 2eb2865

Browse files
committed
[WIN32SS:NTUSER] Improve initialization of window station and desktop objects
As soon as `ObCreateObject()` is successfully invoked, zero-out the winsta and desktop object buffers and assign them the current process session ID (into their first `dwSessionId` member). Only then, continue with regular initialization. It's done in this systematic way in order to ensure that, in case the regular initialization of these objects fails and `ObDereferenceObject()` is invoked, the `nt!ExpWin32SessionCallout()` routine (in `ntoskrnl/ex/win32k.c`) that is executed as part of the Win32 "delete" object callback registered by win32k.sys with the Object Manager, correctly finds a valid initialized `SessionId` value in the "common header" of either the window station or the desktop object being deleted. As a side-result, other parts of win32k can directly refer to `pdesk->dwSessionId` instead of `pdesk->rpwinstaParent->dwSessionId` for a given desktop.
1 parent 1968202 commit 2eb2865

3 files changed

Lines changed: 14 additions & 10 deletions

File tree

win32ss/user/ntuser/desktop.c

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,13 @@ IntDesktopObjectParse(IN PVOID ParseObject,
143143
0,
144144
0,
145145
(PVOID*)&Desktop);
146-
if (!NT_SUCCESS(Status)) return Status;
146+
if (!NT_SUCCESS(Status))
147+
return Status;
148+
RtlZeroMemory(Desktop, sizeof(DESKTOP));
149+
150+
/* Assign the session ID to the desktop */
151+
Desktop->dwSessionId = PsGetCurrentProcessSessionId(); // gSessionId
152+
ASSERT(Desktop->dwSessionId == WinStaObject->dwSessionId);
147153

148154
/* Assign security to the desktop we have created */
149155
Status = IntAssignDesktopSecurityOnParse(WinStaObject, Desktop, AccessState);
@@ -2278,8 +2284,6 @@ UserInitializeDesktop(PDESKTOP pdesk, PUNICODE_STRING DesktopName, PWINSTATION_O
22782284

22792285
TRACE("UserInitializeDesktop desktop 0x%p with name %wZ\n", pdesk, DesktopName);
22802286

2281-
RtlZeroMemory(pdesk, sizeof(DESKTOP));
2282-
22832287
/* Set desktop size, based on whether the WinSta is interactive or not */
22842288
if (pwinsta == InputWindowStation)
22852289
{
@@ -2488,8 +2492,7 @@ IntCreateDesktop(
24882492
}
24892493
pWnd->fnid = FNID_DESKTOP;
24902494

2491-
/* Assign the session ID and the desktop window to the desktop */
2492-
pdesk->dwSessionId = PsGetCurrentProcessSessionId();
2495+
/* Assign the desktop window to the desktop */
24932496
pdesk->DesktopWindow = UserHMGetHandle(pWnd);
24942497
pdesk->pDeskInfo->spwnd = pWnd;
24952498

@@ -2982,7 +2985,7 @@ NtUserSwitchDesktop(HDESK hdesk)
29822985
goto Exit; // Return FALSE
29832986
}
29842987

2985-
if (PsGetCurrentProcessSessionId() != pdesk->rpwinstaParent->dwSessionId)
2988+
if (PsGetCurrentProcessSessionId() != pdesk->dwSessionId)
29862989
{
29872990
ObDereferenceObject(pdesk);
29882991
ERR("NtUserSwitchDesktop called for a desktop of a different session\n");

win32ss/user/ntuser/menu.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -321,7 +321,7 @@ IntDestroyMenuObject(PMENU Menu, BOOL bRecurse)
321321
{
322322
PWND Window;
323323

324-
if (PsGetCurrentProcessSessionId() == Menu->head.rpdesk->rpwinstaParent->dwSessionId)
324+
if (PsGetCurrentProcessSessionId() == Menu->head.rpdesk->dwSessionId)
325325
{
326326
BOOL ret;
327327
if (Menu->hWnd)

win32ss/user/ntuser/winsta.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -504,12 +504,13 @@ IntCreateWindowStation(
504504
SetLastNtError(Status);
505505
return Status;
506506
}
507-
508-
/* Initialize the window station */
509507
RtlZeroMemory(WindowStation, sizeof(WINSTATION_OBJECT));
510508

509+
/* Assign the session ID to the window station */
510+
WindowStation->dwSessionId = PsGetCurrentProcessSessionId(); // gSessionId
511+
512+
/* Initialize the window station */
511513
InitializeListHead(&WindowStation->DesktopListHead);
512-
WindowStation->dwSessionId = NtCurrentPeb()->SessionId;
513514
Status = RtlCreateAtomTable(37, &WindowStation->AtomTable);
514515
if (!NT_SUCCESS(Status))
515516
{

0 commit comments

Comments
 (0)