From 3e357794f993a89de8235e478272b82acc3b631c Mon Sep 17 00:00:00 2001 From: Thomas Faber Date: Sun, 25 Sep 2016 13:46:18 +0000 Subject: [PATCH] [NTOS:PO] - Protect against invalid user mode pointers in NtPowerInformation svn path=/trunk/; revision=72800 --- reactos/ntoskrnl/po/power.c | 72 +++++++++++++++++++++++++++++-------- 1 file changed, 57 insertions(+), 15 deletions(-) diff --git a/reactos/ntoskrnl/po/power.c b/reactos/ntoskrnl/po/power.c index 4c8a4c03ff3..9b96b6016e2 100644 --- a/reactos/ntoskrnl/po/power.c +++ b/reactos/ntoskrnl/po/power.c @@ -657,6 +657,7 @@ NtPowerInformation(IN POWER_INFORMATION_LEVEL PowerInformationLevel, IN ULONG OutputBufferLength) { NTSTATUS Status; + KPROCESSOR_MODE PreviousMode = KeGetPreviousMode(); PAGED_CODE(); @@ -666,6 +667,20 @@ NtPowerInformation(IN POWER_INFORMATION_LEVEL PowerInformationLevel, InputBuffer, InputBufferLength, OutputBuffer, OutputBufferLength); + if (PreviousMode != KernelMode) + { + _SEH2_TRY + { + ProbeForRead(InputBuffer, InputBufferLength, 1); + ProbeForWrite(OutputBuffer, OutputBufferLength, sizeof(ULONG)); + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + _SEH2_YIELD(return _SEH2_GetExceptionCode()); + } + _SEH2_END; + } + switch (PowerInformationLevel) { case SystemBatteryState: @@ -677,11 +692,20 @@ NtPowerInformation(IN POWER_INFORMATION_LEVEL PowerInformationLevel, if (OutputBufferLength < sizeof(SYSTEM_BATTERY_STATE)) return STATUS_BUFFER_TOO_SMALL; - /* Just zero the struct (and thus set BatteryState->BatteryPresent = FALSE) */ - RtlZeroMemory(BatteryState, sizeof(SYSTEM_BATTERY_STATE)); - BatteryState->EstimatedTime = MAXULONG; + _SEH2_TRY + { + /* Just zero the struct (and thus set BatteryState->BatteryPresent = FALSE) */ + RtlZeroMemory(BatteryState, sizeof(SYSTEM_BATTERY_STATE)); + BatteryState->EstimatedTime = MAXULONG; + + Status = STATUS_SUCCESS; + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + Status = _SEH2_GetExceptionCode(); + } + _SEH2_END; - Status = STATUS_SUCCESS; break; } @@ -694,11 +718,20 @@ NtPowerInformation(IN POWER_INFORMATION_LEVEL PowerInformationLevel, if (OutputBufferLength < sizeof(SYSTEM_POWER_CAPABILITIES)) return STATUS_BUFFER_TOO_SMALL; - /* Just zero the struct (and thus set BatteryState->BatteryPresent = FALSE) */ - RtlZeroMemory(PowerCapabilities, sizeof(SYSTEM_POWER_CAPABILITIES)); - //PowerCapabilities->SystemBatteriesPresent = 0; + _SEH2_TRY + { + /* Just zero the struct (and thus set PowerCapabilities->SystemBatteriesPresent = FALSE) */ + RtlZeroMemory(PowerCapabilities, sizeof(SYSTEM_POWER_CAPABILITIES)); + //PowerCapabilities->SystemBatteriesPresent = 0; + + Status = STATUS_SUCCESS; + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + Status = _SEH2_GetExceptionCode(); + } + _SEH2_END; - Status = STATUS_SUCCESS; break; } @@ -711,14 +744,23 @@ NtPowerInformation(IN POWER_INFORMATION_LEVEL PowerInformationLevel, if (OutputBufferLength < sizeof(PROCESSOR_POWER_INFORMATION)) return STATUS_BUFFER_TOO_SMALL; - PowerInformation->Number = 0; - PowerInformation->MaxMhz = 1000; - PowerInformation->CurrentMhz = 1000; - PowerInformation->MhzLimit = 1000; - PowerInformation->MaxIdleState = 0; - PowerInformation->CurrentIdleState = 0; + _SEH2_TRY + { + PowerInformation->Number = 0; + PowerInformation->MaxMhz = 1000; + PowerInformation->CurrentMhz = 1000; + PowerInformation->MhzLimit = 1000; + PowerInformation->MaxIdleState = 0; + PowerInformation->CurrentIdleState = 0; + + Status = STATUS_SUCCESS; + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + Status = _SEH2_GetExceptionCode(); + } + _SEH2_END; - Status = STATUS_SUCCESS; break; } -- 2.17.1