- Protect semaphore release with SEH, since it can cause an exception

- Correct object type initializer
- Correct incorrect PreviousMode checks
- Correct MaximumCount and ReleaseCount checks since they can't be negative either
- Harmonize formatting

svn path=/trunk/; revision=17059
This commit is contained in:
Alex Ionescu 2005-08-05 06:56:17 +00:00
parent 4a4e5adc99
commit 53aa4eb206

View file

@ -2,9 +2,9 @@
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
* FILE: ntoskrnl/ex/sem.c * FILE: ntoskrnl/ex/sem.c
* PURPOSE: Synchronization primitives * PURPOSE: Semaphore Implementation
* *
* PROGRAMMERS: Alex Ionescu (alex@relsoft.net)- Reformatting, bug fixes. * PROGRAMMERS: Alex Ionescu (alex@relsoft.net)
* David Welch (welch@mcmail.com) * David Welch (welch@mcmail.com)
*/ */
@ -18,14 +18,16 @@
POBJECT_TYPE ExSemaphoreObjectType; POBJECT_TYPE ExSemaphoreObjectType;
static GENERIC_MAPPING ExSemaphoreMapping = { static GENERIC_MAPPING ExSemaphoreMapping =
{
STANDARD_RIGHTS_READ | SEMAPHORE_QUERY_STATE, STANDARD_RIGHTS_READ | SEMAPHORE_QUERY_STATE,
STANDARD_RIGHTS_WRITE | SEMAPHORE_MODIFY_STATE, STANDARD_RIGHTS_WRITE | SEMAPHORE_MODIFY_STATE,
STANDARD_RIGHTS_EXECUTE | SYNCHRONIZE | SEMAPHORE_QUERY_STATE, STANDARD_RIGHTS_EXECUTE | SYNCHRONIZE | SEMAPHORE_QUERY_STATE,
SEMAPHORE_ALL_ACCESS}; SEMAPHORE_ALL_ACCESS
};
static const INFORMATION_CLASS_INFO ExSemaphoreInfoClass[] = {
static const INFORMATION_CLASS_INFO ExSemaphoreInfoClass[] =
{
/* SemaphoreBasicInformation */ /* SemaphoreBasicInformation */
ICI_SQ_SAME( sizeof(SEMAPHORE_BASIC_INFORMATION), sizeof(ULONG), ICIF_QUERY ), ICI_SQ_SAME( sizeof(SEMAPHORE_BASIC_INFORMATION), sizeof(ULONG), ICIF_QUERY ),
}; };
@ -47,8 +49,8 @@ ExpInitializeSemaphoreImplementation(VOID)
ObjectTypeInitializer.DefaultNonPagedPoolCharge = sizeof(KSEMAPHORE); ObjectTypeInitializer.DefaultNonPagedPoolCharge = sizeof(KSEMAPHORE);
ObjectTypeInitializer.GenericMapping = ExSemaphoreMapping; ObjectTypeInitializer.GenericMapping = ExSemaphoreMapping;
ObjectTypeInitializer.PoolType = NonPagedPool; ObjectTypeInitializer.PoolType = NonPagedPool;
ObjectTypeInitializer.InvalidAttributes = OBJ_OPENLINK;
ObjectTypeInitializer.ValidAccessMask = SEMAPHORE_ALL_ACCESS; ObjectTypeInitializer.ValidAccessMask = SEMAPHORE_ALL_ACCESS;
ObjectTypeInitializer.UseDefaultObject = TRUE;
ObpCreateTypeObject(&ObjectTypeInitializer, &Name, &ExSemaphoreObjectType); ObpCreateTypeObject(&ObjectTypeInitializer, &Name, &ExSemaphoreObjectType);
} }
@ -67,29 +69,29 @@ NtCreateSemaphore(OUT PHANDLE SemaphoreHandle,
HANDLE hSemaphore; HANDLE hSemaphore;
KPROCESSOR_MODE PreviousMode = ExGetPreviousMode(); KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
NTSTATUS Status = STATUS_SUCCESS; NTSTATUS Status = STATUS_SUCCESS;
PAGED_CODE(); PAGED_CODE();
/* Check Output Safety */ /* Check Output Safety */
if(PreviousMode != KernelMode) { if(PreviousMode != KernelMode)
{
_SEH_TRY { _SEH_TRY
{
ProbeForWrite(SemaphoreHandle, ProbeForWrite(SemaphoreHandle,
sizeof(HANDLE), sizeof(HANDLE),
sizeof(ULONG)); sizeof(ULONG));
} _SEH_EXCEPT(_SEH_ExSystemExceptionFilter) { }
_SEH_EXCEPT(_SEH_ExSystemExceptionFilter)
{
Status = _SEH_GetExceptionCode(); Status = _SEH_GetExceptionCode();
}
} _SEH_END; _SEH_END;
if(!NT_SUCCESS(Status)) return Status; if(!NT_SUCCESS(Status)) return Status;
} }
/* Make sure the counts make sense */ /* Make sure the counts make sense */
if (!MaximumCount || InitialCount < 0 || InitialCount > MaximumCount) { if (MaximumCount <= 0 || InitialCount < 0 || InitialCount > MaximumCount)
{
DPRINT("Invalid Count Data!\n"); DPRINT("Invalid Count Data!\n");
return STATUS_INVALID_PARAMETER; return STATUS_INVALID_PARAMETER;
} }
@ -106,8 +108,8 @@ NtCreateSemaphore(OUT PHANDLE SemaphoreHandle,
(PVOID*)&Semaphore); (PVOID*)&Semaphore);
/* Check for Success */ /* Check for Success */
if (NT_SUCCESS(Status)) { if (NT_SUCCESS(Status))
{
/* Initialize it */ /* Initialize it */
KeInitializeSemaphore(Semaphore, KeInitializeSemaphore(Semaphore,
InitialCount, InitialCount,
@ -123,17 +125,17 @@ NtCreateSemaphore(OUT PHANDLE SemaphoreHandle,
ObDereferenceObject(Semaphore); ObDereferenceObject(Semaphore);
/* Check for success and return handle */ /* Check for success and return handle */
if(NT_SUCCESS(Status)) { if(NT_SUCCESS(Status))
{
_SEH_TRY { _SEH_TRY
{
*SemaphoreHandle = hSemaphore; *SemaphoreHandle = hSemaphore;
}
} _SEH_EXCEPT(_SEH_ExSystemExceptionFilter) { _SEH_EXCEPT(_SEH_ExSystemExceptionFilter)
{
Status = _SEH_GetExceptionCode(); Status = _SEH_GetExceptionCode();
}
} _SEH_END; _SEH_END;
} }
} }
@ -153,22 +155,22 @@ NtOpenSemaphore(OUT PHANDLE SemaphoreHandle,
HANDLE hSemaphore; HANDLE hSemaphore;
KPROCESSOR_MODE PreviousMode = ExGetPreviousMode(); KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
NTSTATUS Status = STATUS_SUCCESS; NTSTATUS Status = STATUS_SUCCESS;
PAGED_CODE(); PAGED_CODE();
/* Check Output Safety */ /* Check Output Safety */
if(PreviousMode == UserMode) { if(PreviousMode != KernelMode)
{
_SEH_TRY { _SEH_TRY
{
ProbeForWrite(SemaphoreHandle, ProbeForWrite(SemaphoreHandle,
sizeof(HANDLE), sizeof(HANDLE),
sizeof(ULONG)); sizeof(ULONG));
} _SEH_EXCEPT(_SEH_ExSystemExceptionFilter) { }
_SEH_EXCEPT(_SEH_ExSystemExceptionFilter)
{
Status = _SEH_GetExceptionCode(); Status = _SEH_GetExceptionCode();
}
} _SEH_END; _SEH_END;
if(!NT_SUCCESS(Status)) return Status; if(!NT_SUCCESS(Status)) return Status;
} }
@ -183,16 +185,15 @@ NtOpenSemaphore(OUT PHANDLE SemaphoreHandle,
&hSemaphore); &hSemaphore);
/* Check for success and return handle */ /* Check for success and return handle */
if(NT_SUCCESS(Status)) { if(NT_SUCCESS(Status))
{
_SEH_TRY { _SEH_TRY
{
*SemaphoreHandle = hSemaphore; *SemaphoreHandle = hSemaphore;
}
} _SEH_EXCEPT(_SEH_ExSystemExceptionFilter) { _SEH_EXCEPT(_SEH_ExSystemExceptionFilter)
{
Status = _SEH_GetExceptionCode(); Status = _SEH_GetExceptionCode();
} _SEH_END; } _SEH_END;
} }
@ -225,8 +226,8 @@ NtQuerySemaphore(IN HANDLE SemaphoreHandle,
ReturnLength, ReturnLength,
PreviousMode, PreviousMode,
&Status); &Status);
if(!NT_SUCCESS(Status)) { if(!NT_SUCCESS(Status))
{
/* Invalid buffers */ /* Invalid buffers */
DPRINT("NtQuerySemaphore() failed, Status: 0x%x\n", Status); DPRINT("NtQuerySemaphore() failed, Status: 0x%x\n", Status);
return Status; return Status;
@ -241,10 +242,10 @@ NtQuerySemaphore(IN HANDLE SemaphoreHandle,
NULL); NULL);
/* Check for success */ /* Check for success */
if(NT_SUCCESS(Status)) { if(NT_SUCCESS(Status))
{
_SEH_TRY { _SEH_TRY
{
PSEMAPHORE_BASIC_INFORMATION BasicInfo = (PSEMAPHORE_BASIC_INFORMATION)SemaphoreInformation; PSEMAPHORE_BASIC_INFORMATION BasicInfo = (PSEMAPHORE_BASIC_INFORMATION)SemaphoreInformation;
/* Return the basic information */ /* Return the basic information */
@ -254,10 +255,10 @@ NtQuerySemaphore(IN HANDLE SemaphoreHandle,
/* Return length */ /* Return length */
if(ReturnLength) *ReturnLength = sizeof(SEMAPHORE_BASIC_INFORMATION); if(ReturnLength) *ReturnLength = sizeof(SEMAPHORE_BASIC_INFORMATION);
} _SEH_EXCEPT(_SEH_ExSystemExceptionFilter) { }
_SEH_EXCEPT(_SEH_ExSystemExceptionFilter)
{
Status = _SEH_GetExceptionCode(); Status = _SEH_GetExceptionCode();
} _SEH_END; } _SEH_END;
/* Dereference the Object */ /* Dereference the Object */
@ -284,25 +285,26 @@ NtReleaseSemaphore(IN HANDLE SemaphoreHandle,
PAGED_CODE(); PAGED_CODE();
/* Check buffer validity */ /* Check buffer validity */
if(PreviousCount != NULL && PreviousMode == UserMode) { if(PreviousCount && PreviousMode != KernelMode)
{
_SEH_TRY { _SEH_TRY
{
ProbeForWrite(PreviousCount, ProbeForWrite(PreviousCount,
sizeof(LONG), sizeof(LONG),
sizeof(ULONG)); sizeof(ULONG));
} _SEH_EXCEPT(_SEH_ExSystemExceptionFilter) { }
_SEH_EXCEPT(_SEH_ExSystemExceptionFilter)
{
Status = _SEH_GetExceptionCode(); Status = _SEH_GetExceptionCode();
}
} _SEH_END; _SEH_END;
if(!NT_SUCCESS(Status)) return Status; if(!NT_SUCCESS(Status)) return Status;
} }
/* Make sure count makes sense */ /* Make sure count makes sense */
if (!ReleaseCount) { if (ReleaseCount <= 0)
{
DPRINT("Invalid Release Count\n"); DPRINT("Invalid Release Count\n");
return STATUS_INVALID_PARAMETER; return STATUS_INVALID_PARAMETER;
} }
@ -316,28 +318,28 @@ NtReleaseSemaphore(IN HANDLE SemaphoreHandle,
NULL); NULL);
/* Check for success */ /* Check for success */
if (NT_SUCCESS(Status)) { if (NT_SUCCESS(Status))
{
/* Release the semaphore */ /* Release the semaphore */
LONG PrevCount = KeReleaseSemaphore(Semaphore, _SEH_TRY
IO_NO_INCREMENT, {
ReleaseCount, LONG PrevCount = KeReleaseSemaphore(Semaphore,
FALSE); IO_NO_INCREMENT,
ObDereferenceObject(Semaphore); ReleaseCount,
FALSE);
/* Return it */ ObDereferenceObject(Semaphore);
if(PreviousCount) {
_SEH_TRY {
/* Return the old count if requested */
if(PreviousCount)
{
*PreviousCount = PrevCount; *PreviousCount = PrevCount;
}
} _SEH_EXCEPT(_SEH_ExSystemExceptionFilter) {
Status = _SEH_GetExceptionCode();
} _SEH_END;
} }
_SEH_EXCEPT(_SEH_ExSystemExceptionFilter)
{
Status = _SEH_GetExceptionCode();
}
_SEH_END;
} }
/* Return Status */ /* Return Status */