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

Reply via email to