https://git.reactos.org/?p=reactos.git;a=commitdiff;h=2858ff53ce0bb75f1058b…
commit 2858ff53ce0bb75f1058b9b3ddb4139d46cb02bb
Author: Thomas Faber <thomas.faber(a)reactos.org>
AuthorDate: Sat Aug 22 21:11:26 2020 +0200
Commit: Thomas Faber <thomas.faber(a)reactos.org>
CommitDate: Fri Nov 27 10:31:45 2020 +0100
[NTOS:KD] Avoid large stack buffer in KdpPrint. CORE-17215
---
ntoskrnl/kd64/kdprint.c | 80 ++++++++++++++++++++++++++++++++++++++-----------
1 file changed, 62 insertions(+), 18 deletions(-)
diff --git a/ntoskrnl/kd64/kdprint.c b/ntoskrnl/kd64/kdprint.c
index 9932798fbde..a086652ddb3 100644
--- a/ntoskrnl/kd64/kdprint.c
+++ b/ntoskrnl/kd64/kdprint.c
@@ -13,6 +13,8 @@
#define NDEBUG
#include <debug.h>
+#define KD_PRINT_MAX_BYTES 512
+
/* FUNCTIONS *****************************************************************/
BOOLEAN
@@ -224,8 +226,8 @@ KdpPrompt(
STRING PromptBuffer, ResponseBuffer;
BOOLEAN Enable, Resend;
PCHAR SafeResponseString;
- CHAR CapturedPrompt[512];
- CHAR SafeResponseBuffer[512];
+ CHAR CapturedPrompt[KD_PRINT_MAX_BYTES];
+ CHAR SafeResponseBuffer[KD_PRINT_MAX_BYTES];
/* Normalize the lengths */
PromptLength = min(PromptLength,
@@ -307,6 +309,50 @@ KdpPrompt(
return ResponseBuffer.Length;
}
+static
+NTSTATUS
+NTAPI
+KdpPrintFromUser(
+ _In_ ULONG ComponentId,
+ _In_ ULONG Level,
+ _In_reads_bytes_(Length) PCHAR String,
+ _In_ USHORT Length,
+ _In_ KPROCESSOR_MODE PreviousMode,
+ _In_ PKTRAP_FRAME TrapFrame,
+ _In_ PKEXCEPTION_FRAME ExceptionFrame,
+ _Out_ PBOOLEAN Handled)
+{
+ CHAR CapturedString[KD_PRINT_MAX_BYTES];
+
+ ASSERT(PreviousMode == UserMode);
+ ASSERT(Length <= sizeof(CapturedString));
+
+ /* Capture user-mode buffers */
+ _SEH2_TRY
+ {
+ /* Probe and capture the string */
+ ProbeForRead(String, Length, 1);
+ KdpMoveMemory(CapturedString, String, Length);
+ String = CapturedString;
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ /* Bad string pointer, bail out */
+ _SEH2_YIELD(return STATUS_ACCESS_VIOLATION);
+ }
+ _SEH2_END;
+
+ /* Now go through the kernel-mode code path */
+ return KdpPrint(ComponentId,
+ Level,
+ String,
+ Length,
+ KernelMode,
+ TrapFrame,
+ ExceptionFrame,
+ Handled);
+}
+
NTSTATUS
NTAPI
KdpPrint(
@@ -322,7 +368,6 @@ KdpPrint(
NTSTATUS Status;
BOOLEAN Enable;
STRING OutputString;
- CHAR CapturedString[512];
if (NtQueryDebugFilterState(ComponentId, Level) == (NTSTATUS)FALSE)
{
@@ -335,25 +380,24 @@ KdpPrint(
*Handled = FALSE;
/* Normalize the length */
- Length = min(Length, sizeof(CapturedString));
+ Length = min(Length, KD_PRINT_MAX_BYTES);
/* Check if we need to verify the string */
if (PreviousMode != KernelMode)
{
- /* Capture user-mode buffers */
- _SEH2_TRY
- {
- /* Probe and capture the string */
- ProbeForRead(String, Length, 1);
- KdpMoveMemory(CapturedString, String, Length);
- String = CapturedString;
- }
- _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
- {
- /* Bad string pointer, bail out */
- _SEH2_YIELD(return STATUS_ACCESS_VIOLATION);
- }
- _SEH2_END;
+ /* This case requires a 512 byte stack buffer.
+ * We don't want to use that much stack in the kernel case, but we
+ * can't use _alloca due to PSEH. So the buffer exists in this
+ * helper function instead.
+ */
+ return KdpPrintFromUser(ComponentId,
+ Level,
+ String,
+ Length,
+ PreviousMode,
+ TrapFrame,
+ ExceptionFrame,
+ Handled);
}
/* Setup the output string */