https://git.reactos.org/?p=reactos.git;a=commitdiff;h=03873aeef396eca773283a71257967b8c0ec7b4b
commit 03873aeef396eca773283a71257967b8c0ec7b4b Author: Hermès Bélusca-Maïto <hermes.belusca-ma...@reactos.org> AuthorDate: Thu Dec 20 03:32:08 2018 +0100 Commit: Hermès Bélusca-Maïto <hermes.belusca-ma...@reactos.org> CommitDate: Thu Dec 20 03:47:36 2018 +0100 [NTOS] Fixes for NtDisplayString(). - Require the user to have TCB privilege for using this function. - Probe and capture the user-provided string (and avoid usermode-triggered BSODS ;-) - Allocate the OEM-converted string in *NonPagedPool* because we are going to transmit the buffer to BOOTVID. --- ntoskrnl/inbv/inbv.c | 61 +++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 56 insertions(+), 5 deletions(-) diff --git a/ntoskrnl/inbv/inbv.c b/ntoskrnl/inbv/inbv.c index cb6af3e4bf..75825d0aa2 100644 --- a/ntoskrnl/inbv/inbv.c +++ b/ntoskrnl/inbv/inbv.c @@ -5,6 +5,10 @@ #include <debug.h> #include "bootvid/bootvid.h" +#ifndef TAG_OSTR +#define TAG_OSTR 'RTSO' +#endif + /* GLOBALS *******************************************************************/ /* @@ -771,15 +775,62 @@ NTSTATUS NTAPI NtDisplayString(IN PUNICODE_STRING DisplayString) { + NTSTATUS Status; + UNICODE_STRING CapturedString; OEM_STRING OemString; + KPROCESSOR_MODE PreviousMode; + + PAGED_CODE(); + + PreviousMode = ExGetPreviousMode(); + + /* We require the TCB privilege */ + if (!SeSinglePrivilegeCheck(SeTcbPrivilege, PreviousMode)) + return STATUS_PRIVILEGE_NOT_HELD; + + /* Capture the string */ + Status = ProbeAndCaptureUnicodeString(&CapturedString, PreviousMode, DisplayString); + if (!NT_SUCCESS(Status)) + return Status; + + /* Do not display the string if it is empty */ + if (CapturedString.Length == 0 || CapturedString.Buffer == NULL) + { + Status = STATUS_SUCCESS; + goto Quit; + } - /* Convert the string to OEM and display it */ - RtlUnicodeStringToOemString(&OemString, DisplayString, TRUE); + /* + * Convert the string since INBV understands only ANSI/OEM. Allocate the + * string buffer in non-paged pool because INBV passes it down to BOOTVID. + * We cannot perform the allocation using RtlUnicodeStringToOemString() + * since its allocator uses PagedPool. + */ + RtlInitEmptyAnsiString((PANSI_STRING)&OemString, NULL, + RtlUnicodeStringToOemSize(&CapturedString)); + OemString.Buffer = ExAllocatePoolWithTag(NonPagedPool, + OemString.MaximumLength, + TAG_OSTR); + if (OemString.Buffer == NULL) + { + Status = STATUS_NO_MEMORY; + goto Quit; + } + RtlUnicodeStringToOemString(&OemString, &CapturedString, FALSE); + + /* Display the string */ InbvDisplayString(OemString.Buffer); - RtlFreeOemString(&OemString); - /* Return success */ - return STATUS_SUCCESS; + /* Free the string buffer */ + ExFreePoolWithTag(OemString.Buffer, TAG_OSTR); + + Status = STATUS_SUCCESS; + +Quit: + /* Free the captured string */ + ReleaseCapturedUnicodeString(&CapturedString, PreviousMode); + + return Status; } #ifdef INBV_ROTBAR_IMPLEMENTED