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);
@ -86,9 +87,12 @@ CmUnRegisterCallback(IN LARGE_INTEGER Cookie)
CurrentCallback = CONTAINING_RECORD(CurrentEntry, REGISTRY_CALLBACK, ListEntry);
if(CurrentCallback->Cookie.QuadPart == Cookie.QuadPart)
{
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 */
@ -104,6 +108,13 @@ CmUnRegisterCallback(IN LARGE_INTEGER Cookie)
ExFreePool(CurrentCallback);
return STATUS_SUCCESS;
}
else
{
/* pending delete, pretend like it already is deleted */
ExReleaseFastMutex(&CmiCallbackLock);
return STATUS_UNSUCCESSFUL;
}
}
}
ExReleaseFastMutex(&CmiCallbackLock);
@ -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,
@ -553,6 +553,8 @@ ObDeleteHandle(PEPROCESS Process,
POBJECT_HEADER Header;
HANDLE_BLOCK *Block;
PAGED_CODE();
DPRINT("ObDeleteHandle(Handle %x)\n",Handle);
HandleTable = &Process->HandleTable;
@ -631,6 +633,8 @@ ObCreateHandle(PEPROCESS Process,
PHANDLE_TABLE HandleTable;
KIRQL oldlvl;
PAGED_CODE();
DPRINT("ObCreateHandle(Process %x, obj %x)\n",Process,ObjectBody);
ASSERT(Process);
@ -724,6 +728,8 @@ ObQueryObjectAuditingByHandle(IN HANDLE Handle,
KIRQL oldIrql;
PHANDLE_ENTRY HandleEntry;
PAGED_CODE();
DPRINT("ObQueryObjectAuditingByHandle(Handle %x)\n", Handle);
Process = PsGetCurrentProcess();
@ -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);
@ -967,6 +973,8 @@ ObInsertObject(IN PVOID Object,
POBJECT_HEADER ObjectHeader;
ACCESS_MASK Access;
PAGED_CODE();
Access = DesiredAccess;
ObjectHeader = BODY_TO_HEADER(Object);

View file

@ -56,6 +56,8 @@ ObReferenceObjectByName(PUNICODE_STRING ObjectPath,
OBJECT_ATTRIBUTES ObjectAttributes;
NTSTATUS Status;
PAGED_CODE();
InitializeObjectAttributes(&ObjectAttributes,
ObjectPath,
Attributes,
@ -127,6 +129,8 @@ ObOpenObjectByName(IN POBJECT_ATTRIBUTES ObjectAttributes,
PVOID Object = NULL;
NTSTATUS Status;
PAGED_CODE();
DPRINT("ObOpenObjectByName(...)\n");
Status = ObFindObject(ObjectAttributes,

View file

@ -38,6 +38,8 @@ NtSetInformationObject (IN HANDLE ObjectHandle,
PVOID Object;
NTSTATUS Status;
PAGED_CODE();
if (ObjectInformationClass != ObjectHandleInformation)
return STATUS_INVALID_INFO_CLASS;
@ -89,6 +91,8 @@ NtQueryObject (IN HANDLE ObjectHandle,
PVOID Object;
NTSTATUS Status;
PAGED_CODE();
Status = ObReferenceObjectByHandle (ObjectHandle,
0,
NULL,
@ -261,6 +265,8 @@ NtMakeTemporaryObject(IN HANDLE ObjectHandle)
PVOID ObjectBody;
NTSTATUS Status;
PAGED_CODE();
Status = ObReferenceObjectByHandle(ObjectHandle,
0,
NULL,
@ -300,6 +306,8 @@ NtMakePermanentObject(IN HANDLE ObjectHandle)
PVOID ObjectBody;
NTSTATUS Status;
PAGED_CODE();
Status = ObReferenceObjectByHandle(ObjectHandle,
0,
NULL,

View file

@ -347,6 +347,8 @@ ObFindObject(POBJECT_ATTRIBUTES ObjectAttributes,
ULONG Attributes;
PUNICODE_STRING ObjectName;
PAGED_CODE();
DPRINT("ObFindObject(ObjectAttributes %x, ReturnedObject %x, "
"RemainingPath %x)\n",ObjectAttributes,ReturnedObject,RemainingPath);
DPRINT("ObjectAttributes->ObjectName %wZ\n",
@ -484,6 +486,8 @@ ObQueryNameString (IN PVOID Object,
ULONG LocalReturnLength;
NTSTATUS Status;
PAGED_CODE();
*ReturnLength = 0;
if (Length < sizeof(OBJECT_NAME_INFORMATION) + sizeof(WCHAR))
@ -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)
{
@ -815,6 +819,8 @@ ObReferenceObjectByPointer(IN PVOID Object,
{
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,
@ -1118,6 +1126,8 @@ ObGetObjectPointerCount(PVOID Object)
{
POBJECT_HEADER Header;
PAGED_CODE();
ASSERT(Object);
Header = BODY_TO_HEADER(Object);
@ -1143,6 +1153,8 @@ 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
@ -28,6 +28,8 @@ ObAssignSecurity(IN PACCESS_STATE AccessState,
PSECURITY_DESCRIPTOR NewDescriptor;
NTSTATUS Status;
PAGED_CODE();
/* Build the new security descriptor */
Status = SeAssignSecurity(SecurityDescriptor,
AccessState->SecurityDescriptor,
@ -74,6 +76,8 @@ ObGetObjectSecurity(IN PVOID Object,
ULONG Length;
NTSTATUS Status;
PAGED_CODE();
Header = BODY_TO_HEADER(Object);
if (Header->ObjectType == NULL)
return STATUS_UNSUCCESSFUL;
@ -129,6 +133,8 @@ VOID STDCALL
ObReleaseObjectSecurity(IN PSECURITY_DESCRIPTOR SecurityDescriptor,
IN BOOLEAN MemoryAllocated)
{
PAGED_CODE();
if (SecurityDescriptor == NULL)
return;
@ -157,6 +163,8 @@ NtQuerySecurityObject(IN HANDLE Handle,
PVOID Object;
NTSTATUS Status;
PAGED_CODE();
DPRINT("NtQuerySecurityObject() called\n");
Status = ObReferenceObjectByHandle(Handle,
@ -227,6 +235,8 @@ NtSetSecurityObject(IN HANDLE Handle,
ULONG_PTR Current;
NTSTATUS Status;
PAGED_CODE();
DPRINT("NtSetSecurityObject() called\n");
Status = ObReferenceObjectByHandle(Handle,

View file

@ -206,43 +206,64 @@ 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))
{
return(Status);
}
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));
@ -251,16 +272,38 @@ NtCreateSymbolicLinkObject(OUT PHANDLE LinkHandle,
SymbolicLink->TargetName.MaximumLength,
TAG_SYMLINK_TARGET);
RtlCopyUnicodeString(&SymbolicLink->TargetName,
LinkTarget);
&CapturedLinkTarget);
DPRINT("DeviceName %S\n", SymbolicLink->TargetName.Buffer);
ZwQuerySystemTime (&SymbolicLink->CreateTime);
DPRINT("%s() = STATUS_SUCCESS\n",__FUNCTION__);
Status = ObInsertObject ((PVOID)SymbolicLink,
NULL,
DesiredAccess,
0,
NULL,
&hLink);
if (NT_SUCCESS(Status))
{
_SEH_TRY
{
*LinkHandle = hLink;
}
_SEH_HANDLE
{
Status = _SEH_GetExceptionCode();
}
_SEH_END;
}
ObDereferenceObject(SymbolicLink);
}
return(STATUS_SUCCESS);
RtlReleaseCapturedUnicodeString(&CapturedLinkTarget,
PreviousMode,
FALSE);
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,
Status = ObOpenObjectByName(ObjectAttributes,
ObSymbolicLinkType,
NULL,
(KPROCESSOR_MODE)KeGetPreviousMode(),
PreviousMode,
DesiredAccess,
NULL,
LinkHandle));
&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;
Status = ObReferenceObjectByHandle(LinkHandle,
SYMBOLIC_LINK_QUERY,
ObSymbolicLinkType,
(KPROCESSOR_MODE)KeGetPreviousMode(),
(PVOID *)&SymlinkObject,
NULL);
if(!NT_SUCCESS(Status))
{
return Status;
}
if (ResultLength != NULL)
}
else
{
*ResultLength = (ULONG)SymlinkObject->TargetName.Length + sizeof(WCHAR);
SafeLinkTarget = *LinkTarget;
}
if (LinkTarget->MaximumLength >= SymlinkObject->TargetName.Length + sizeof(WCHAR))
Status = ObReferenceObjectByHandle(LinkHandle,
SYMBOLIC_LINK_QUERY,
ObSymbolicLinkType,
PreviousMode,
(PVOID *)&SymlinkObject,
NULL);
if (NT_SUCCESS(Status))
{
RtlCopyUnicodeString(LinkTarget,
ULONG LengthRequired = SymlinkObject->TargetName.Length + sizeof(WCHAR);
_SEH_TRY
{
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);
Status = STATUS_SUCCESS;
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;
ObDereferenceObject(SymlinkObject);
}
return Status;
}

View file

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