https://git.reactos.org/?p=reactos.git;a=commitdiff;h=03873aeef396eca773283…
commit 03873aeef396eca773283a71257967b8c0ec7b4b
Author: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org>
AuthorDate: Thu Dec 20 03:32:08 2018 +0100
Commit: Hermès Bélusca-Maïto <hermes.belusca-maito(a)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