[NTOS:KD] Avoid large stack buffer in KdpPrint. CORE-17215

This commit is contained in:
Thomas Faber 2020-08-22 21:11:26 +02:00
parent ae1d272add
commit 2858ff53ce
No known key found for this signature in database
GPG key ID: 076E7C3D44720826

View file

@ -13,6 +13,8 @@
#define NDEBUG #define NDEBUG
#include <debug.h> #include <debug.h>
#define KD_PRINT_MAX_BYTES 512
/* FUNCTIONS *****************************************************************/ /* FUNCTIONS *****************************************************************/
BOOLEAN BOOLEAN
@ -224,8 +226,8 @@ KdpPrompt(
STRING PromptBuffer, ResponseBuffer; STRING PromptBuffer, ResponseBuffer;
BOOLEAN Enable, Resend; BOOLEAN Enable, Resend;
PCHAR SafeResponseString; PCHAR SafeResponseString;
CHAR CapturedPrompt[512]; CHAR CapturedPrompt[KD_PRINT_MAX_BYTES];
CHAR SafeResponseBuffer[512]; CHAR SafeResponseBuffer[KD_PRINT_MAX_BYTES];
/* Normalize the lengths */ /* Normalize the lengths */
PromptLength = min(PromptLength, PromptLength = min(PromptLength,
@ -307,6 +309,50 @@ KdpPrompt(
return ResponseBuffer.Length; 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 NTSTATUS
NTAPI NTAPI
KdpPrint( KdpPrint(
@ -322,7 +368,6 @@ KdpPrint(
NTSTATUS Status; NTSTATUS Status;
BOOLEAN Enable; BOOLEAN Enable;
STRING OutputString; STRING OutputString;
CHAR CapturedString[512];
if (NtQueryDebugFilterState(ComponentId, Level) == (NTSTATUS)FALSE) if (NtQueryDebugFilterState(ComponentId, Level) == (NTSTATUS)FALSE)
{ {
@ -335,25 +380,24 @@ KdpPrint(
*Handled = FALSE; *Handled = FALSE;
/* Normalize the length */ /* Normalize the length */
Length = min(Length, sizeof(CapturedString)); Length = min(Length, KD_PRINT_MAX_BYTES);
/* Check if we need to verify the string */ /* Check if we need to verify the string */
if (PreviousMode != KernelMode) if (PreviousMode != KernelMode)
{ {
/* Capture user-mode buffers */ /* This case requires a 512 byte stack buffer.
_SEH2_TRY * 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
/* Probe and capture the string */ * helper function instead.
ProbeForRead(String, Length, 1); */
KdpMoveMemory(CapturedString, String, Length); return KdpPrintFromUser(ComponentId,
String = CapturedString; Level,
} String,
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) Length,
{ PreviousMode,
/* Bad string pointer, bail out */ TrapFrame,
_SEH2_YIELD(return STATUS_ACCESS_VIOLATION); ExceptionFrame,
} Handled);
_SEH2_END;
} }
/* Setup the output string */ /* Setup the output string */