mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 01:55:19 +00:00
fixed semaphore functions to securely access buffers and some minor fixes
svn path=/trunk/; revision=13232
This commit is contained in:
parent
b25bf92b14
commit
baf658a398
3 changed files with 208 additions and 53 deletions
|
@ -2205,7 +2205,7 @@ ZwOpenSection(
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
STDCALL
|
STDCALL
|
||||||
NtOpenSemaphore(
|
NtOpenSemaphore(
|
||||||
IN HANDLE SemaphoreHandle,
|
OUT PHANDLE SemaphoreHandle,
|
||||||
IN ACCESS_MASK DesiredAcces,
|
IN ACCESS_MASK DesiredAcces,
|
||||||
IN POBJECT_ATTRIBUTES ObjectAttributes
|
IN POBJECT_ATTRIBUTES ObjectAttributes
|
||||||
);
|
);
|
||||||
|
@ -3108,7 +3108,7 @@ NTSTATUS
|
||||||
STDCALL
|
STDCALL
|
||||||
NtQuerySystemEnvironmentValue(
|
NtQuerySystemEnvironmentValue(
|
||||||
IN PUNICODE_STRING VariableName,
|
IN PUNICODE_STRING VariableName,
|
||||||
OUT PWSTR ValueBuffer,
|
OUT PWCHAR ValueBuffer,
|
||||||
IN ULONG ValueBufferLength,
|
IN ULONG ValueBufferLength,
|
||||||
OUT PULONG ReturnLength OPTIONAL
|
OUT PULONG ReturnLength OPTIONAL
|
||||||
);
|
);
|
||||||
|
@ -3117,7 +3117,7 @@ NTSTATUS
|
||||||
STDCALL
|
STDCALL
|
||||||
ZwQuerySystemEnvironmentValue(
|
ZwQuerySystemEnvironmentValue(
|
||||||
IN PUNICODE_STRING VariableName,
|
IN PUNICODE_STRING VariableName,
|
||||||
OUT PWSTR ValueBuffer,
|
OUT PWCHAR ValueBuffer,
|
||||||
IN ULONG ValueBufferLength,
|
IN ULONG ValueBufferLength,
|
||||||
OUT PULONG ReturnLength OPTIONAL
|
OUT PULONG ReturnLength OPTIONAL
|
||||||
);
|
);
|
||||||
|
|
|
@ -25,6 +25,11 @@ static GENERIC_MAPPING ExSemaphoreMapping = {
|
||||||
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[] =
|
||||||
|
{
|
||||||
|
ICI_SQ_SAME( sizeof(SEMAPHORE_BASIC_INFORMATION), sizeof(ULONG), ICIF_QUERY ), /* SemaphoreBasicInformation */
|
||||||
|
};
|
||||||
|
|
||||||
/* FUNCTIONS *****************************************************************/
|
/* FUNCTIONS *****************************************************************/
|
||||||
|
|
||||||
NTSTATUS STDCALL
|
NTSTATUS STDCALL
|
||||||
|
@ -73,6 +78,9 @@ ExpInitializeSemaphoreImplementation(VOID)
|
||||||
ObpCreateTypeObject(ExSemaphoreObjectType);
|
ObpCreateTypeObject(ExSemaphoreObjectType);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @implemented
|
||||||
|
*/
|
||||||
NTSTATUS STDCALL
|
NTSTATUS STDCALL
|
||||||
NtCreateSemaphore(OUT PHANDLE SemaphoreHandle,
|
NtCreateSemaphore(OUT PHANDLE SemaphoreHandle,
|
||||||
IN ACCESS_MASK DesiredAccess,
|
IN ACCESS_MASK DesiredAccess,
|
||||||
|
@ -81,58 +89,135 @@ NtCreateSemaphore(OUT PHANDLE SemaphoreHandle,
|
||||||
IN LONG MaximumCount)
|
IN LONG MaximumCount)
|
||||||
{
|
{
|
||||||
PKSEMAPHORE Semaphore;
|
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,
|
ExSemaphoreObjectType,
|
||||||
ObjectAttributes,
|
ObjectAttributes,
|
||||||
ExGetPreviousMode(),
|
PreviousMode,
|
||||||
NULL,
|
NULL,
|
||||||
sizeof(KSEMAPHORE),
|
sizeof(KSEMAPHORE),
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
(PVOID*)&Semaphore);
|
(PVOID*)&Semaphore);
|
||||||
if (!NT_SUCCESS(Status))
|
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;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @implemented
|
||||||
|
*/
|
||||||
NTSTATUS STDCALL
|
NTSTATUS STDCALL
|
||||||
NtOpenSemaphore(IN HANDLE SemaphoreHandle,
|
NtOpenSemaphore(OUT PHANDLE SemaphoreHandle,
|
||||||
IN ACCESS_MASK DesiredAccess,
|
IN ACCESS_MASK DesiredAccess,
|
||||||
IN POBJECT_ATTRIBUTES ObjectAttributes)
|
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,
|
Status = ObOpenObjectByName(ObjectAttributes,
|
||||||
ExSemaphoreObjectType,
|
ExSemaphoreObjectType,
|
||||||
NULL,
|
NULL,
|
||||||
UserMode,
|
PreviousMode,
|
||||||
DesiredAccess,
|
DesiredAccess,
|
||||||
NULL,
|
NULL,
|
||||||
SemaphoreHandle);
|
&hSemaphore);
|
||||||
|
if(NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
_SEH_TRY
|
||||||
|
{
|
||||||
|
*SemaphoreHandle = hSemaphore;
|
||||||
|
}
|
||||||
|
_SEH_HANDLE
|
||||||
|
{
|
||||||
|
Status = _SEH_GetExceptionCode();
|
||||||
|
}
|
||||||
|
_SEH_END;
|
||||||
|
}
|
||||||
|
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @implemented
|
||||||
|
*/
|
||||||
NTSTATUS STDCALL
|
NTSTATUS STDCALL
|
||||||
NtQuerySemaphore(IN HANDLE SemaphoreHandle,
|
NtQuerySemaphore(IN HANDLE SemaphoreHandle,
|
||||||
IN SEMAPHORE_INFORMATION_CLASS SemaphoreInformationClass,
|
IN SEMAPHORE_INFORMATION_CLASS SemaphoreInformationClass,
|
||||||
|
@ -140,62 +225,132 @@ NtQuerySemaphore(IN HANDLE SemaphoreHandle,
|
||||||
IN ULONG SemaphoreInformationLength,
|
IN ULONG SemaphoreInformationLength,
|
||||||
OUT PULONG ReturnLength OPTIONAL)
|
OUT PULONG ReturnLength OPTIONAL)
|
||||||
{
|
{
|
||||||
PSEMAPHORE_BASIC_INFORMATION Info;
|
|
||||||
PKSEMAPHORE Semaphore;
|
PKSEMAPHORE Semaphore;
|
||||||
NTSTATUS Status;
|
KPROCESSOR_MODE PreviousMode;
|
||||||
|
NTSTATUS Status = STATUS_SUCCESS;
|
||||||
|
|
||||||
Info = (PSEMAPHORE_BASIC_INFORMATION)SemaphoreInformation;
|
PreviousMode = ExGetPreviousMode();
|
||||||
|
|
||||||
if (SemaphoreInformationClass > SemaphoreBasicInformation)
|
DefaultQueryInfoBufferCheck(SemaphoreInformationClass,
|
||||||
return STATUS_INVALID_INFO_CLASS;
|
ExSemaphoreInfoClass,
|
||||||
|
SemaphoreInformation,
|
||||||
if (SemaphoreInformationLength < sizeof(SEMAPHORE_BASIC_INFORMATION))
|
SemaphoreInformationLength,
|
||||||
return STATUS_INFO_LENGTH_MISMATCH;
|
ReturnLength,
|
||||||
|
PreviousMode,
|
||||||
|
&Status);
|
||||||
|
if(!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DPRINT1("NtQueryEvent() failed, Status: 0x%x\n", Status);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
Status = ObReferenceObjectByHandle(SemaphoreHandle,
|
Status = ObReferenceObjectByHandle(SemaphoreHandle,
|
||||||
SEMAPHORE_QUERY_STATE,
|
EVENT_QUERY_STATE,
|
||||||
ExSemaphoreObjectType,
|
ExSemaphoreObjectType,
|
||||||
UserMode,
|
PreviousMode,
|
||||||
(PVOID*)&Semaphore,
|
(PVOID*)&Semaphore,
|
||||||
NULL);
|
NULL);
|
||||||
if (!NT_SUCCESS(Status))
|
if(NT_SUCCESS(Status))
|
||||||
return Status;
|
{
|
||||||
|
switch(SemaphoreInformationClass)
|
||||||
|
{
|
||||||
|
case SemaphoreBasicInformation:
|
||||||
|
{
|
||||||
|
PSEMAPHORE_BASIC_INFORMATION BasicInfo = (PSEMAPHORE_BASIC_INFORMATION)SemaphoreInformation;
|
||||||
|
|
||||||
Info->CurrentCount = KeReadStateSemaphore(Semaphore);
|
_SEH_TRY
|
||||||
Info->MaximumCount = Semaphore->Limit;
|
{
|
||||||
|
BasicInfo->CurrentCount = KeReadStateSemaphore(Semaphore);
|
||||||
|
BasicInfo->MaximumCount = Semaphore->Limit;
|
||||||
|
|
||||||
if (ReturnLength != NULL)
|
if(ReturnLength != NULL)
|
||||||
*ReturnLength = sizeof(SEMAPHORE_BASIC_INFORMATION);
|
{
|
||||||
|
*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
|
NTSTATUS STDCALL
|
||||||
NtReleaseSemaphore(IN HANDLE SemaphoreHandle,
|
NtReleaseSemaphore(IN HANDLE SemaphoreHandle,
|
||||||
IN LONG ReleaseCount,
|
IN LONG ReleaseCount,
|
||||||
OUT PLONG PreviousCount OPTIONAL)
|
OUT PLONG PreviousCount OPTIONAL)
|
||||||
{
|
{
|
||||||
|
KPROCESSOR_MODE PreviousMode;
|
||||||
PKSEMAPHORE Semaphore;
|
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,
|
Status = ObReferenceObjectByHandle(SemaphoreHandle,
|
||||||
SEMAPHORE_MODIFY_STATE,
|
SEMAPHORE_MODIFY_STATE,
|
||||||
ExSemaphoreObjectType,
|
ExSemaphoreObjectType,
|
||||||
UserMode,
|
PreviousMode,
|
||||||
(PVOID*)&Semaphore,
|
(PVOID*)&Semaphore,
|
||||||
NULL);
|
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,
|
return Status;
|
||||||
FALSE);
|
|
||||||
ObDereferenceObject(Semaphore);
|
|
||||||
return(STATUS_SUCCESS);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* EOF */
|
/* EOF */
|
||||||
|
|
|
@ -169,7 +169,7 @@ failbasiccleanup:
|
||||||
{
|
{
|
||||||
ProbeForRead(OriginalCopy.Buffer,
|
ProbeForRead(OriginalCopy.Buffer,
|
||||||
OriginalCopy.Length,
|
OriginalCopy.Length,
|
||||||
sizeof(ULONG));
|
sizeof(WCHAR));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_SEH_HANDLE
|
_SEH_HANDLE
|
||||||
|
|
Loading…
Reference in a new issue