mirror of
https://github.com/reactos/reactos.git
synced 2025-08-05 12:24:21 +00:00
- 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:
parent
4a4e5adc99
commit
53aa4eb206
1 changed files with 85 additions and 83 deletions
|
@ -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 */
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue