Author: hbelusca
Date: Tue Dec 31 20:47:05 2013
New Revision: 61468
URL: http://svn.reactos.org/svn/reactos?rev=61468&view=rev
Log:
[NTOSKRNL]
Fix user-mode access of pointers. From a patch by Sven Bjorn (private communication) and Aleksander Andrejevic.
"[...]In the routine NtSetTimerResolution() the pointer "CurrentResolution" is
checked using ProbeForWriteUlong(), but it is then accessed outside of a try-block.
This should be an error, since the user mode memory can become invalid at any point
in time and thus potentially make the kernel crash on access.
[...]"
CORE-7387 #comment A fix by Sven Bjorn was committed in revision 61468, thanks :)
Modified:
trunk/reactos/ntoskrnl/ex/time.c
Modified: trunk/reactos/ntoskrnl/ex/time.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ex/time.c?rev=614…
==============================================================================
--- trunk/reactos/ntoskrnl/ex/time.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/ex/time.c [iso-8859-1] Tue Dec 31 20:47:05 2013
@@ -417,7 +417,6 @@
NtQuerySystemTime(OUT PLARGE_INTEGER SystemTime)
{
KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
- NTSTATUS Status = STATUS_SUCCESS;
PAGED_CODE();
/* Check if we were called from user-mode */
@@ -429,16 +428,16 @@
ProbeForWriteLargeInteger(SystemTime);
/*
- * It's safe to pass the pointer directly to KeQuerySystemTime as
- * it's just a basic copy to this pointer. If it raises an
+ * It's safe to pass the pointer directly to KeQuerySystemTime
+ * as it's just a basic copy to this pointer. If it raises an
* exception nothing dangerous can happen!
*/
KeQuerySystemTime(SystemTime);
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
- /* Get the exception code */
- Status = _SEH2_GetExceptionCode();
+ /* Return the exception code */
+ _SEH2_YIELD(return _SEH2_GetExceptionCode());
}
_SEH2_END;
}
@@ -448,8 +447,8 @@
KeQuerySystemTime(SystemTime);
}
- /* Return status to caller */
- return Status;
+ /* Return success */
+ return STATUS_SUCCESS;
}
/*
@@ -485,7 +484,7 @@
{
KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
- /* Check if the call came from user mode */
+ /* Check if the call came from user-mode */
if (PreviousMode != KernelMode)
{
_SEH2_TRY
@@ -494,6 +493,17 @@
ProbeForWriteUlong(MinimumResolution);
ProbeForWriteUlong(MaximumResolution);
ProbeForWriteUlong(ActualResolution);
+
+ /*
+ * Set the parameters to the actual values.
+ *
+ * NOTE:
+ * MinimumResolution corresponds to the biggest time increment and
+ * MaximumResolution corresponds to the smallest time increment.
+ */
+ *MinimumResolution = KeMaximumIncrement;
+ *MaximumResolution = KeMinimumIncrement;
+ *ActualResolution = KeTimeIncrement;
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
@@ -502,17 +512,13 @@
}
_SEH2_END;
}
-
- /*
- * Set the parameters to the actual values.
- *
- * NOTE:
- * MinimumResolution corresponds to the biggest time increment and
- * MaximumResolution corresponds to the smallest time increment.
- */
- *MinimumResolution = KeMaximumIncrement;
- *MaximumResolution = KeMinimumIncrement;
- *ActualResolution = KeTimeIncrement;
+ else
+ {
+ /* Set the parameters to the actual values */
+ *MinimumResolution = KeMaximumIncrement;
+ *MaximumResolution = KeMinimumIncrement;
+ *ActualResolution = KeTimeIncrement;
+ }
/* Return success */
return STATUS_SUCCESS;
@@ -532,7 +538,7 @@
PEPROCESS Process = PsGetCurrentProcess();
ULONG NewResolution;
- /* Check if the call came from user mode */
+ /* Check if the call came from user-mode */
if (PreviousMode != KernelMode)
{
_SEH2_TRY
@@ -550,7 +556,24 @@
/* Set and return the new resolution */
NewResolution = ExSetTimerResolution(DesiredResolution, SetResolution);
- *CurrentResolution = NewResolution;
+
+ if (PreviousMode != KernelMode)
+ {
+ _SEH2_TRY
+ {
+ *CurrentResolution = NewResolution;
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ /* Return the exception code */
+ _SEH2_YIELD(return _SEH2_GetExceptionCode());
+ }
+ _SEH2_END;
+ }
+ else
+ {
+ *CurrentResolution = NewResolution;
+ }
if (SetResolution || Process->SetTimerResolution)
{