https://git.reactos.org/?p=reactos.git;a=commitdiff;h=9e7c3770e3cc44a45e3ae…
commit 9e7c3770e3cc44a45e3aea92cc0d4a7d7bb24470
Author: Hervé Poussineau <hpoussin(a)reactos.org>
AuthorDate: Sat Sep 14 08:41:20 2024 +0200
Commit: Hermès Bélusca-Maïto <hermes.belusca-maito(a)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;
}