1. fixed the timer functions to securely access buffers
2. minor fixes due to copy+paste
Modified: trunk/reactos/ntoskrnl/ex/sem.c
Modified: trunk/reactos/ntoskrnl/ex/timer.c

Modified: trunk/reactos/ntoskrnl/ex/sem.c
--- trunk/reactos/ntoskrnl/ex/sem.c	2005-01-23 23:02:19 UTC (rev 13235)
+++ trunk/reactos/ntoskrnl/ex/sem.c	2005-01-23 23:51:40 UTC (rev 13236)
@@ -240,12 +240,12 @@
                                &Status);
    if(!NT_SUCCESS(Status))
    {
-     DPRINT1("NtQueryEvent() failed, Status: 0x%x\n", Status);
+     DPRINT1("NtQuerySemaphore() failed, Status: 0x%x\n", Status);
      return Status;
    }
 
    Status = ObReferenceObjectByHandle(SemaphoreHandle,
-				      EVENT_QUERY_STATE,
+				      SEMAPHORE_QUERY_STATE,
 				      ExSemaphoreObjectType,
 				      PreviousMode,
 				      (PVOID*)&Semaphore,

Modified: trunk/reactos/ntoskrnl/ex/timer.c
--- trunk/reactos/ntoskrnl/ex/timer.c	2005-01-23 23:02:19 UTC (rev 13235)
+++ trunk/reactos/ntoskrnl/ex/timer.c	2005-01-23 23:51:40 UTC (rev 13236)
@@ -36,6 +36,10 @@
 	STANDARD_RIGHTS_EXECUTE | SYNCHRONIZE,
 	TIMER_ALL_ACCESS};
 
+static const INFORMATION_CLASS_INFO ExTimerInfoClass[] =
+{
+  ICI_SQ_SAME( sizeof(TIMER_BASIC_INFORMATION), sizeof(ULONG), ICIF_QUERY ), /* TimerBasicInformation */
+};
 
 /* FUNCTIONS *****************************************************************/
 
@@ -146,36 +150,67 @@
 	      OUT PBOOLEAN CurrentState OPTIONAL)
 {
    PNTTIMER Timer;
-   NTSTATUS Status;
-   BOOLEAN State;
-   KIRQL OldIrql;
+   KPROCESSOR_MODE PreviousMode;
+   NTSTATUS Status = STATUS_SUCCESS;
+   
+   PreviousMode = ExGetPreviousMode();
+   
+   DPRINT("NtCancelTimer(0x%x, 0x%x)\n", TimerHandle, CurrentState);
+   
+   if(CurrentState != NULL && PreviousMode != KernelMode)
+   {
+     _SEH_TRY
+     {
+       ProbeForWrite(CurrentState,
+                     sizeof(BOOLEAN),
+                     sizeof(BOOLEAN));
+     }
+     _SEH_HANDLE
+     {
+       Status = _SEH_GetExceptionCode();
+     }
+     _SEH_END;
+     
+     if(!NT_SUCCESS(Status))
+     {
+       return Status;
+     }
+   }
 
-   DPRINT("NtCancelTimer()\n");
    Status = ObReferenceObjectByHandle(TimerHandle,
 				      TIMER_ALL_ACCESS,
 				      ExTimerType,
-				      UserMode,
+				      PreviousMode,
 				      (PVOID*)&Timer,
 				      NULL);
-   if (!NT_SUCCESS(Status))
-     return Status;
+   if(NT_SUCCESS(Status))
+   {
+     BOOLEAN State;
+     KIRQL OldIrql = KeRaiseIrqlToDpcLevel();
 
-   OldIrql = KeRaiseIrqlToDpcLevel();
+     State = KeCancelTimer(&Timer->Timer);
+     KeRemoveQueueDpc(&Timer->Dpc);
+     KeRemoveQueueApc(&Timer->Apc);
+     Timer->Running = FALSE;
 
-   State = KeCancelTimer(&Timer->Timer);
-   KeRemoveQueueDpc(&Timer->Dpc);
-   KeRemoveQueueApc(&Timer->Apc);
-   Timer->Running = FALSE;
+     KeLowerIrql(OldIrql);
+     ObDereferenceObject(Timer);
 
-   KeLowerIrql(OldIrql);
-   ObDereferenceObject(Timer);
-
-   if (CurrentState != NULL)
+     if(CurrentState != NULL)
      {
-	*CurrentState = State;
+       _SEH_TRY
+       {
+         *CurrentState = State;
+       }
+       _SEH_HANDLE
+       {
+         Status = _SEH_GetExceptionCode();
+       }
+       _SEH_END;
      }
+   }
 
-   return STATUS_SUCCESS;
+   return Status;
 }
 
 
@@ -186,39 +221,76 @@
 	      IN TIMER_TYPE TimerType)
 {
    PNTTIMER Timer;
-   NTSTATUS Status;
+   HANDLE hTimer;
+   KPROCESSOR_MODE PreviousMode;
+   NTSTATUS Status = STATUS_SUCCESS;
+   
+   DPRINT("NtCreateTimer()\n");
+   
+   PreviousMode = ExGetPreviousMode();
+   
+   if(PreviousMode != KernelMode)
+   {
+     _SEH_TRY
+     {
+       ProbeForWrite(TimerHandle,
+                     sizeof(HANDLE),
+                     sizeof(ULONG));
+     }
+     _SEH_HANDLE
+     {
+       Status = _SEH_GetExceptionCode();
+     }
+     _SEH_END;
 
-   DPRINT("NtCreateTimer()\n");
-   Status = ObCreateObject(ExGetPreviousMode(),
+     if(!NT_SUCCESS(Status))
+     {
+       return Status;
+     }
+   }
+
+   Status = ObCreateObject(PreviousMode,
 			   ExTimerType,
 			   ObjectAttributes,
-			   ExGetPreviousMode(),
+			   PreviousMode,
 			   NULL,
 			   sizeof(NTTIMER),
 			   0,
 			   0,
 			   (PVOID*)&Timer);
-   if (!NT_SUCCESS(Status))
-     return Status;
+   if(NT_SUCCESS(Status))
+   {
+     KeInitializeTimerEx(&Timer->Timer,
+		         TimerType);
 
-   KeInitializeTimerEx(&Timer->Timer,
-		       TimerType);
+     KeInitializeDpc(&Timer->Dpc,
+		     &ExpTimerDpcRoutine,
+		     Timer);
 
-   KeInitializeDpc(&Timer->Dpc,
-		   &ExpTimerDpcRoutine,
-		   Timer);
+     Timer->Running = FALSE;
 
-   Timer->Running = FALSE;
+     Status = ObInsertObject ((PVOID)Timer,
+			      NULL,
+			      DesiredAccess,
+			      0,
+			      NULL,
+			      &hTimer);
+     ObDereferenceObject(Timer);
+     
+     if(NT_SUCCESS(Status))
+     {
+       _SEH_TRY
+       {
+         *TimerHandle = hTimer;
+       }
+       _SEH_HANDLE
+       {
+         Status = _SEH_GetExceptionCode();
+       }
+       _SEH_END;
+     }
+   }
 
-   Status = ObInsertObject ((PVOID)Timer,
-			    NULL,
-			    DesiredAccess,
-			    0,
-			    NULL,
-			    TimerHandle);
-
-   ObDereferenceObject(Timer);
-
    return Status;
 }
 
@@ -228,15 +300,54 @@
 	    IN ACCESS_MASK DesiredAccess,
 	    IN POBJECT_ATTRIBUTES ObjectAttributes)
 {
-   NTSTATUS Status;
+   HANDLE hTimer;
+   KPROCESSOR_MODE PreviousMode;
+   NTSTATUS Status = STATUS_SUCCESS;
 
+   DPRINT("NtOpenTimer()\n");
+
+   PreviousMode = ExGetPreviousMode();
+
+   if(PreviousMode != KernelMode)
+   {
+     _SEH_TRY
+     {
+       ProbeForWrite(TimerHandle,
+                     sizeof(HANDLE),
+                     sizeof(ULONG));
+     }
+     _SEH_HANDLE
+     {
+       Status = _SEH_GetExceptionCode();
+     }
+     _SEH_END;
+
+     if(!NT_SUCCESS(Status))
+     {
+       return Status;
+     }
+   }
+
    Status = ObOpenObjectByName(ObjectAttributes,
 			       ExTimerType,
 			       NULL,
-			       UserMode,
+			       PreviousMode,
 			       DesiredAccess,
 			       NULL,
-			       TimerHandle);
+			       &hTimer);
+   if(NT_SUCCESS(Status))
+   {
+     _SEH_TRY
+     {
+       *TimerHandle = hTimer;
+     }
+     _SEH_HANDLE
+     {
+       Status = _SEH_GetExceptionCode();
+     }
+     _SEH_END;
+   }
+   
    return Status;
 }
 
@@ -248,58 +359,67 @@
 	     IN ULONG TimerInformationLength,
 	     OUT PULONG ReturnLength  OPTIONAL)
 {
-  PNTTIMER Timer;
-  TIMER_BASIC_INFORMATION SafeTimerInformation;
-  ULONG ResultLength;
-  NTSTATUS Status;
+   PNTTIMER Timer;
+   KPROCESSOR_MODE PreviousMode;
+   NTSTATUS Status = STATUS_SUCCESS;
 
-  Status = ObReferenceObjectByHandle(TimerHandle,
-				     TIMER_QUERY_STATE,
-				     ExTimerType,
-				     (KPROCESSOR_MODE)KeGetPreviousMode(),
-				     (PVOID*)&Timer,
-				     NULL);
-  if (!NT_SUCCESS(Status))
-    {
-      return(Status);
-    }
+   PreviousMode = ExGetPreviousMode();
 
-  if (TimerInformationClass != TimerBasicInformation)
-    {
-      ObDereferenceObject(Timer);
-      return(STATUS_INVALID_INFO_CLASS);
-    }
-  if (TimerInformationLength < sizeof(TIMER_BASIC_INFORMATION))
-    {
-      ObDereferenceObject(Timer);
-      return(STATUS_INFO_LENGTH_MISMATCH);
-    }
+   DefaultQueryInfoBufferCheck(TimerInformationClass,
+                               ExTimerInfoClass,
+                               TimerInformation,
+                               TimerInformationLength,
+                               ReturnLength,
+                               PreviousMode,
+                               &Status);
+   if(!NT_SUCCESS(Status))
+   {
+     DPRINT1("NtQueryTimer() failed, Status: 0x%x\n", Status);
+     return Status;
+   }
 
-  memcpy(&SafeTimerInformation.TimeRemaining, &Timer->Timer.DueTime,
-	 sizeof(LARGE_INTEGER));
-  SafeTimerInformation.SignalState = (BOOLEAN)Timer->Timer.Header.SignalState;
-  ResultLength = sizeof(TIMER_BASIC_INFORMATION);
+   Status = ObReferenceObjectByHandle(TimerHandle,
+				      TIMER_QUERY_STATE,
+				      ExTimerType,
+				      PreviousMode,
+				      (PVOID*)&Timer,
+				      NULL);
+   if(NT_SUCCESS(Status))
+   {
+     switch(TimerInformationClass)
+     {
+       case TimerBasicInformation:
+       {
+         PTIMER_BASIC_INFORMATION BasicInfo = (PTIMER_BASIC_INFORMATION)TimerInformation;
 
-  Status = MmCopyToCaller(TimerInformation, &SafeTimerInformation,
-			  sizeof(TIMER_BASIC_INFORMATION));
-  if (!NT_SUCCESS(Status))
-    {
-      ObDereferenceObject(Timer);
-      return(Status);
-    }
+         _SEH_TRY
+         {
+           /* FIXME - interrupt correction */
+           BasicInfo->TimeRemaining.QuadPart = Timer->Timer.DueTime.QuadPart;
+           BasicInfo->SignalState = (BOOLEAN)Timer->Timer.Header.SignalState;
 
-  if (ReturnLength != NULL)
-    {
-      Status = MmCopyToCaller(ReturnLength, &ResultLength,
-			      sizeof(ULONG));
-      if (!NT_SUCCESS(Status))
-	{
-	  ObDereferenceObject(Timer);
-	  return(Status);
-	}
-    }
-  ObDereferenceObject(Timer);
-  return(STATUS_SUCCESS);
+           if(ReturnLength != NULL)
+           {
+             *ReturnLength = sizeof(TIMER_BASIC_INFORMATION);
+           }
+         }
+         _SEH_HANDLE
+         {
+           Status = _SEH_GetExceptionCode();
+         }
+         _SEH_END;
+         break;
+       }
+
+       default:
+         Status = STATUS_NOT_IMPLEMENTED;
+         break;
+     }
+
+     ObDereferenceObject(Timer);
+   }
+
+   return Status;
 }
 
 
@@ -313,16 +433,48 @@
 	   OUT PBOOLEAN PreviousState  OPTIONAL)
 {
    PNTTIMER Timer;
-   NTSTATUS Status;
    BOOLEAN Result;
    BOOLEAN State;
+   LARGE_INTEGER TimerDueTime;
+   KPROCESSOR_MODE PreviousMode;
+   NTSTATUS Status = STATUS_SUCCESS;
 
    DPRINT("NtSetTimer()\n");
 
+   PreviousMode = ExGetPreviousMode();
+
+   if(PreviousMode != KernelMode)
+   {
+     _SEH_TRY
+     {
+       ProbeForRead(DueTime,
+                    sizeof(LARGE_INTEGER),
+                    sizeof(ULONG));
+       TimerDueTime = *DueTime;
+
+       if(PreviousState != NULL)
+       {
+         ProbeForWrite(PreviousState,
+                       sizeof(BOOLEAN),
+                       sizeof(BOOLEAN));
+       }
+     }
+     _SEH_HANDLE
+     {
+       Status = _SEH_GetExceptionCode();
+     }
+     _SEH_END;
+
+     if(!NT_SUCCESS(Status))
+     {
+       return Status;
+     }
+   }
+
    Status = ObReferenceObjectByHandle(TimerHandle,
 				      TIMER_ALL_ACCESS,
 				      ExTimerType,
-				      (KPROCESSOR_MODE)KeGetPreviousMode(),
+				      PreviousMode,
 				      (PVOID*)&Timer,
 				      NULL);
    if (!NT_SUCCESS(Status))
@@ -351,15 +503,15 @@
 		       &ExpTimerApcKernelRoutine,
 		       (PKRUNDOWN_ROUTINE)NULL,
 		       (PKNORMAL_ROUTINE)TimerApcRoutine,
-		       (KPROCESSOR_MODE)KeGetPreviousMode(),
+		       PreviousMode,
 		       TimerContext);
      }
 
    Result = KeSetTimerEx(&Timer->Timer,
-			 *DueTime,
+			 TimerDueTime,
 			 Period,
 			 TimerApcRoutine ? &Timer->Dpc : 0 );
-   if (Result == TRUE)
+   if (Result)
      {
 	ObDereferenceObject(Timer);
 	DPRINT1( "KeSetTimer says the timer was already running, this shouldn't be\n" );
@@ -371,11 +523,19 @@
    ObDereferenceObject(Timer);
 
    if (PreviousState != NULL)
+   {
+     _SEH_TRY
      {
-	*PreviousState = State;
+       *PreviousState = State;
      }
+     _SEH_HANDLE
+     {
+       Status = _SEH_GetExceptionCode();
+     }
+     _SEH_END;
+   }
 
-   return STATUS_SUCCESS;
+   return Status;
 }
 
 /* EOF */