added more irql checks and secured access to buffers in symbolic link code

svn path=/trunk/; revision=13718
This commit is contained in:
Thomas Bluemel 2005-02-22 21:09:54 +00:00
parent 87428f5f55
commit 310c7ac816
10 changed files with 288 additions and 83 deletions

View file

@ -431,6 +431,7 @@ typedef struct _REGISTRY_CALLBACK
PEX_CALLBACK_FUNCTION Function;
PVOID Context;
LARGE_INTEGER Cookie;
BOOLEAN PendingDelete;
} REGISTRY_CALLBACK, *PREGISTRY_CALLBACK;
NTSTATUS

View file

@ -50,6 +50,7 @@ CmRegisterCallback(IN PEX_CALLBACK_FUNCTION Function,
ExInitializeRundownProtection(&Callback->RundownRef);
Callback->Function = Function;
Callback->Context = Context;
Callback->PendingDelete = FALSE;
/* add it to the callback list and receive a cookie for the callback */
ExAcquireFastMutex(&CmiCallbackLock);
@ -87,22 +88,32 @@ CmUnRegisterCallback(IN LARGE_INTEGER Cookie)
CurrentCallback = CONTAINING_RECORD(CurrentEntry, REGISTRY_CALLBACK, ListEntry);
if(CurrentCallback->Cookie.QuadPart == Cookie.QuadPart)
{
/* found the callback, don't unlink it from the list yet so we don't screw
the calling loop */
ExReleaseFastMutex(&CmiCallbackLock);
if(!CurrentCallback->PendingDelete)
{
/* found the callback, don't unlink it from the list yet so we don't screw
the calling loop */
CurrentCallback->PendingDelete = TRUE;
ExReleaseFastMutex(&CmiCallbackLock);
/* if the callback is currently executing, wait until it finished */
ExWaitForRundownProtectionRelease(&CurrentCallback->RundownRef);
/* if the callback is currently executing, wait until it finished */
ExWaitForRundownProtectionRelease(&CurrentCallback->RundownRef);
/* time to unlink it. It's now safe because every attempt to acquire a
runtime protection on this callback will fail */
ExAcquireFastMutex(&CmiCallbackLock);
RemoveEntryList(&CurrentCallback->ListEntry);
ExReleaseFastMutex(&CmiCallbackLock);
/* time to unlink it. It's now safe because every attempt to acquire a
runtime protection on this callback will fail */
ExAcquireFastMutex(&CmiCallbackLock);
RemoveEntryList(&CurrentCallback->ListEntry);
ExReleaseFastMutex(&CmiCallbackLock);
/* free the callback */
ExFreePool(CurrentCallback);
return STATUS_SUCCESS;
/* free the callback */
ExFreePool(CurrentCallback);
return STATUS_SUCCESS;
}
else
{
/* pending delete, pretend like it already is deleted */
ExReleaseFastMutex(&CmiCallbackLock);
return STATUS_UNSUCCESSFUL;
}
}
}
@ -127,7 +138,8 @@ CmiCallRegisteredCallbacks(IN REG_NOTIFY_CLASS Argument1,
PREGISTRY_CALLBACK CurrentCallback;
CurrentCallback = CONTAINING_RECORD(CurrentEntry, REGISTRY_CALLBACK, ListEntry);
if(ExAcquireRundownProtectionEx(&CurrentCallback->RundownRef, 1))
if(!CurrentCallback->PendingDelete &&
ExAcquireRundownProtectionEx(&CurrentCallback->RundownRef, 1))
{
NTSTATUS Status;

View file

@ -50,6 +50,8 @@ NtOpenDirectoryObject (OUT PHANDLE DirectoryHandle,
KPROCESSOR_MODE PreviousMode;
NTSTATUS Status = STATUS_SUCCESS;
PAGED_CODE();
PreviousMode = ExGetPreviousMode();
if(PreviousMode != KernelMode)
@ -169,6 +171,8 @@ NtQueryDirectoryObject (IN HANDLE DirectoryHandle,
ULONG NextEntry = 0;
NTSTATUS Status = STATUS_SUCCESS;
PAGED_CODE();
PreviousMode = ExGetPreviousMode();
if(PreviousMode != KernelMode)
@ -427,6 +431,8 @@ NtCreateDirectoryObject (OUT PHANDLE DirectoryHandle,
KPROCESSOR_MODE PreviousMode;
NTSTATUS Status = STATUS_SUCCESS;
PAGED_CODE();
DPRINT("NtCreateDirectoryObject(DirectoryHandle %x, "
"DesiredAccess %x, ObjectAttributes %x\n",
DirectoryHandle, DesiredAccess, ObjectAttributes);

View file

@ -287,7 +287,7 @@ NtDuplicateObject (IN HANDLE SourceProcessHandle,
HANDLE TargetHandle;
NTSTATUS Status;
ASSERT_IRQL(PASSIVE_LEVEL);
PAGED_CODE();
Status = ObReferenceObjectByHandle(SourceProcessHandle,
PROCESS_DUP_HANDLE,
@ -552,6 +552,8 @@ ObDeleteHandle(PEPROCESS Process,
PHANDLE_TABLE HandleTable;
POBJECT_HEADER Header;
HANDLE_BLOCK *Block;
PAGED_CODE();
DPRINT("ObDeleteHandle(Handle %x)\n",Handle);
@ -630,6 +632,8 @@ ObCreateHandle(PEPROCESS Process,
HANDLE_BLOCK* new_blk = NULL;
PHANDLE_TABLE HandleTable;
KIRQL oldlvl;
PAGED_CODE();
DPRINT("ObCreateHandle(Process %x, obj %x)\n",Process,ObjectBody);
@ -723,6 +727,8 @@ ObQueryObjectAuditingByHandle(IN HANDLE Handle,
PEPROCESS Process;
KIRQL oldIrql;
PHANDLE_ENTRY HandleEntry;
PAGED_CODE();
DPRINT("ObQueryObjectAuditingByHandle(Handle %x)\n", Handle);
@ -777,7 +783,7 @@ ObReferenceObjectByHandle(HANDLE Handle,
ULONG Attributes;
NTSTATUS Status;
ASSERT_IRQL(PASSIVE_LEVEL);
PAGED_CODE();
DPRINT("ObReferenceObjectByHandle(Handle %x, DesiredAccess %x, "
"ObjectType %x, AccessMode %d, Object %x)\n",Handle,DesiredAccess,
@ -930,7 +936,7 @@ NtClose(IN HANDLE Handle)
POBJECT_HEADER Header;
NTSTATUS Status;
ASSERT_IRQL(PASSIVE_LEVEL);
PAGED_CODE();
DPRINT("NtClose(Handle %x)\n",Handle);
@ -966,6 +972,8 @@ ObInsertObject(IN PVOID Object,
{
POBJECT_HEADER ObjectHeader;
ACCESS_MASK Access;
PAGED_CODE();
Access = DesiredAccess;
ObjectHeader = BODY_TO_HEADER(Object);

View file

@ -55,6 +55,8 @@ ObReferenceObjectByName(PUNICODE_STRING ObjectPath,
UNICODE_STRING RemainingPath;
OBJECT_ATTRIBUTES ObjectAttributes;
NTSTATUS Status;
PAGED_CODE();
InitializeObjectAttributes(&ObjectAttributes,
ObjectPath,
@ -126,6 +128,8 @@ ObOpenObjectByName(IN POBJECT_ATTRIBUTES ObjectAttributes,
UNICODE_STRING RemainingPath;
PVOID Object = NULL;
NTSTATUS Status;
PAGED_CODE();
DPRINT("ObOpenObjectByName(...)\n");

View file

@ -37,6 +37,8 @@ NtSetInformationObject (IN HANDLE ObjectHandle,
{
PVOID Object;
NTSTATUS Status;
PAGED_CODE();
if (ObjectInformationClass != ObjectHandleInformation)
return STATUS_INVALID_INFO_CLASS;
@ -88,6 +90,8 @@ NtQueryObject (IN HANDLE ObjectHandle,
ULONG InfoLength;
PVOID Object;
NTSTATUS Status;
PAGED_CODE();
Status = ObReferenceObjectByHandle (ObjectHandle,
0,
@ -260,6 +264,8 @@ NtMakeTemporaryObject(IN HANDLE ObjectHandle)
{
PVOID ObjectBody;
NTSTATUS Status;
PAGED_CODE();
Status = ObReferenceObjectByHandle(ObjectHandle,
0,
@ -299,6 +305,8 @@ NtMakePermanentObject(IN HANDLE ObjectHandle)
{
PVOID ObjectBody;
NTSTATUS Status;
PAGED_CODE();
Status = ObReferenceObjectByHandle(ObjectHandle,
0,

View file

@ -346,6 +346,8 @@ ObFindObject(POBJECT_ATTRIBUTES ObjectAttributes,
UNICODE_STRING PathString;
ULONG Attributes;
PUNICODE_STRING ObjectName;
PAGED_CODE();
DPRINT("ObFindObject(ObjectAttributes %x, ReturnedObject %x, "
"RemainingPath %x)\n",ObjectAttributes,ReturnedObject,RemainingPath);
@ -483,6 +485,8 @@ ObQueryNameString (IN PVOID Object,
POBJECT_HEADER ObjectHeader;
ULONG LocalReturnLength;
NTSTATUS Status;
PAGED_CODE();
*ReturnLength = 0;
@ -611,7 +615,7 @@ ObCreateObject (IN KPROCESSOR_MODE ObjectAttributesAccessMode OPTIONAL,
PSECURITY_DESCRIPTOR NewSecurityDescriptor = NULL;
SECURITY_SUBJECT_CONTEXT SubjectContext;
ASSERT_IRQL(APC_LEVEL);
PAGED_CODE();
if(ObjectAttributesAccessMode == UserMode && ObjectAttributes != NULL)
{
@ -814,6 +818,8 @@ ObReferenceObjectByPointer(IN PVOID Object,
IN KPROCESSOR_MODE AccessMode)
{
POBJECT_HEADER Header;
/* NOTE: should be possible to reference an object above APC_LEVEL! */
DPRINT("ObReferenceObjectByPointer(Object %x, ObjectType %x)\n",
Object,ObjectType);
@ -876,6 +882,8 @@ ObOpenObjectByPointer(IN POBJECT Object,
{
NTSTATUS Status;
PAGED_CODE();
DPRINT("ObOpenObjectByPointer()\n");
Status = ObReferenceObjectByPointer(Object,
@ -1117,6 +1125,8 @@ ULONG STDCALL
ObGetObjectPointerCount(PVOID Object)
{
POBJECT_HEADER Header;
PAGED_CODE();
ASSERT(Object);
Header = BODY_TO_HEADER(Object);
@ -1142,6 +1152,8 @@ ULONG
ObGetObjectHandleCount(PVOID Object)
{
POBJECT_HEADER Header;
PAGED_CODE();
ASSERT(Object);
Header = BODY_TO_HEADER(Object);

View file

@ -1,4 +1,4 @@
/* $Id:$
/* $Id$
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -27,6 +27,8 @@ ObAssignSecurity(IN PACCESS_STATE AccessState,
{
PSECURITY_DESCRIPTOR NewDescriptor;
NTSTATUS Status;
PAGED_CODE();
/* Build the new security descriptor */
Status = SeAssignSecurity(SecurityDescriptor,
@ -73,6 +75,8 @@ ObGetObjectSecurity(IN PVOID Object,
POBJECT_HEADER Header;
ULONG Length;
NTSTATUS Status;
PAGED_CODE();
Header = BODY_TO_HEADER(Object);
if (Header->ObjectType == NULL)
@ -129,6 +133,8 @@ VOID STDCALL
ObReleaseObjectSecurity(IN PSECURITY_DESCRIPTOR SecurityDescriptor,
IN BOOLEAN MemoryAllocated)
{
PAGED_CODE();
if (SecurityDescriptor == NULL)
return;
@ -156,6 +162,8 @@ NtQuerySecurityObject(IN HANDLE Handle,
POBJECT_HEADER Header;
PVOID Object;
NTSTATUS Status;
PAGED_CODE();
DPRINT("NtQuerySecurityObject() called\n");
@ -226,6 +234,8 @@ NtSetSecurityObject(IN HANDLE Handle,
ULONG Control = 0;
ULONG_PTR Current;
NTSTATUS Status;
PAGED_CODE();
DPRINT("NtSetSecurityObject() called\n");

View file

@ -206,61 +206,104 @@ NtCreateSymbolicLinkObject(OUT PHANDLE LinkHandle,
IN POBJECT_ATTRIBUTES ObjectAttributes,
IN PUNICODE_STRING LinkTarget)
{
HANDLE hLink;
PSYMLINK_OBJECT SymbolicLink;
NTSTATUS Status;
UNICODE_STRING CapturedLinkTarget;
KPROCESSOR_MODE PreviousMode;
NTSTATUS Status = STATUS_SUCCESS;
ASSERT_IRQL(PASSIVE_LEVEL);
PAGED_CODE();
PreviousMode = ExGetPreviousMode();
if(PreviousMode != KernelMode)
{
_SEH_TRY
{
ProbeForWrite(LinkHandle,
sizeof(HANDLE),
sizeof(ULONG));
}
_SEH_HANDLE
{
Status = _SEH_GetExceptionCode();
}
_SEH_END;
if(!NT_SUCCESS(Status))
{
return Status;
}
}
Status = RtlCaptureUnicodeString(&CapturedLinkTarget,
PreviousMode,
PagedPool,
FALSE,
LinkTarget);
if(!NT_SUCCESS(Status))
{
DPRINT1("NtCreateSymbolicLinkObject: Capturing the target link failed!\n");
return Status;
}
DPRINT("NtCreateSymbolicLinkObject(LinkHandle %p, DesiredAccess %ul, ObjectAttributes %p, LinkTarget %wZ)\n",
LinkHandle,
DesiredAccess,
ObjectAttributes,
LinkTarget);
&CapturedLinkTarget);
Status = ObCreateObject(ExGetPreviousMode(),
ObSymbolicLinkType,
ObjectAttributes,
ExGetPreviousMode(),
PreviousMode,
NULL,
sizeof(SYMLINK_OBJECT),
0,
0,
(PVOID*)&SymbolicLink);
if (!NT_SUCCESS(Status))
if (NT_SUCCESS(Status))
{
SymbolicLink->TargetName.Length = 0;
SymbolicLink->TargetName.MaximumLength =
((wcslen(LinkTarget->Buffer) + 1) * sizeof(WCHAR));
SymbolicLink->TargetName.Buffer =
ExAllocatePoolWithTag(NonPagedPool,
SymbolicLink->TargetName.MaximumLength,
TAG_SYMLINK_TARGET);
RtlCopyUnicodeString(&SymbolicLink->TargetName,
&CapturedLinkTarget);
DPRINT("DeviceName %S\n", SymbolicLink->TargetName.Buffer);
ZwQuerySystemTime (&SymbolicLink->CreateTime);
Status = ObInsertObject ((PVOID)SymbolicLink,
NULL,
DesiredAccess,
0,
NULL,
&hLink);
if (NT_SUCCESS(Status))
{
return(Status);
_SEH_TRY
{
*LinkHandle = hLink;
}
_SEH_HANDLE
{
Status = _SEH_GetExceptionCode();
}
_SEH_END;
}
ObDereferenceObject(SymbolicLink);
}
RtlReleaseCapturedUnicodeString(&CapturedLinkTarget,
PreviousMode,
FALSE);
Status = ObInsertObject ((PVOID)SymbolicLink,
NULL,
DesiredAccess,
0,
NULL,
LinkHandle);
if (!NT_SUCCESS(Status))
{
ObDereferenceObject (SymbolicLink);
return Status;
}
SymbolicLink->TargetName.Length = 0;
SymbolicLink->TargetName.MaximumLength =
((wcslen(LinkTarget->Buffer) + 1) * sizeof(WCHAR));
SymbolicLink->TargetName.Buffer =
ExAllocatePoolWithTag(NonPagedPool,
SymbolicLink->TargetName.MaximumLength,
TAG_SYMLINK_TARGET);
RtlCopyUnicodeString(&SymbolicLink->TargetName,
LinkTarget);
DPRINT("DeviceName %S\n", SymbolicLink->TargetName.Buffer);
ZwQuerySystemTime (&SymbolicLink->CreateTime);
DPRINT("%s() = STATUS_SUCCESS\n",__FUNCTION__);
ObDereferenceObject(SymbolicLink);
return(STATUS_SUCCESS);
return Status;
}
@ -282,16 +325,58 @@ NtOpenSymbolicLinkObject(OUT PHANDLE LinkHandle,
IN ACCESS_MASK DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes)
{
HANDLE hLink;
KPROCESSOR_MODE PreviousMode;
NTSTATUS Status = STATUS_SUCCESS;
PAGED_CODE();
PreviousMode = ExGetPreviousMode();
if(PreviousMode != KernelMode)
{
_SEH_TRY
{
ProbeForWrite(LinkHandle,
sizeof(HANDLE),
sizeof(ULONG));
}
_SEH_HANDLE
{
Status = _SEH_GetExceptionCode();
}
_SEH_END;
if(!NT_SUCCESS(Status))
{
return Status;
}
}
DPRINT("NtOpenSymbolicLinkObject (Name %wZ)\n",
ObjectAttributes->ObjectName);
return(ObOpenObjectByName(ObjectAttributes,
ObSymbolicLinkType,
NULL,
(KPROCESSOR_MODE)KeGetPreviousMode(),
DesiredAccess,
NULL,
LinkHandle));
Status = ObOpenObjectByName(ObjectAttributes,
ObSymbolicLinkType,
NULL,
PreviousMode,
DesiredAccess,
NULL,
&hLink);
if(NT_SUCCESS(Status))
{
_SEH_TRY
{
*LinkHandle = hLink;
}
_SEH_HANDLE
{
Status = _SEH_GetExceptionCode();
}
_SEH_END;
}
return Status;
}
@ -313,37 +398,92 @@ NtQuerySymbolicLinkObject(IN HANDLE LinkHandle,
OUT PUNICODE_STRING LinkTarget,
OUT PULONG ResultLength OPTIONAL)
{
UNICODE_STRING SafeLinkTarget;
PSYMLINK_OBJECT SymlinkObject;
NTSTATUS Status;
KPROCESSOR_MODE PreviousMode;
NTSTATUS Status = STATUS_SUCCESS;
PAGED_CODE();
PreviousMode = ExGetPreviousMode();
if(PreviousMode != KernelMode)
{
_SEH_TRY
{
/* probe the unicode string and buffers supplied */
ProbeForWrite(LinkTarget,
sizeof(UNICODE_STRING),
sizeof(ULONG));
SafeLinkTarget = *LinkTarget;
ProbeForWrite(SafeLinkTarget.Buffer,
SafeLinkTarget.MaximumLength,
sizeof(WCHAR));
if(ResultLength != NULL)
{
ProbeForWrite(ResultLength,
sizeof(ULONG),
sizeof(ULONG));
}
}
_SEH_HANDLE
{
Status = _SEH_GetExceptionCode();
}
_SEH_END;
if(!NT_SUCCESS(Status))
{
return Status;
}
}
else
{
SafeLinkTarget = *LinkTarget;
}
Status = ObReferenceObjectByHandle(LinkHandle,
SYMBOLIC_LINK_QUERY,
ObSymbolicLinkType,
(KPROCESSOR_MODE)KeGetPreviousMode(),
PreviousMode,
(PVOID *)&SymlinkObject,
NULL);
if (!NT_SUCCESS(Status))
if (NT_SUCCESS(Status))
{
ULONG LengthRequired = SymlinkObject->TargetName.Length + sizeof(WCHAR);
_SEH_TRY
{
return Status;
if(SafeLinkTarget.MaximumLength >= LengthRequired)
{
/* don't pass TargetLink to RtlCopyUnicodeString here because the caller
might have modified the structure which could lead to a copy into
kernel memory! */
RtlCopyUnicodeString(&SafeLinkTarget,
&SymlinkObject->TargetName);
SafeLinkTarget.Buffer[SafeLinkTarget.Length / sizeof(WCHAR)] = L'\0';
/* copy back the new UNICODE_STRING structure */
*LinkTarget = SafeLinkTarget;
}
else
{
Status = STATUS_BUFFER_TOO_SMALL;
}
if(ResultLength != NULL)
{
*ResultLength = LengthRequired;
}
}
_SEH_HANDLE
{
Status = _SEH_GetExceptionCode();
}
_SEH_END;
if (ResultLength != NULL)
{
*ResultLength = (ULONG)SymlinkObject->TargetName.Length + sizeof(WCHAR);
}
if (LinkTarget->MaximumLength >= SymlinkObject->TargetName.Length + sizeof(WCHAR))
{
RtlCopyUnicodeString(LinkTarget,
&SymlinkObject->TargetName);
Status = STATUS_SUCCESS;
}
else
{
Status = STATUS_BUFFER_TOO_SMALL;
}
ObDereferenceObject(SymlinkObject);
ObDereferenceObject(SymlinkObject);
}
return Status;
}

View file

@ -91,6 +91,8 @@ PoSetPowerState(
IN POWER_STATE State)
{
POWER_STATE ps;
ASSERT_IRQL(DISPATCH_LEVEL);
ps.SystemState = PowerSystemWorking; // Fully on
ps.DeviceState = PowerDeviceD0; // Fully on
@ -228,6 +230,8 @@ NtPowerInformation(
)
{
NTSTATUS Status;
PAGED_CODE();
DPRINT("NtPowerInformation(PowerInformationLevel 0x%x, InputBuffer 0x%x, "
"InputBufferLength 0x%x, OutputBuffer 0x%x, OutputBufferLength 0x%x)\n",