X-Git-Url: https://git.reactos.org/?p=reactos.git;a=blobdiff_plain;f=ntoskrnl%2Fkd64%2Fkdprint.c;h=7604a255ab4774680d6c1f760143fa04862f82c4;hp=06b638c2271698d8e481c1d704354fd5d5e6e266;hb=d6dc1fd2310ed67891edc27a49aacc2eb11220f3;hpb=b819608ed8503c9668a797e62597645d99261eaf diff --git a/ntoskrnl/kd64/kdprint.c b/ntoskrnl/kd64/kdprint.c index 06b638c2271..7604a255ab4 100644 --- a/ntoskrnl/kd64/kdprint.c +++ b/ntoskrnl/kd64/kdprint.c @@ -21,12 +21,15 @@ KdpPrintString(IN PSTRING Output) { 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 */ @@ -59,15 +62,16 @@ KdpPromptString(IN PSTRING PromptString, { 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 */ @@ -84,7 +88,7 @@ KdpPromptString(IN PSTRING PromptString, Header.Buffer = (PCHAR)&DebugIo; /* Build the data */ - Data.Length = PromptString->Length; + Data.Length = Length; Data.Buffer = KdpMessageBuffer; /* Send the packet */ @@ -111,10 +115,13 @@ KdpPromptString(IN PSTRING PromptString, } 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 */ @@ -141,7 +148,7 @@ KdpCommandString(IN PSTRING NameString, /* Save the CPU Control State and save the context */ KiSaveProcessorControlState(&Prcb->ProcessorState); - RtlCopyMemory(&Prcb->ProcessorState.ContextFrame, + KdpMoveMemory(&Prcb->ProcessorState.ContextFrame, ContextRecord, sizeof(CONTEXT)); @@ -151,7 +158,7 @@ KdpCommandString(IN PSTRING NameString, &Prcb->ProcessorState.ContextFrame); /* Restore the processor state */ - RtlCopyMemory(ContextRecord, + KdpMoveMemory(ContextRecord, &Prcb->ProcessorState.ContextFrame, sizeof(CONTEXT)); KiRestoreProcessorControlState(&Prcb->ProcessorState); @@ -181,7 +188,7 @@ KdpSymbol(IN PSTRING DllPath, /* Save the CPU Control State and save the context */ KiSaveProcessorControlState(&Prcb->ProcessorState); - RtlCopyMemory(&Prcb->ProcessorState.ContextFrame, + KdpMoveMemory(&Prcb->ProcessorState.ContextFrame, ContextRecord, sizeof(CONTEXT)); @@ -192,7 +199,7 @@ KdpSymbol(IN PSTRING DllPath, &Prcb->ProcessorState.ContextFrame); /* Restore the processor state */ - RtlCopyMemory(ContextRecord, + KdpMoveMemory(ContextRecord, &Prcb->ProcessorState.ContextFrame, sizeof(CONTEXT)); KiRestoreProcessorControlState(&Prcb->ProcessorState); @@ -205,7 +212,7 @@ USHORT 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, @@ -213,21 +220,55 @@ KdpPrompt(IN LPSTR PromptString, { 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; @@ -249,6 +290,24 @@ KdpPrompt(IN LPSTR PromptString, /* 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; } @@ -267,6 +326,7 @@ KdpPrint(IN ULONG ComponentId, NTSTATUS ReturnStatus; BOOLEAN Enable; STRING OutputString; + PVOID CapturedString; /* Assume failure */ *Handled = FALSE; @@ -288,7 +348,27 @@ KdpPrint(IN ULONG ComponentId, /* 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 */