fixed semaphore functions to securely access buffers and some minor fixes
Modified: trunk/reactos/include/ntos/zw.h
Modified: trunk/reactos/ntoskrnl/ex/sem.c
Modified: trunk/reactos/ntoskrnl/ob/object.c

Modified: trunk/reactos/include/ntos/zw.h
--- trunk/reactos/include/ntos/zw.h	2005-01-23 21:26:27 UTC (rev 13231)
+++ trunk/reactos/include/ntos/zw.h	2005-01-23 22:09:27 UTC (rev 13232)
@@ -2205,7 +2205,7 @@
 NTSTATUS
 STDCALL
 NtOpenSemaphore(
-	IN HANDLE SemaphoreHandle,
+	OUT PHANDLE SemaphoreHandle,
 	IN ACCESS_MASK DesiredAcces,
 	IN POBJECT_ATTRIBUTES ObjectAttributes
 	);
@@ -3108,7 +3108,7 @@
 STDCALL
 NtQuerySystemEnvironmentValue(
 	IN PUNICODE_STRING VariableName,
-	OUT PWSTR ValueBuffer,
+	OUT PWCHAR ValueBuffer,
 	IN ULONG ValueBufferLength,
 	OUT PULONG ReturnLength  OPTIONAL
 	);
@@ -3117,7 +3117,7 @@
 STDCALL
 ZwQuerySystemEnvironmentValue(
 	IN PUNICODE_STRING VariableName,
-	OUT PWSTR ValueBuffer,
+	OUT PWCHAR ValueBuffer,
 	IN ULONG ValueBufferLength,
 	OUT PULONG ReturnLength  OPTIONAL
 	);

Modified: trunk/reactos/ntoskrnl/ex/sem.c
--- trunk/reactos/ntoskrnl/ex/sem.c	2005-01-23 21:26:27 UTC (rev 13231)
+++ trunk/reactos/ntoskrnl/ex/sem.c	2005-01-23 22:09:27 UTC (rev 13232)
@@ -25,6 +25,11 @@
 	STANDARD_RIGHTS_EXECUTE | SYNCHRONIZE | SEMAPHORE_QUERY_STATE,
 	SEMAPHORE_ALL_ACCESS};
 
+static const INFORMATION_CLASS_INFO ExSemaphoreInfoClass[] =
+{
+  ICI_SQ_SAME( sizeof(SEMAPHORE_BASIC_INFORMATION), sizeof(ULONG), ICIF_QUERY ), /* SemaphoreBasicInformation */
+};
+
 /* FUNCTIONS *****************************************************************/
 
 NTSTATUS STDCALL
@@ -73,6 +78,9 @@
    ObpCreateTypeObject(ExSemaphoreObjectType);
 }
 
+/*
+ * @implemented
+ */
 NTSTATUS STDCALL
 NtCreateSemaphore(OUT PHANDLE SemaphoreHandle,
 		  IN ACCESS_MASK DesiredAccess,
@@ -81,58 +89,135 @@
 		  IN LONG MaximumCount)
 {
    PKSEMAPHORE Semaphore;
-   NTSTATUS Status;
+   HANDLE hSemaphore;
+   KPROCESSOR_MODE PreviousMode;
+   NTSTATUS Status = STATUS_SUCCESS;
+   
+   PreviousMode = ExGetPreviousMode();
+   
+   if(PreviousMode == UserMode)
+   {
+     _SEH_TRY
+     {
+       ProbeForWrite(SemaphoreHandle,
+                     sizeof(HANDLE),
+                     sizeof(ULONG));
+     }
+     _SEH_HANDLE
+     {
+       Status = _SEH_GetExceptionCode();
+     }
+     _SEH_END;
 
-   Status = ObCreateObject(ExGetPreviousMode(),
+     if(!NT_SUCCESS(Status))
+     {
+       return Status;
+     }
+   }
+
+   Status = ObCreateObject(PreviousMode,
 			   ExSemaphoreObjectType,
 			   ObjectAttributes,
-			   ExGetPreviousMode(),
+			   PreviousMode,
 			   NULL,
 			   sizeof(KSEMAPHORE),
 			   0,
 			   0,
 			   (PVOID*)&Semaphore);
    if (!NT_SUCCESS(Status))
+   {
+     KeInitializeSemaphore(Semaphore,
+			   InitialCount,
+			   MaximumCount);
+
+     Status = ObInsertObject ((PVOID)Semaphore,
+			      NULL,
+			      DesiredAccess,
+			      0,
+			      NULL,
+			      &hSemaphore);
+
+     ObDereferenceObject(Semaphore);
+   
+     if(NT_SUCCESS(Status))
      {
-	return(Status);
+       _SEH_TRY
+       {
+         *SemaphoreHandle = hSemaphore;
+       }
+       _SEH_HANDLE
+       {
+         Status = _SEH_GetExceptionCode();
+       }
+       _SEH_END;
      }
+   }
 
-   KeInitializeSemaphore(Semaphore,
-			 InitialCount,
-			 MaximumCount);
-
-   Status = ObInsertObject ((PVOID)Semaphore,
-			    NULL,
-			    DesiredAccess,
-			    0,
-			    NULL,
-			    SemaphoreHandle);
-
-   ObDereferenceObject(Semaphore);
-
    return Status;
 }
 
 
+/*
+ * @implemented
+ */
 NTSTATUS STDCALL
-NtOpenSemaphore(IN HANDLE SemaphoreHandle,
+NtOpenSemaphore(OUT PHANDLE SemaphoreHandle,
 		IN ACCESS_MASK	DesiredAccess,
 		IN POBJECT_ATTRIBUTES ObjectAttributes)
 {
-   NTSTATUS Status;
+   HANDLE hSemaphore;
+   KPROCESSOR_MODE PreviousMode;
+   NTSTATUS Status = STATUS_SUCCESS;
+
+   PreviousMode = ExGetPreviousMode();
+
+   if(PreviousMode == UserMode)
+   {
+     _SEH_TRY
+     {
+       ProbeForWrite(SemaphoreHandle,
+                     sizeof(HANDLE),
+                     sizeof(ULONG));
+     }
+     _SEH_HANDLE
+     {
+       Status = _SEH_GetExceptionCode();
+     }
+     _SEH_END;
+
+     if(!NT_SUCCESS(Status))
+     {
+       return Status;
+     }
+   }
    
    Status = ObOpenObjectByName(ObjectAttributes,
 			       ExSemaphoreObjectType,
 			       NULL,
-			       UserMode,
+			       PreviousMode,
 			       DesiredAccess,
 			       NULL,
-			       SemaphoreHandle);
+			       &hSemaphore);
+   if(NT_SUCCESS(Status))
+   {
+     _SEH_TRY
+     {
+       *SemaphoreHandle = hSemaphore;
+     }
+     _SEH_HANDLE
+     {
+       Status = _SEH_GetExceptionCode();
+     }
+     _SEH_END;
+   }
    
    return Status;
 }
 
 
+/*
+ * @implemented
+ */
 NTSTATUS STDCALL
 NtQuerySemaphore(IN HANDLE SemaphoreHandle,
 		 IN SEMAPHORE_INFORMATION_CLASS SemaphoreInformationClass,
@@ -140,62 +225,132 @@
 		 IN ULONG SemaphoreInformationLength,
 		 OUT PULONG ReturnLength  OPTIONAL)
 {
-   PSEMAPHORE_BASIC_INFORMATION Info;
    PKSEMAPHORE Semaphore;
-   NTSTATUS Status;
+   KPROCESSOR_MODE PreviousMode;
+   NTSTATUS Status = STATUS_SUCCESS;
 
-   Info = (PSEMAPHORE_BASIC_INFORMATION)SemaphoreInformation;
+   PreviousMode = ExGetPreviousMode();
 
-   if (SemaphoreInformationClass > SemaphoreBasicInformation)
-     return STATUS_INVALID_INFO_CLASS;
+   DefaultQueryInfoBufferCheck(SemaphoreInformationClass,
+                               ExSemaphoreInfoClass,
+                               SemaphoreInformation,
+                               SemaphoreInformationLength,
+                               ReturnLength,
+                               PreviousMode,
+                               &Status);
+   if(!NT_SUCCESS(Status))
+   {
+     DPRINT1("NtQueryEvent() failed, Status: 0x%x\n", Status);
+     return Status;
+   }
 
-   if (SemaphoreInformationLength < sizeof(SEMAPHORE_BASIC_INFORMATION))
-     return STATUS_INFO_LENGTH_MISMATCH;
-
    Status = ObReferenceObjectByHandle(SemaphoreHandle,
-				      SEMAPHORE_QUERY_STATE,
+				      EVENT_QUERY_STATE,
 				      ExSemaphoreObjectType,
-				      UserMode,
+				      PreviousMode,
 				      (PVOID*)&Semaphore,
 				      NULL);
-   if (!NT_SUCCESS(Status))
-     return Status;
+   if(NT_SUCCESS(Status))
+   {
+     switch(SemaphoreInformationClass)
+     {
+       case SemaphoreBasicInformation:
+       {
+         PSEMAPHORE_BASIC_INFORMATION BasicInfo = (PSEMAPHORE_BASIC_INFORMATION)SemaphoreInformation;
 
-   Info->CurrentCount = KeReadStateSemaphore(Semaphore);
-   Info->MaximumCount = Semaphore->Limit;
+         _SEH_TRY
+         {
+           BasicInfo->CurrentCount = KeReadStateSemaphore(Semaphore);
+           BasicInfo->MaximumCount = Semaphore->Limit;
 
-   if (ReturnLength != NULL)
-     *ReturnLength = sizeof(SEMAPHORE_BASIC_INFORMATION);
+           if(ReturnLength != NULL)
+           {
+             *ReturnLength = sizeof(SEMAPHORE_BASIC_INFORMATION);
+           }
+         }
+         _SEH_HANDLE
+         {
+           Status = _SEH_GetExceptionCode();
+         }
+         _SEH_END;
+         break;
+       }
 
-   ObDereferenceObject(Semaphore);
+       default:
+         Status = STATUS_NOT_IMPLEMENTED;
+         break;
+     }
 
-   return STATUS_SUCCESS;
+     ObDereferenceObject(Semaphore);
+   }
+
+   return Status;
 }
 
+
+/*
+ * @implemented
+ */
 NTSTATUS STDCALL
 NtReleaseSemaphore(IN HANDLE SemaphoreHandle,
 		   IN LONG ReleaseCount,
 		   OUT PLONG PreviousCount  OPTIONAL)
 {
+   KPROCESSOR_MODE PreviousMode;
    PKSEMAPHORE Semaphore;
-   NTSTATUS Status;
+   NTSTATUS Status = STATUS_SUCCESS;
    
+   PreviousMode = ExGetPreviousMode();
+   
+   if(PreviousCount != NULL && PreviousMode == UserMode)
+   {
+     _SEH_TRY
+     {
+       ProbeForWrite(PreviousCount,
+                     sizeof(LONG),
+                     sizeof(ULONG));
+     }
+     _SEH_HANDLE
+     {
+       Status = _SEH_GetExceptionCode();
+     }
+     _SEH_END;
+
+     if(!NT_SUCCESS(Status))
+     {
+       return Status;
+     }
+   }
+   
    Status = ObReferenceObjectByHandle(SemaphoreHandle,
 				      SEMAPHORE_MODIFY_STATE,
 				      ExSemaphoreObjectType,
-				      UserMode,
+				      PreviousMode,
 				      (PVOID*)&Semaphore,
 				      NULL);
-   if (!NT_SUCCESS(Status))
+   if (NT_SUCCESS(Status))
+   {
+     LONG PrevCount = KeReleaseSemaphore(Semaphore,
+                                         IO_NO_INCREMENT,
+                                         ReleaseCount,
+                                         FALSE);
+     ObDereferenceObject(Semaphore);
+     
+     if(PreviousCount != NULL)
      {
-	return(Status);
+       _SEH_TRY
+       {
+         *PreviousCount = PrevCount;
+       }
+       _SEH_HANDLE
+       {
+         Status = _SEH_GetExceptionCode();
+       }
+       _SEH_END;
      }
-   KeReleaseSemaphore(Semaphore,
-		      IO_NO_INCREMENT,
-		      ReleaseCount,
-		      FALSE);
-   ObDereferenceObject(Semaphore);
-   return(STATUS_SUCCESS);
+   }
+
+   return Status;
 }
 
 /* EOF */

Modified: trunk/reactos/ntoskrnl/ob/object.c
--- trunk/reactos/ntoskrnl/ob/object.c	2005-01-23 21:26:27 UTC (rev 13231)
+++ trunk/reactos/ntoskrnl/ob/object.c	2005-01-23 22:09:27 UTC (rev 13232)
@@ -169,7 +169,7 @@
           {
             ProbeForRead(OriginalCopy.Buffer,
                          OriginalCopy.Length,
-                         sizeof(ULONG));
+                         sizeof(WCHAR));
           }
         }
         _SEH_HANDLE