Skip to content

Commit 1a38c76

Browse files
committed
[NTOS:KD] Protect against invalid user arguments in KdpPrompt. CORE-14057
1 parent 8624801 commit 1a38c76

File tree

3 files changed

+75
-9
lines changed

3 files changed

+75
-9
lines changed

ntoskrnl/include/internal/kd.h

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -199,10 +199,11 @@ KdpPrintString(
199199
ULONG
200200
NTAPI
201201
KdpPrompt(
202-
IN LPSTR InString,
203-
IN USHORT InStringLength,
204-
OUT LPSTR OutString,
205-
IN USHORT OutStringLength
202+
_In_reads_bytes_(InStringLength) PCHAR UnsafeInString,
203+
_In_ USHORT InStringLength,
204+
_Out_writes_bytes_(OutStringLength) PCHAR UnsafeOutString,
205+
_In_ USHORT OutStringLength,
206+
_In_ KPROCESSOR_MODE PreviousMode
206207
);
207208

208209
BOOLEAN

ntoskrnl/kd/kdmain.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,8 @@ KdpEnterDebuggerException(IN PKTRAP_FRAME TrapFrame,
175175
(USHORT)ExceptionRecord->
176176
ExceptionInformation[2],
177177
OutString,
178-
OutStringLength);
178+
OutStringLength,
179+
PreviousMode);
179180

180181
/* Return the number of characters that we received */
181182
Context->Eax = ReturnValue;

ntoskrnl/kdbg/kdb_cli.c

Lines changed: 68 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3662,15 +3662,61 @@ extern KSPIN_LOCK KdpSerialSpinLock;
36623662

36633663
ULONG
36643664
NTAPI
3665-
KdpPrompt(IN LPSTR InString,
3666-
IN USHORT InStringLength,
3667-
OUT LPSTR OutString,
3668-
IN USHORT OutStringLength)
3665+
KdpPrompt(
3666+
_In_reads_bytes_(InStringLength) PCHAR UnsafeInString,
3667+
_In_ USHORT InStringLength,
3668+
_Out_writes_bytes_(OutStringLength) PCHAR UnsafeOutString,
3669+
_In_ USHORT OutStringLength,
3670+
_In_ KPROCESSOR_MODE PreviousMode)
36693671
{
36703672
USHORT i;
36713673
CHAR Response;
36723674
ULONG DummyScanCode;
36733675
KIRQL OldIrql;
3676+
PCHAR InString;
3677+
PCHAR OutString;
3678+
3679+
/* Normalize the lengths */
3680+
InStringLength = min(InStringLength,
3681+
512);
3682+
OutStringLength = min(OutStringLength,
3683+
512);
3684+
3685+
/* Check if we need to verify the string */
3686+
if (PreviousMode != KernelMode)
3687+
{
3688+
/* Handle user-mode buffers safely */
3689+
_SEH2_TRY
3690+
{
3691+
/* Probe the prompt */
3692+
ProbeForRead(UnsafeInString,
3693+
InStringLength,
3694+
1);
3695+
3696+
/* Capture prompt */
3697+
InString = _alloca(InStringLength);
3698+
RtlCopyMemory(InString,
3699+
UnsafeInString,
3700+
InStringLength);
3701+
3702+
/* Probe and make room for response */
3703+
ProbeForWrite(UnsafeOutString,
3704+
OutStringLength,
3705+
1);
3706+
OutString = _alloca(OutStringLength);
3707+
}
3708+
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
3709+
{
3710+
/* Bad string pointer, bail out */
3711+
_SEH2_YIELD(return 0);
3712+
}
3713+
_SEH2_END;
3714+
}
3715+
else
3716+
{
3717+
InString = UnsafeInString;
3718+
OutString = UnsafeOutString;
3719+
}
36743720

36753721
/* Acquire the printing spinlock without waiting at raised IRQL */
36763722
while (TRUE)
@@ -3779,6 +3825,24 @@ KdpPrompt(IN LPSTR InString,
37793825
/* Lower IRQL back */
37803826
KeLowerIrql(OldIrql);
37813827

3828+
/* Copy back response if required */
3829+
if (PreviousMode != KernelMode)
3830+
{
3831+
_SEH2_TRY
3832+
{
3833+
/* Safely copy back response to user mode */
3834+
RtlCopyMemory(UnsafeOutString,
3835+
OutString,
3836+
i);
3837+
}
3838+
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
3839+
{
3840+
/* String became invalid after we exited, fail */
3841+
_SEH2_YIELD(return 0);
3842+
}
3843+
_SEH2_END;
3844+
}
3845+
37823846
/* Return the length */
37833847
return i;
37843848
}

0 commit comments

Comments
 (0)