[WIN32SS:NTUSER] Update SetWindowStationUser() and NtUserSetWindowStationUser() prototypes.

Also, improve NtUserSetWindowStationUser() capture order, make psid optional as it should (and avoid a user-mode triggered BSOD), and initialize luidUser only when everything succeeded.
This commit is contained in:
Hermès Bélusca-Maïto 2018-07-08 20:39:19 +02:00
parent 9bf7fb6f42
commit b003d68ca5
No known key found for this signature in database
GPG key ID: 3B2539C65E7B93D0
3 changed files with 61 additions and 33 deletions

View file

@ -3289,10 +3289,10 @@ NtUserSetWindowsHookEx(
BOOL BOOL
NTAPI NTAPI
NtUserSetWindowStationUser( NtUserSetWindowStationUser(
HWINSTA hWindowStation, IN HWINSTA hWindowStation,
PLUID pluid, IN PLUID pluid,
PSID psid, IN PSID psid OPTIONAL,
DWORD size); IN DWORD size);
WORD WORD
NTAPI NTAPI

View file

@ -1482,16 +1482,18 @@ NtUserLockWorkStation(VOID)
return ret; return ret;
} }
BOOL APIENTRY BOOL
NTAPI
NtUserSetWindowStationUser( NtUserSetWindowStationUser(
HWINSTA hWindowStation, IN HWINSTA hWindowStation,
PLUID pluid, IN PLUID pluid,
PSID psid, IN PSID psid OPTIONAL,
DWORD size) IN DWORD size)
{ {
BOOL Ret = FALSE;
NTSTATUS Status; NTSTATUS Status;
PWINSTATION_OBJECT WindowStation = NULL; PWINSTATION_OBJECT WindowStation = NULL;
BOOL Ret = FALSE; LUID luidUser;
UserEnterExclusive(); UserEnterExclusive();
@ -1501,21 +1503,43 @@ NtUserSetWindowStationUser(
goto Leave; goto Leave;
} }
/* Validate the window station */
Status = IntValidateWindowStationHandle(hWindowStation, Status = IntValidateWindowStationHandle(hWindowStation,
UserMode, UserMode,
0, 0,
&WindowStation, &WindowStation,
0); NULL);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
goto Leave; goto Leave;
} }
/* Capture the user LUID */
_SEH2_TRY
{
ProbeForRead(pluid, sizeof(LUID), 1);
luidUser = *pluid;
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
Status = _SEH2_GetExceptionCode();
_SEH2_YIELD(goto Leave);
}
_SEH2_END;
/* Reset the window station user LUID */
RtlZeroMemory(&WindowStation->luidUser, sizeof(LUID));
/* Reset the window station user SID */
if (WindowStation->psidUser) if (WindowStation->psidUser)
{ {
ExFreePoolWithTag(WindowStation->psidUser, USERTAG_SECURITY); ExFreePoolWithTag(WindowStation->psidUser, USERTAG_SECURITY);
WindowStation->psidUser = NULL;
} }
/* Copy the new user SID if one has been provided */
if (psid)
{
WindowStation->psidUser = ExAllocatePoolWithTag(PagedPool, size, USERTAG_SECURITY); WindowStation->psidUser = ExAllocatePoolWithTag(PagedPool, size, USERTAG_SECURITY);
if (WindowStation->psidUser == NULL) if (WindowStation->psidUser == NULL)
{ {
@ -1523,13 +1547,11 @@ NtUserSetWindowStationUser(
goto Leave; goto Leave;
} }
Status = STATUS_SUCCESS;
_SEH2_TRY _SEH2_TRY
{ {
ProbeForRead(psid, size, 1); ProbeForRead(psid, size, 1);
ProbeForRead(pluid, sizeof(LUID), 1);
RtlCopyMemory(WindowStation->psidUser, psid, size); RtlCopyMemory(WindowStation->psidUser, psid, size);
WindowStation->luidUser = *pluid;
} }
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{ {
@ -1543,11 +1565,17 @@ NtUserSetWindowStationUser(
WindowStation->psidUser = NULL; WindowStation->psidUser = NULL;
goto Leave; goto Leave;
} }
}
/* Copy the new user LUID */
WindowStation->luidUser = luidUser;
Ret = TRUE; Ret = TRUE;
Leave: Leave:
if (WindowStation) ObDereferenceObject(WindowStation); if (WindowStation)
ObDereferenceObject(WindowStation);
UserLeave(); UserLeave();
return Ret; return Ret;
} }

View file

@ -399,8 +399,8 @@ BOOL
WINAPI WINAPI
SetWindowStationUser( SetWindowStationUser(
IN HWINSTA hWindowStation, IN HWINSTA hWindowStation,
IN PLUID pluid OPTIONAL, IN PLUID pluid,
IN PSID psid, IN PSID psid OPTIONAL,
IN DWORD size) IN DWORD size)
{ {
BOOL Success; BOOL Success;
@ -410,7 +410,7 @@ SetWindowStationUser(
{ {
/* Signal log-on/off to WINSRV */ /* Signal log-on/off to WINSRV */
/* User is logging on if pluid != LuidNone, otherwise it is a log-off */ /* User is logging on if *pluid != LuidNone, otherwise it is a log-off */
LUID LuidNone = {0, 0}; LUID LuidNone = {0, 0};
BOOL IsLogon = (pluid && !RtlEqualLuid(pluid, &LuidNone)); BOOL IsLogon = (pluid && !RtlEqualLuid(pluid, &LuidNone));