https://git.reactos.org/?p=reactos.git;a=commitdiff;h=9e7c3770e3cc44a45e3aea92cc0d4a7d7bb24470
commit 9e7c3770e3cc44a45e3aea92cc0d4a7d7bb24470 Author: Hervé Poussineau <hpous...@reactos.org> AuthorDate: Sat Sep 14 08:41:20 2024 +0200 Commit: Hermès Bélusca-Maïto <hermes.belusca-ma...@reactos.org> CommitDate: Tue Jan 28 22:00:38 2025 +0100 [NTOS:EX] Improve NtSystemDebugControl - Add SEH probing for user buffer - Mark some classes as i386 only - Explicitly return STATUS_NOT_IMPLEMENTED on disabled classes (must use KdSystemDebugControl instead) - Explicitly return STATUS_NOT_IMPLEMENTED on not implemented classes - Return STATUS_INVALID_INFO_CLASS on all other classes --- ntoskrnl/ex/dbgctrl.c | 121 +++++++++++++++++++++++++++++++++----------------- 1 file changed, 80 insertions(+), 41 deletions(-) diff --git a/ntoskrnl/ex/dbgctrl.c b/ntoskrnl/ex/dbgctrl.c index 3aa65b99a97..dbb47793ee5 100644 --- a/ntoskrnl/ex/dbgctrl.c +++ b/ntoskrnl/ex/dbgctrl.c @@ -214,48 +214,87 @@ NtSystemDebugControl( _In_ ULONG OutputBufferLength, _Out_opt_ PULONG ReturnLength) { - switch (Command) + KPROCESSOR_MODE PreviousMode = KeGetPreviousMode(); + ULONG Length = 0; + NTSTATUS Status; + + _SEH2_TRY { - case SysDbgQueryModuleInformation: - case SysDbgQueryTraceInformation: - case SysDbgSetTracepoint: - case SysDbgSetSpecialCall: - case SysDbgClearSpecialCalls: - case SysDbgQuerySpecialCalls: - case SysDbgQueryVersion: - case SysDbgReadVirtual: - case SysDbgWriteVirtual: - case SysDbgReadPhysical: - case SysDbgWritePhysical: - case SysDbgReadControlSpace: - case SysDbgWriteControlSpace: - case SysDbgReadIoSpace: - case SysDbgWriteIoSpace: - case SysDbgReadMsr: - case SysDbgWriteMsr: - case SysDbgReadBusData: - case SysDbgWriteBusData: - case SysDbgCheckLowMemory: - case SysDbgGetTriageDump: - return STATUS_NOT_IMPLEMENTED; - case SysDbgBreakPoint: - case SysDbgEnableKernelDebugger: - case SysDbgDisableKernelDebugger: - case SysDbgGetAutoKdEnable: - case SysDbgSetAutoKdEnable: - case SysDbgGetPrintBufferSize: - case SysDbgSetPrintBufferSize: - case SysDbgGetKdUmExceptionEnable: - case SysDbgSetKdUmExceptionEnable: + if (PreviousMode != KernelMode) + { + if (InputBufferLength) + ProbeForRead(InputBuffer, InputBufferLength, sizeof(ULONG)); + if (OutputBufferLength) + ProbeForWrite(OutputBuffer, OutputBufferLength, sizeof(ULONG)); + if (ReturnLength) + ProbeForWriteUlong(ReturnLength); + } + + switch (Command) + { + case SysDbgQueryModuleInformation: + /* Removed in WinNT4 */ + Status = STATUS_INVALID_INFO_CLASS; + break; + +#ifdef _M_IX86 + case SysDbgQueryTraceInformation: + case SysDbgSetTracepoint: + case SysDbgSetSpecialCall: + case SysDbgClearSpecialCalls: + case SysDbgQuerySpecialCalls: + UNIMPLEMENTED; + Status = STATUS_NOT_IMPLEMENTED; + break; +#endif + + case SysDbgQueryVersion: + case SysDbgReadVirtual: + case SysDbgWriteVirtual: + case SysDbgReadPhysical: + case SysDbgWritePhysical: + case SysDbgReadControlSpace: + case SysDbgWriteControlSpace: + case SysDbgReadIoSpace: + case SysDbgWriteIoSpace: + case SysDbgReadMsr: + case SysDbgWriteMsr: + case SysDbgReadBusData: + case SysDbgWriteBusData: + case SysDbgCheckLowMemory: + /* Those are implemented in KdSystemDebugControl */ + Status = STATUS_NOT_IMPLEMENTED; + break; + + case SysDbgBreakPoint: + case SysDbgEnableKernelDebugger: + case SysDbgDisableKernelDebugger: + case SysDbgGetAutoKdEnable: + case SysDbgSetAutoKdEnable: + case SysDbgGetPrintBufferSize: + case SysDbgSetPrintBufferSize: + case SysDbgGetKdUmExceptionEnable: + case SysDbgSetKdUmExceptionEnable: + case SysDbgGetTriageDump: + case SysDbgGetKdBlockEnable: + case SysDbgSetKdBlockEnable: + UNIMPLEMENTED; + Status = STATUS_NOT_IMPLEMENTED; + break; - case SysDbgGetKdBlockEnable: - case SysDbgSetKdBlockEnable: - return KdSystemDebugControl( - Command, - InputBuffer, InputBufferLength, - OutputBuffer, OutputBufferLength, - ReturnLength, KeGetPreviousMode()); - default: - return STATUS_INVALID_INFO_CLASS; + default: + Status = STATUS_INVALID_INFO_CLASS; + break; + } + + if (ReturnLength) + *ReturnLength = Length; + + _SEH2_YIELD(return Status); + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + _SEH2_YIELD(return _SEH2_GetExceptionCode()); } + _SEH2_END; }