From aa815e1cfa66f65e1964bbb4cce917c04d56f631 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?George=20Bi=C8=99oc?= Date: Sun, 8 May 2022 00:39:44 +0200 Subject: [PATCH] [WIN32K:NTUSER] Assign a security descriptor when parsing the desktop object The problem ReactOS currently faces is this -- whenever the desktop is being parsed we aren't assigning a security descriptor to it. As a matter of fact when Winlogon tries to assign new security information to the application desktop when a user logs in, Winlogon fails because no prior descriptor has been created for it even though we already do this when initializing security buffers in Winlogon. With that said, we must assign a descriptor when parsing the desktop as well. This fixes a hack in Winlogon where security assigning of application desktop during a log in is disabled (which we can now enable such code path back). --- win32ss/user/ntuser/desktop.c | 8 +++++ win32ss/user/ntuser/security.c | 66 ++++++++++++++++++++++++++++++++++ win32ss/user/ntuser/security.h | 7 ++++ 3 files changed, 81 insertions(+) diff --git a/win32ss/user/ntuser/desktop.c b/win32ss/user/ntuser/desktop.c index fb8d6ed96cd..fcb3a8aa009 100644 --- a/win32ss/user/ntuser/desktop.c +++ b/win32ss/user/ntuser/desktop.c @@ -128,6 +128,14 @@ IntDesktopObjectParse(IN PVOID ParseObject, (PVOID*)&Desktop); if (!NT_SUCCESS(Status)) return Status; + /* Assign security to the desktop we have created */ + Status = IntAssignDesktopSecurityOnParse(WinStaObject, Desktop, AccessState); + if (!NT_SUCCESS(Status)) + { + ObDereferenceObject(Desktop); + return Status; + } + /* Initialize the desktop */ Status = UserInitializeDesktop(Desktop, RemainingName, WinStaObject); if (!NT_SUCCESS(Status)) diff --git a/win32ss/user/ntuser/security.c b/win32ss/user/ntuser/security.c index 0286a76f5e3..276d01bfe16 100644 --- a/win32ss/user/ntuser/security.c +++ b/win32ss/user/ntuser/security.c @@ -235,6 +235,72 @@ IntQueryUserSecurityIdentification( return STATUS_SUCCESS; } +/** + * @brief + * Assigns a security descriptor to the desktop + * object during a desktop object parse procedure. + * + * @param[in] WinSta + * A pointer to a window station object, of which + * such object contains its own security descriptor + * that will be captured. + * + * @param[in] Desktop + * A pointer to a desktop object that is created + * during a parse procedure. + * + * @param[in] AccessState + * A pointer to an access state structure that + * describes the progress state of an access in + * action. + * + * @return + * Returns STATUS_SUCCESS if the function has successfully + * assigned new security descriptor to the desktop object. + * A NTSTATUS failure code is returned otherwise. + */ +NTSTATUS +NTAPI +IntAssignDesktopSecurityOnParse( + _In_ PWINSTATION_OBJECT WinSta, + _In_ PDESKTOP Desktop, + _In_ PACCESS_STATE AccessState) +{ + NTSTATUS Status; + PSECURITY_DESCRIPTOR CapturedDescriptor; + BOOLEAN MemoryAllocated; + + /* + * Capture the security descriptor from + * the window station. The window station + * in question has a descriptor that is + * inheritable and contains desktop access + * rights as well. + */ + Status = ObGetObjectSecurity(WinSta, + &CapturedDescriptor, + &MemoryAllocated); + if (!NT_SUCCESS(Status)) + { + ERR("IntAssignDesktopSecurityOnParse(): Failed to capture the security descriptor from window station (Status 0x%08lx)\n", Status); + return Status; + } + + /* Assign new security to the desktop */ + Status = ObAssignSecurity(AccessState, + CapturedDescriptor, + Desktop, + ExDesktopObjectType); + if (!NT_SUCCESS(Status)) + { + ERR("IntAssignDesktopSecurityOnParse(): Failed to assign security information to the desktop object (Status 0x%08lx)\n", Status); + } + + /* Release the descriptor that we have captured */ + ObReleaseObjectSecurity(CapturedDescriptor, MemoryAllocated); + return Status; +} + /** * @brief * Creates a security descriptor for the service. diff --git a/win32ss/user/ntuser/security.h b/win32ss/user/ntuser/security.h index f719beccc8a..1bbf185ac30 100644 --- a/win32ss/user/ntuser/security.h +++ b/win32ss/user/ntuser/security.h @@ -84,6 +84,13 @@ NTSTATUS IntQueryUserSecurityIdentification( _Out_ PTOKEN_USER *User); +NTSTATUS +NTAPI +IntAssignDesktopSecurityOnParse( + _In_ PWINSTATION_OBJECT WinSta, + _In_ PDESKTOP Desktop, + _In_ PACCESS_STATE AccessState); + NTSTATUS NTAPI IntCreateServiceSecurity(