fixed semaphore functions to securely access buffers and some minor fixes

svn path=/trunk/; revision=13232
This commit is contained in:
Thomas Bluemel 2005-01-23 22:09:27 +00:00
parent b25bf92b14
commit baf658a398
3 changed files with 208 additions and 53 deletions

View file

@ -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
); );

View file

@ -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,12 +89,36 @@ 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;
Status = ObCreateObject(ExGetPreviousMode(), 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 = ObCreateObject(PreviousMode,
ExSemaphoreObjectType, ExSemaphoreObjectType,
ObjectAttributes, ObjectAttributes,
ExGetPreviousMode(), PreviousMode,
NULL, NULL,
sizeof(KSEMAPHORE), sizeof(KSEMAPHORE),
0, 0,
@ -94,9 +126,6 @@ NtCreateSemaphore(OUT PHANDLE SemaphoreHandle,
(PVOID*)&Semaphore); (PVOID*)&Semaphore);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
return(Status);
}
KeInitializeSemaphore(Semaphore, KeInitializeSemaphore(Semaphore,
InitialCount, InitialCount,
MaximumCount); MaximumCount);
@ -106,33 +135,89 @@ NtCreateSemaphore(OUT PHANDLE SemaphoreHandle,
DesiredAccess, DesiredAccess,
0, 0,
NULL, NULL,
SemaphoreHandle); &hSemaphore);
ObDereferenceObject(Semaphore); ObDereferenceObject(Semaphore);
if(NT_SUCCESS(Status))
{
_SEH_TRY
{
*SemaphoreHandle = hSemaphore;
}
_SEH_HANDLE
{
Status = _SEH_GetExceptionCode();
}
_SEH_END;
}
}
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 = ObReferenceObjectByHandle(SemaphoreHandle, &Status);
SEMAPHORE_QUERY_STATE,
ExSemaphoreObjectType,
UserMode,
(PVOID*)&Semaphore,
NULL);
if(!NT_SUCCESS(Status)) if(!NT_SUCCESS(Status))
{
DPRINT1("NtQueryEvent() failed, Status: 0x%x\n", Status);
return Status; return Status;
Info->CurrentCount = KeReadStateSemaphore(Semaphore);
Info->MaximumCount = Semaphore->Limit;
if (ReturnLength != NULL)
*ReturnLength = sizeof(SEMAPHORE_BASIC_INFORMATION);
ObDereferenceObject(Semaphore);
return STATUS_SUCCESS;
} }
Status = ObReferenceObjectByHandle(SemaphoreHandle,
EVENT_QUERY_STATE,
ExSemaphoreObjectType,
PreviousMode,
(PVOID*)&Semaphore,
NULL);
if(NT_SUCCESS(Status))
{
switch(SemaphoreInformationClass)
{
case SemaphoreBasicInformation:
{
PSEMAPHORE_BASIC_INFORMATION BasicInfo = (PSEMAPHORE_BASIC_INFORMATION)SemaphoreInformation;
_SEH_TRY
{
BasicInfo->CurrentCount = KeReadStateSemaphore(Semaphore);
BasicInfo->MaximumCount = Semaphore->Limit;
if(ReturnLength != NULL)
{
*ReturnLength = sizeof(SEMAPHORE_BASIC_INFORMATION);
}
}
_SEH_HANDLE
{
Status = _SEH_GetExceptionCode();
}
_SEH_END;
break;
}
default:
Status = STATUS_NOT_IMPLEMENTED;
break;
}
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))
{ {
return(Status); LONG PrevCount = KeReleaseSemaphore(Semaphore,
}
KeReleaseSemaphore(Semaphore,
IO_NO_INCREMENT, IO_NO_INCREMENT,
ReleaseCount, ReleaseCount,
FALSE); FALSE);
ObDereferenceObject(Semaphore); ObDereferenceObject(Semaphore);
return(STATUS_SUCCESS);
if(PreviousCount != NULL)
{
_SEH_TRY
{
*PreviousCount = PrevCount;
}
_SEH_HANDLE
{
Status = _SEH_GetExceptionCode();
}
_SEH_END;
}
}
return Status;
} }
/* EOF */ /* EOF */

View file

@ -169,7 +169,7 @@ failbasiccleanup:
{ {
ProbeForRead(OriginalCopy.Buffer, ProbeForRead(OriginalCopy.Buffer,
OriginalCopy.Length, OriginalCopy.Length,
sizeof(ULONG)); sizeof(WCHAR));
} }
} }
_SEH_HANDLE _SEH_HANDLE