https://git.reactos.org/?p=reactos.git;a=commitdiff;h=2858ff53ce0bb75f1058b9...
commit 2858ff53ce0bb75f1058b9b3ddb4139d46cb02bb Author: Thomas Faber thomas.faber@reactos.org AuthorDate: Sat Aug 22 21:11:26 2020 +0200 Commit: Thomas Faber thomas.faber@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 */