diff --git a/reactos/ntoskrnl/include/internal/kd64.h b/reactos/ntoskrnl/include/internal/kd64.h index 38534c124d9..79578237247 100644 --- a/reactos/ntoskrnl/include/internal/kd64.h +++ b/reactos/ntoskrnl/include/internal/kd64.h @@ -351,6 +351,24 @@ KdpCopyMemoryChunks( OUT PULONG ActualSize OPTIONAL ); +// +// Internal memory handling routines for KD isolation +// +VOID +NTAPI +KdpMoveMemory( + IN PVOID Destination, + IN PVOID Source, + IN SIZE_T Length +); + +VOID +NTAPI +KdpZeroMemory( + IN PVOID Destination, + IN SIZE_T Length +); + // // Low Level Support Routines for the KD API // diff --git a/reactos/ntoskrnl/kd64/kdapi.c b/reactos/ntoskrnl/kd64/kdapi.c index bc2de45408a..f0415ba3ae0 100644 --- a/reactos/ntoskrnl/kd64/kdapi.c +++ b/reactos/ntoskrnl/kd64/kdapi.c @@ -15,6 +15,32 @@ /* PRIVATE FUNCTIONS *********************************************************/ +VOID +NTAPI +KdpMoveMemory(IN PVOID Destination, + IN PVOID Source, + IN SIZE_T Length) +{ + PCHAR DestinationBytes, SourceBytes; + + /* Copy the buffers 1 byte at a time */ + DestinationBytes = Destination; + SourceBytes = Source; + while (Length--) *DestinationBytes++ = *SourceBytes++; +} + +VOID +NTAPI +KdpZeroMemory(IN PVOID Destination, + IN SIZE_T Length) +{ + PCHAR DestinationBytes; + + /* Zero the buffer 1 byte at a time */ + DestinationBytes = Destination; + while (Length--) *DestinationBytes++ = 0; +} + NTSTATUS NTAPI KdpCopyMemoryChunks(IN ULONG64 Address, @@ -368,7 +394,7 @@ KdpSetCommonState(IN ULONG NewState, WaitStateChange->ProgramCounter = (ULONG64)(LONG_PTR)KeGetContextPc(Context); /* Zero out the entire Control Report */ - RtlZeroMemory(&WaitStateChange->AnyControlReport, + KdpZeroMemory(&WaitStateChange->AnyControlReport, sizeof(DBGKD_ANY_CONTROL_REPORT)); /* Now copy the instruction stream and set the count */ @@ -402,7 +428,9 @@ NTAPI KdpSysGetVersion(IN PDBGKD_GET_VERSION64 Version) { /* Copy the version block */ - RtlCopyMemory(Version, &KdVersionBlock, sizeof(DBGKD_GET_VERSION64)); + KdpMoveMemory(Version, + &KdVersionBlock, + sizeof(DBGKD_GET_VERSION64)); } VOID @@ -711,7 +739,9 @@ KdpGetContext(IN PDBGKD_MANIPULATE_STATE64 State, } /* Copy it over to the debugger */ - RtlCopyMemory(Data->Buffer, TargetContext, sizeof(CONTEXT)); + KdpMoveMemory(Data->Buffer, + TargetContext, + sizeof(CONTEXT)); Data->Length = sizeof(CONTEXT); /* Let the debugger set the context now */ @@ -765,7 +795,9 @@ KdpSetContext(IN PDBGKD_MANIPULATE_STATE64 State, } /* Copy the new context to it */ - RtlCopyMemory(TargetContext, Data->Buffer, sizeof(CONTEXT)); + KdpMoveMemory(TargetContext, + Data->Buffer, + sizeof(CONTEXT)); /* Finish up */ State->ReturnStatus = STATUS_SUCCESS; @@ -819,7 +851,7 @@ KdpGetContextEx(IN PDBGKD_MANIPULATE_STATE64 State, } /* Copy what is requested */ - RtlCopyMemory(Data->Buffer, + KdpMoveMemory(Data->Buffer, (PVOID)((ULONG_PTR)TargetContext + ContextEx->Offset), ContextEx->ByteCount); @@ -883,7 +915,7 @@ KdpSetContextEx(IN PDBGKD_MANIPULATE_STATE64 State, } /* Copy what is requested */ - RtlCopyMemory((PVOID)((ULONG_PTR)TargetContext + ContextEx->Offset), + KdpMoveMemory((PVOID)((ULONG_PTR)TargetContext + ContextEx->Offset), Data->Buffer, ContextEx->ByteCount); @@ -1639,7 +1671,7 @@ KdpReportCommandStringStateChange(IN PSTRING NameString, KdpSetContextState(&WaitStateChange, Context); /* Clear the command string structure */ - RtlZeroMemory(&WaitStateChange.u.CommandString, + KdpZeroMemory(&WaitStateChange.u.CommandString, sizeof(DBGKD_COMMAND_STRING)); /* Normalize name string to max */ @@ -1709,15 +1741,22 @@ KdpReportExceptionStateChange(IN PEXCEPTION_RECORD ExceptionRecord, /* Build the architecture common parts of the message */ KdpSetCommonState(DbgKdExceptionStateChange, Context, &WaitStateChange); - /* Copy the Exception Record and set First Chance flag */ #if !defined(_WIN64) + + /* Convert it and copy it over */ ExceptionRecord32To64((PEXCEPTION_RECORD32)ExceptionRecord, &WaitStateChange.u.Exception.ExceptionRecord); + #else - RtlCopyMemory(&WaitStateChange.u.Exception.ExceptionRecord, + + /* Just copy it directly, no need to convert */ + KdpMoveMemory(&WaitStateChange.u.Exception.ExceptionRecord, ExceptionRecord, sizeof(EXCEPTION_RECORD)); + #endif + + /* Set the First Chance flag */ WaitStateChange.u.Exception.FirstChance = !SecondChanceException; /* Now finish creating the structure */ diff --git a/reactos/ntoskrnl/kd64/kdprint.c b/reactos/ntoskrnl/kd64/kdprint.c index 5b6959bde83..9fccf7463b4 100644 --- a/reactos/ntoskrnl/kd64/kdprint.c +++ b/reactos/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); @@ -216,38 +223,48 @@ KdpPrompt(IN LPSTR PromptString, PVOID CapturedPrompt, CapturedResponse; /* Normalize the lengths */ - PromptLength = min(PromptLength, 512); - MaximumResponseLength = min(MaximumResponseLength, 512); + PromptLength = min(PromptLength, + 512); + MaximumResponseLength = min(MaximumResponseLength, + 512); /* Check if we need to verify the string */ if (PreviousMode != KernelMode) { - /* Capture user-mode buffers */ + /* Handle user-mode buffers safely */ _SEH2_TRY { - ProbeForRead(PromptString, PromptLength, 1); - CapturedPrompt = alloca(512); - RtlMoveMemory(CapturedPrompt, PromptString, PromptLength); + /* Probe the prompt */ + ProbeForRead(PromptString, + PromptLength, + 1); + + /* Capture prompt */ + CapturedPrompt = _alloca(PromptLength); + KdpMoveMemory(CapturedPrompt, + PromptString, + PromptLength); PromptString = CapturedPrompt; - ProbeForWrite(ResponseString, MaximumResponseLength, 1); - CapturedResponse = alloca(512); + /* Probe and make room for response */ + ProbeForWrite(ResponseString, + MaximumResponseLength, + 1); + CapturedResponse = _alloca(MaximumResponseLength); + ResponseString = CapturedResponse; } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { + /* Bad string pointer, bail out */ _SEH2_YIELD(return 0); } _SEH2_END; } - else - { - CapturedResponse = ResponseString; - } /* Setup the prompt and response buffers */ PromptBuffer.Buffer = PromptString; PromptBuffer.Length = PromptLength; - ResponseBuffer.Buffer = CapturedResponse; + ResponseBuffer.Buffer = ResponseString; ResponseBuffer.Length = 0; ResponseBuffer.MaximumLength = MaximumResponseLength; @@ -274,10 +291,14 @@ KdpPrompt(IN LPSTR PromptString, { _SEH2_TRY { - RtlMoveMemory(ResponseString, ResponseBuffer.Buffer, ResponseBuffer.Length); + /* 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; @@ -326,13 +347,21 @@ KdpPrint(IN ULONG ComponentId, /* Capture user-mode buffers */ _SEH2_TRY { - ProbeForRead(String, Length, 1); - CapturedString = alloca(512); - RtlMoveMemory(CapturedString, String, Length); + /* 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; diff --git a/reactos/ntoskrnl/kd64/kdtrap.c b/reactos/ntoskrnl/kd64/kdtrap.c index ce7e20c26b2..91a83de4691 100644 --- a/reactos/ntoskrnl/kd64/kdtrap.c +++ b/reactos/ntoskrnl/kd64/kdtrap.c @@ -58,13 +58,14 @@ KdpReport(IN PKTRAP_FRAME TrapFrame, { BOOLEAN Enable, Handled; PKPRCB Prcb; - NTSTATUS ExceptionCode = ExceptionRecord->ExceptionCode; + NTSTATUS ExceptionCode; /* * Determine whether to pass the exception to the debugger. * First, check if this is a "debug exception", meaning breakpoint * (including debug service), single step and assertion failure exceptions. */ + ExceptionCode = ExceptionRecord->ExceptionCode; if ((ExceptionCode == STATUS_BREAKPOINT) || (ExceptionCode == STATUS_SINGLE_STEP) || (ExceptionCode == STATUS_ASSERTION_FAILURE)) @@ -92,8 +93,8 @@ KdpReport(IN PKTRAP_FRAME TrapFrame, else if (SecondChanceException == FALSE) { /* - * This isn't a debug exception and the stop-on-exception flag isn't - * set, so don't bother + * This isn't a debug exception and the stop-on-exception flag isn't set, + * so don't bother handling it */ return FALSE; } @@ -107,7 +108,7 @@ KdpReport(IN PKTRAP_FRAME TrapFrame, */ Prcb = KeGetCurrentPrcb(); KiSaveProcessorControlState(&Prcb->ProcessorState); - RtlCopyMemory(&Prcb->ProcessorState.ContextFrame, + KdpMoveMemory(&Prcb->ProcessorState.ContextFrame, ContextRecord, sizeof(CONTEXT)); @@ -118,7 +119,7 @@ KdpReport(IN PKTRAP_FRAME TrapFrame, SecondChanceException); /* Now restore the processor state, manually again. */ - RtlCopyMemory(ContextRecord, + KdpMoveMemory(ContextRecord, &Prcb->ProcessorState.ContextFrame, sizeof(CONTEXT)); KiRestoreProcessorControlState(&Prcb->ProcessorState); @@ -138,7 +139,7 @@ KdpTrap(IN PKTRAP_FRAME TrapFrame, IN KPROCESSOR_MODE PreviousMode, IN BOOLEAN SecondChanceException) { - BOOLEAN Unload = FALSE; + BOOLEAN Unload; ULONG_PTR ProgramCounter; BOOLEAN Handled; NTSTATUS ReturnStatus; @@ -156,6 +157,7 @@ KdpTrap(IN PKTRAP_FRAME TrapFrame, ProgramCounter = KeGetContextPc(ContextRecord); /* Check what kind of operation was requested from us */ + Unload = FALSE; switch (ExceptionRecord->ExceptionInformation[0]) { /* DbgPrint */ @@ -164,27 +166,24 @@ KdpTrap(IN PKTRAP_FRAME TrapFrame, /* Call the worker routine */ ReturnStatus = KdpPrint((ULONG)KdpGetParameterThree(ContextRecord), (ULONG)KdpGetParameterFour(ContextRecord), - (LPSTR)ExceptionRecord-> - ExceptionInformation[1], - (USHORT)ExceptionRecord-> - ExceptionInformation[2], + (LPSTR)ExceptionRecord->ExceptionInformation[1], + (USHORT)ExceptionRecord->ExceptionInformation[2], PreviousMode, TrapFrame, ExceptionFrame, &Handled); /* Update the return value for the caller */ - KeSetContextReturnRegister(ContextRecord, ReturnStatus); + KeSetContextReturnRegister(ContextRecord, + ReturnStatus); break; /* DbgPrompt */ case BREAKPOINT_PROMPT: /* Call the worker routine */ - ReturnLength = KdpPrompt((LPSTR)ExceptionRecord-> - ExceptionInformation[1], - (USHORT)ExceptionRecord-> - ExceptionInformation[2], + ReturnLength = KdpPrompt((LPSTR)ExceptionRecord->ExceptionInformation[1], + (USHORT)ExceptionRecord->ExceptionInformation[2], (LPSTR)KdpGetParameterThree(ContextRecord), (USHORT)KdpGetParameterFour(ContextRecord), PreviousMode, @@ -276,9 +275,10 @@ KdpStub(IN PKTRAP_FRAME TrapFrame, IN KPROCESSOR_MODE PreviousMode, IN BOOLEAN SecondChanceException) { - ULONG_PTR ExceptionCommand = ExceptionRecord->ExceptionInformation[0]; + ULONG_PTR ExceptionCommand; /* Check if this was a breakpoint due to DbgPrint or Load/UnloadSymbols */ + ExceptionCommand = ExceptionRecord->ExceptionInformation[0]; if ((ExceptionRecord->ExceptionCode == STATUS_BREAKPOINT) && (ExceptionRecord->NumberParameters > 0) && ((ExceptionCommand == BREAKPOINT_LOAD_SYMBOLS) || diff --git a/reactos/ntoskrnl/mm/ARM3/session.c b/reactos/ntoskrnl/mm/ARM3/session.c index 4f6f11aaea2..23de7c07e61 100644 --- a/reactos/ntoskrnl/mm/ARM3/session.c +++ b/reactos/ntoskrnl/mm/ARM3/session.c @@ -44,6 +44,14 @@ MiInitializeSessionWsSupport(VOID) InitializeListHead(&MmWorkingSetExpansionHead); } +BOOLEAN +NTAPI +MmIsSessionAddress(IN PVOID Address) +{ + /* Check if it is in range */ + return MI_IS_SESSION_ADDRESS(Address) ? TRUE : FALSE; +} + LCID NTAPI MmGetSessionLocaleId(VOID)