{
STRING Data, Header;
DBGKD_DEBUG_IO DebugIo;
- USHORT Length = Output->Length;
+ USHORT Length;
/* Copy the string */
- RtlMoveMemory(KdpMessageBuffer, Output->Buffer, Length);
+ KdpMoveMemory(KdpMessageBuffer,
+ Output->Buffer,
+ Output->Length);
/* Make sure we don't exceed the KD Packet size */
+ Length = Output->Length;
if ((sizeof(DBGKD_DEBUG_IO) + Length) > PACKET_MAX_SIZE)
{
/* Normalize length */
{
STRING Data, Header;
DBGKD_DEBUG_IO DebugIo;
- ULONG Length = PromptString->Length;
+ ULONG Length;
KDSTATUS Status;
/* Copy the string to the message buffer */
- RtlCopyMemory(KdpMessageBuffer,
+ KdpMoveMemory(KdpMessageBuffer,
PromptString->Buffer,
PromptString->Length);
/* Make sure we don't exceed the KD Packet size */
+ Length = PromptString->Length;
if ((sizeof(DBGKD_DEBUG_IO) + Length) > PACKET_MAX_SIZE)
{
/* Normalize length */
Header.Buffer = (PCHAR)&DebugIo;
/* Build the data */
- Data.Length = PromptString->Length;
+ Data.Length = Length;
Data.Buffer = KdpMessageBuffer;
/* Send the packet */
} while (Status != KdPacketReceived);
/* Don't copy back a larger response than there is room for */
- Length = min(Length, ResponseString->MaximumLength);
+ Length = min(Length,
+ ResponseString->MaximumLength);
/* Copy back the string and return the length */
- RtlCopyMemory(ResponseString->Buffer, KdpMessageBuffer, Length);
+ KdpMoveMemory(ResponseString->Buffer,
+ KdpMessageBuffer,
+ Length);
ResponseString->Length = (USHORT)Length;
/* Success; we don't need to resend */
/* Save the CPU Control State and save the context */
KiSaveProcessorControlState(&Prcb->ProcessorState);
- RtlCopyMemory(&Prcb->ProcessorState.ContextFrame,
+ KdpMoveMemory(&Prcb->ProcessorState.ContextFrame,
ContextRecord,
sizeof(CONTEXT));
&Prcb->ProcessorState.ContextFrame);
/* Restore the processor state */
- RtlCopyMemory(ContextRecord,
+ KdpMoveMemory(ContextRecord,
&Prcb->ProcessorState.ContextFrame,
sizeof(CONTEXT));
KiRestoreProcessorControlState(&Prcb->ProcessorState);
/* Save the CPU Control State and save the context */
KiSaveProcessorControlState(&Prcb->ProcessorState);
- RtlCopyMemory(&Prcb->ProcessorState.ContextFrame,
+ KdpMoveMemory(&Prcb->ProcessorState.ContextFrame,
ContextRecord,
sizeof(CONTEXT));
&Prcb->ProcessorState.ContextFrame);
/* Restore the processor state */
- RtlCopyMemory(ContextRecord,
+ KdpMoveMemory(ContextRecord,
&Prcb->ProcessorState.ContextFrame,
sizeof(CONTEXT));
KiRestoreProcessorControlState(&Prcb->ProcessorState);
NTAPI
KdpPrompt(IN LPSTR PromptString,
IN USHORT PromptLength,
- OUT LPSTR ResponseString,
+ OUT PCHAR ResponseString,
IN USHORT MaximumResponseLength,
IN KPROCESSOR_MODE PreviousMode,
IN PKTRAP_FRAME TrapFrame,
{
STRING PromptBuffer, ResponseBuffer;
BOOLEAN Enable, Resend;
+ CHAR CapturedPrompt[512];
+ CHAR SafeResponseBuffer[512];
+ PCHAR SafeResponseString;
/* Normalize the lengths */
- PromptLength = min(PromptLength, 512);
- MaximumResponseLength = min(MaximumResponseLength, 512);
+ PromptLength = min(PromptLength,
+ sizeof(CapturedPrompt));
+ MaximumResponseLength = min(MaximumResponseLength,
+ sizeof(SafeResponseBuffer));
/* Check if we need to verify the string */
if (PreviousMode != KernelMode)
{
- /* FIXME: Handle user-mode */
+ /* Handle user-mode buffers safely */
+ _SEH2_TRY
+ {
+ /* Probe the prompt */
+ ProbeForRead(PromptString,
+ PromptLength,
+ 1);
+
+ /* Capture prompt */
+ KdpMoveMemory(CapturedPrompt,
+ PromptString,
+ PromptLength);
+ PromptString = CapturedPrompt;
+
+ /* Probe and make room for response */
+ ProbeForWrite(ResponseString,
+ MaximumResponseLength,
+ 1);
+ SafeResponseString = SafeResponseBuffer;
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ /* Bad string pointer, bail out */
+ _SEH2_YIELD(return 0);
+ }
+ _SEH2_END;
+ }
+ else
+ {
+ SafeResponseString = ResponseString;
}
/* Setup the prompt and response buffers */
PromptBuffer.Buffer = PromptString;
PromptBuffer.Length = PromptLength;
- ResponseBuffer.Buffer = ResponseString;
+ ResponseBuffer.Buffer = SafeResponseString;
ResponseBuffer.Length = 0;
ResponseBuffer.MaximumLength = MaximumResponseLength;
/* Exit the debugger */
KdExitDebugger(Enable);
+ /* Copy back response if required */
+ if (PreviousMode != KernelMode)
+ {
+ _SEH2_TRY
+ {
+ /* Safely copy back response to user mode */
+ KdpMoveMemory(ResponseString,
+ ResponseBuffer.Buffer,
+ ResponseBuffer.Length);
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ /* String became invalid after we exited, fail */
+ _SEH2_YIELD(return 0);
+ }
+ _SEH2_END;
+ }
+
/* Return the number of characters received */
return ResponseBuffer.Length;
}
NTSTATUS ReturnStatus;
BOOLEAN Enable;
STRING OutputString;
+ PVOID CapturedString;
/* Assume failure */
*Handled = FALSE;
/* Check if we need to verify the buffer */
if (PreviousMode != KernelMode)
{
- /* FIXME: Support user-mode */
+ /* Capture user-mode buffers */
+ _SEH2_TRY
+ {
+ /* Probe the string */
+ ProbeForRead(String,
+ Length,
+ 1);
+
+ /* Capture it */
+ CapturedString = alloca(Length);
+ KdpMoveMemory(CapturedString,
+ String,
+ Length);
+ String = CapturedString;
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ /* Bad pointer, fail the print */
+ _SEH2_YIELD(return STATUS_ACCESS_VIOLATION);
+ }
+ _SEH2_END;
}
/* Setup the output string */