[WIN32K:NTUSER] Detect when the NtUserCreateWindowStation() caller has provided an empty window station name, and if so, generate a name in the format: "Service-0x<luidhigh>-<luidlow>$" .

CORE-11933 and PR #621.
This commit is contained in:
Hermès Bélusca-Maïto 2018-06-16 19:45:20 +02:00
parent ba018294d3
commit dae57caa36
No known key found for this signature in database
GPG key ID: 3B2539C65E7B93D0

View file

@ -512,6 +512,7 @@ NtUserCreateWindowStation(
HWINSTA hWinSta; HWINSTA hWinSta;
OBJECT_ATTRIBUTES LocalObjectAttributes; OBJECT_ATTRIBUTES LocalObjectAttributes;
UNICODE_STRING WindowStationName; UNICODE_STRING WindowStationName;
KPROCESSOR_MODE AccessMode = UserMode;
TRACE("NtUserCreateWindowStation called\n"); TRACE("NtUserCreateWindowStation called\n");
@ -520,10 +521,22 @@ NtUserCreateWindowStation(
{ {
ProbeForRead(ObjectAttributes, sizeof(OBJECT_ATTRIBUTES), sizeof(ULONG)); ProbeForRead(ObjectAttributes, sizeof(OBJECT_ATTRIBUTES), sizeof(ULONG));
LocalObjectAttributes = *ObjectAttributes; LocalObjectAttributes = *ObjectAttributes;
if (LocalObjectAttributes.ObjectName ||
LocalObjectAttributes.RootDirectory
/* &&
LocalObjectAttributes.ObjectName->Buffer &&
LocalObjectAttributes.ObjectName->Length > 0 */)
{
Status = IntSafeCopyUnicodeStringTerminateNULL(&WindowStationName, Status = IntSafeCopyUnicodeStringTerminateNULL(&WindowStationName,
LocalObjectAttributes.ObjectName); LocalObjectAttributes.ObjectName);
LocalObjectAttributes.ObjectName = &WindowStationName; LocalObjectAttributes.ObjectName = &WindowStationName;
} }
else
{
LocalObjectAttributes.ObjectName = NULL;
Status = STATUS_SUCCESS;
}
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{ {
Status =_SEH2_GetExceptionCode(); Status =_SEH2_GetExceptionCode();
@ -537,11 +550,64 @@ NtUserCreateWindowStation(
return NULL; return NULL;
} }
/*
* If the caller did not provide a window station name, build a new one
* based on the logon session identifier for the calling process.
*/
if (!LocalObjectAttributes.ObjectName)
{
LUID CallerLuid;
WCHAR ServiceWinStaName[MAX_PATH];
/* Retrieve the LUID of the current process */
Status = GetProcessLuid(NULL, NULL, &CallerLuid);
if (!NT_SUCCESS(Status))
{
ERR("Failed to retrieve the caller LUID, Status 0x%08lx\n", Status);
SetLastNtError(Status);
return NULL;
}
/* Build a valid window station name from the LUID */
Status = RtlStringCbPrintfW(ServiceWinStaName,
sizeof(ServiceWinStaName),
L"%wZ\\Service-0x%x-%x$",
&gustrWindowStationsDir,
CallerLuid.HighPart,
CallerLuid.LowPart);
if (!NT_SUCCESS(Status))
{
ERR("Impossible to build a valid window station name, Status 0x%08lx\n", Status);
SetLastNtError(Status);
return NULL;
}
WindowStationName.Length = wcslen(ServiceWinStaName) * sizeof(WCHAR);
WindowStationName.MaximumLength =
WindowStationName.Length + sizeof(UNICODE_NULL);
WindowStationName.Buffer =
ExAllocatePoolWithTag(PagedPool,
WindowStationName.MaximumLength,
TAG_STRING);
if (!WindowStationName.Buffer)
{
Status = STATUS_NO_MEMORY;
ERR("Impossible to build a valid window station name, Status 0x%08lx\n", Status);
SetLastNtError(Status);
return NULL;
}
RtlStringCbCopyW(WindowStationName.Buffer,
WindowStationName.MaximumLength,
ServiceWinStaName);
LocalObjectAttributes.ObjectName = &WindowStationName;
AccessMode = KernelMode;
}
// TODO: Capture and use the SecurityQualityOfService! // TODO: Capture and use the SecurityQualityOfService!
Status = IntCreateWindowStation(&hWinSta, Status = IntCreateWindowStation(&hWinSta,
&LocalObjectAttributes, &LocalObjectAttributes,
UserMode, AccessMode,
dwDesiredAccess, dwDesiredAccess,
Unknown2, Unknown2,
Unknown3, Unknown3,