[NTOSKRNL] Only allow SYSTEM to call NtSetUuidSeed()

Also, validate input buffer before attempting any operation on it.
This will avoid userland applications to be able to trigger an invalid
read in the kernel (and thus a BSOD).

Regarding access restriction, see:
https://stackoverflow.com/questions/1254244/need-access-to-ntsetuuidseed-from-a-non-localsystem-process

CORE-15460
This commit is contained in:
Pierre Schweitzer 2018-12-18 23:08:19 +01:00
parent 36c1b87a0b
commit 6ca1c55c6e
No known key found for this signature in database
GPG key ID: 7545556C3D585B0B

View file

@ -377,12 +377,58 @@ NTSTATUS
NTAPI
NtSetUuidSeed(IN PUCHAR Seed)
{
NTSTATUS Status;
BOOLEAN GotContext;
PACCESS_TOKEN Token;
SECURITY_SUBJECT_CONTEXT SubjectContext;
LUID CallerLuid, SystemLuid = SYSTEM_LUID;
PAGED_CODE();
RtlCopyMemory(UuidSeed,
Seed,
SEED_BUFFER_SIZE);
return STATUS_SUCCESS;
/* Should only be done by umode */
ASSERT(KeGetPreviousMode() != KernelMode);
/* No context to release */
GotContext = FALSE;
_SEH2_TRY
{
/* Get our caller context and remember to release it */
SeCaptureSubjectContext(&SubjectContext);
GotContext = TRUE;
/* Get caller access token and its associated ID */
Token = SeQuerySubjectContextToken(&SubjectContext);
Status = SeQueryAuthenticationIdToken(Token, &CallerLuid);
if (!NT_SUCCESS(Status))
{
RtlRaiseStatus(Status);
}
/* This call is only allowed for SYSTEM */
if (!RtlEqualLuid(&CallerLuid, &SystemLuid))
{
RtlRaiseStatus(STATUS_ACCESS_DENIED);
}
/* Check for buffer validity and then copy it to our seed */
ProbeForRead(Seed, SEED_BUFFER_SIZE, 1);
RtlCopyMemory(UuidSeed, Seed, SEED_BUFFER_SIZE);
Status = STATUS_SUCCESS;
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
Status = _SEH2_GetExceptionCode();
}
_SEH2_END;
/* Release context if required */
if (GotContext)
{
SeReleaseSubjectContext(&SubjectContext);
}
return Status;
}
/* EOF */