[NTOS:KD] Fix wrong debug level checking logic in KdpPrint.
[reactos.git] / ntoskrnl / kd64 / kdprint.c
index 06b638c..81da68b 100644 (file)
 
 /* FUNCTIONS *****************************************************************/
 
+#ifdef _WINKD_
+
 BOOLEAN
 NTAPI
-KdpPrintString(IN PSTRING Output)
+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 */
@@ -54,20 +60,22 @@ KdpPrintString(IN PSTRING Output)
 
 BOOLEAN
 NTAPI
-KdpPromptString(IN PSTRING PromptString,
-                IN PSTRING ResponseString)
+KdpPromptString(
+    _In_ PSTRING PromptString,
+    _In_ PSTRING ResponseString)
 {
     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 +92,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 +119,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 +152,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 +162,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 +192,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 +203,7 @@ KdpSymbol(IN PSTRING DllPath,
                                     &Prcb->ProcessorState.ContextFrame);
 
     /* Restore the processor state */
-    RtlCopyMemory(ContextRecord,
+    KdpMoveMemory(ContextRecord,
                   &Prcb->ProcessorState.ContextFrame,
                   sizeof(CONTEXT));
     KiRestoreProcessorControlState(&Prcb->ProcessorState);
@@ -201,33 +212,77 @@ KdpSymbol(IN PSTRING DllPath,
     KdExitDebugger(Enable);
 }
 
+#else
+
+extern
+BOOLEAN
+NTAPI
+KdpPrintString(
+    _In_ PSTRING Output);
+
+extern
+BOOLEAN
+NTAPI
+KdpPromptString(
+    _In_ PSTRING PromptString,
+    _In_ PSTRING ResponseString);
+
+#endif // _WINKD_
+
 USHORT
 NTAPI
-KdpPrompt(IN LPSTR PromptString,
-          IN USHORT PromptLength,
-          OUT LPSTR ResponseString,
-          IN USHORT MaximumResponseLength,
-          IN KPROCESSOR_MODE PreviousMode,
-          IN PKTRAP_FRAME TrapFrame,
-          IN PKEXCEPTION_FRAME ExceptionFrame)
+KdpPrompt(
+    _In_reads_bytes_(PromptLength) PCHAR PromptString,
+    _In_ USHORT PromptLength,
+    _Out_writes_bytes_(MaximumResponseLength) PCHAR ResponseString,
+    _In_ USHORT MaximumResponseLength,
+    _In_ KPROCESSOR_MODE PreviousMode,
+    _In_ PKTRAP_FRAME TrapFrame,
+    _In_ PKEXCEPTION_FRAME ExceptionFrame)
 {
     STRING PromptBuffer, ResponseBuffer;
     BOOLEAN Enable, Resend;
+    PCHAR SafeResponseString;
+    CHAR CapturedPrompt[512];
+    CHAR SafeResponseBuffer[512];
 
     /* 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 and capture the prompt */
+            ProbeForRead(PromptString, PromptLength, 1);
+            KdpMoveMemory(CapturedPrompt, PromptString, PromptLength);
+            PromptString = CapturedPrompt;
+
+            /* Probe and make room for the 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 */
+    /* Setup the prompt and response buffers */
     PromptBuffer.Buffer = PromptString;
-    PromptBuffer.Length = PromptLength;
-    ResponseBuffer.Buffer = ResponseString;
+    PromptBuffer.Length = PromptBuffer.MaximumLength = PromptLength;
+    ResponseBuffer.Buffer = SafeResponseString;
     ResponseBuffer.Length = 0;
     ResponseBuffer.MaximumLength = MaximumResponseLength;
 
@@ -249,51 +304,80 @@ KdpPrompt(IN LPSTR PromptString,
     /* Exit the debugger */
     KdExitDebugger(Enable);
 
+    /* Copy back the response if required */
+    if (PreviousMode != KernelMode)
+    {
+        _SEH2_TRY
+        {
+            /* Safely copy back the 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
 NTAPI
-KdpPrint(IN ULONG ComponentId,
-         IN ULONG Level,
-         IN LPSTR String,
-         IN USHORT Length,
-         IN KPROCESSOR_MODE PreviousMode,
-         IN PKTRAP_FRAME TrapFrame,
-         IN PKEXCEPTION_FRAME ExceptionFrame,
-         OUT PBOOLEAN Handled)
+KdpPrint(
+    _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)
 {
-    NTSTATUS ReturnStatus;
+    NTSTATUS Status;
     BOOLEAN Enable;
     STRING OutputString;
+    CHAR CapturedString[512];
 
-    /* Assume failure */
-    *Handled = FALSE;
-
-    /* Validate the mask */
-    if (Level < 32) Level = 1 << Level;
-    if (!(Kd_WIN2000_Mask & Level) ||
-        ((ComponentId < KdComponentTableSize) &&
-        !(*KdComponentTable[ComponentId] & Level)))
+    if (NtQueryDebugFilterState(ComponentId, Level) == (NTSTATUS)FALSE)
     {
         /* Mask validation failed */
         *Handled = TRUE;
         return STATUS_SUCCESS;
     }
 
+    /* Assume failure */
+    *Handled = FALSE;
+
     /* Normalize the length */
-    Length = min(Length, 512);
+    Length = min(Length, sizeof(CapturedString));
 
-    /* Check if we need to verify the buffer */
+    /* Check if we need to verify the string */
     if (PreviousMode != KernelMode)
     {
-        /* FIXME: Support user-mode */
+        /* 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;
     }
 
     /* Setup the output string */
     OutputString.Buffer = String;
-    OutputString.Length = Length;
+    OutputString.Length = OutputString.MaximumLength = Length;
 
     /* Log the print */
     //KdLogDbgPrint(&OutputString);
@@ -313,29 +397,30 @@ KdpPrint(IN ULONG ComponentId,
     if (KdpPrintString(&OutputString))
     {
         /* User pressed CTRL-C, breakpoint on return */
-        ReturnStatus = STATUS_BREAKPOINT;
+        Status = STATUS_BREAKPOINT;
     }
     else
     {
         /* String was printed */
-        ReturnStatus = STATUS_SUCCESS;
+        Status = STATUS_SUCCESS;
     }
 
     /* Exit the debugger and return */
     KdExitDebugger(Enable);
     *Handled = TRUE;
-    return ReturnStatus;
+    return Status;
 }
 
 VOID
 __cdecl
-KdpDprintf(IN PCHAR Format,
-           ...)
+KdpDprintf(
+    _In_ PCHAR Format,
+    ...)
 {
     STRING String;
-    CHAR Buffer[100];
     USHORT Length;
     va_list ap;
+    CHAR Buffer[100];
 
     /* Format the string */
     va_start(ap, Format);
@@ -343,12 +428,12 @@ KdpDprintf(IN PCHAR Format,
                                 sizeof(Buffer),
                                 Format,
                                 ap);
+    va_end(ap);
 
     /* Set it up */
     String.Buffer = Buffer;
-    String.Length = Length + 1;
+    String.Length = String.MaximumLength = Length;
 
     /* Send it to the debugger directly */
     KdpPrintString(&String);
-    va_end(ap);
 }