[NTOS:PO]
authorThomas Faber <thomas.faber@reactos.org>
Sun, 25 Sep 2016 13:46:18 +0000 (13:46 +0000)
committerThomas Faber <thomas.faber@reactos.org>
Sun, 25 Sep 2016 13:46:18 +0000 (13:46 +0000)
- Protect against invalid user mode pointers in NtPowerInformation

svn path=/trunk/; revision=72800

reactos/ntoskrnl/po/power.c

index 4c8a4c0..9b96b60 100644 (file)
@@ -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;
         }