diff --git a/reactos/ntoskrnl/cm/cm.h b/reactos/ntoskrnl/cm/cm.h index 0a4a9e0db0e..f3579cd777b 100644 --- a/reactos/ntoskrnl/cm/cm.h +++ b/reactos/ntoskrnl/cm/cm.h @@ -431,6 +431,7 @@ typedef struct _REGISTRY_CALLBACK PEX_CALLBACK_FUNCTION Function; PVOID Context; LARGE_INTEGER Cookie; + BOOLEAN PendingDelete; } REGISTRY_CALLBACK, *PREGISTRY_CALLBACK; NTSTATUS diff --git a/reactos/ntoskrnl/cm/ntfunc.c b/reactos/ntoskrnl/cm/ntfunc.c index 6da91f148dd..a34bc97e0a0 100644 --- a/reactos/ntoskrnl/cm/ntfunc.c +++ b/reactos/ntoskrnl/cm/ntfunc.c @@ -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; diff --git a/reactos/ntoskrnl/ob/dirobj.c b/reactos/ntoskrnl/ob/dirobj.c index fab1f3d4001..57bcc7ac748 100644 --- a/reactos/ntoskrnl/ob/dirobj.c +++ b/reactos/ntoskrnl/ob/dirobj.c @@ -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); diff --git a/reactos/ntoskrnl/ob/handle.c b/reactos/ntoskrnl/ob/handle.c index 7e2306a3ddd..b7811227fbb 100644 --- a/reactos/ntoskrnl/ob/handle.c +++ b/reactos/ntoskrnl/ob/handle.c @@ -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); diff --git a/reactos/ntoskrnl/ob/namespc.c b/reactos/ntoskrnl/ob/namespc.c index 23a3d3f0a9b..f67794ad08c 100644 --- a/reactos/ntoskrnl/ob/namespc.c +++ b/reactos/ntoskrnl/ob/namespc.c @@ -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"); diff --git a/reactos/ntoskrnl/ob/ntobj.c b/reactos/ntoskrnl/ob/ntobj.c index 91d9b86a872..048936ad52c 100644 --- a/reactos/ntoskrnl/ob/ntobj.c +++ b/reactos/ntoskrnl/ob/ntobj.c @@ -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, diff --git a/reactos/ntoskrnl/ob/object.c b/reactos/ntoskrnl/ob/object.c index b065b353377..f54fbf62674 100644 --- a/reactos/ntoskrnl/ob/object.c +++ b/reactos/ntoskrnl/ob/object.c @@ -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); diff --git a/reactos/ntoskrnl/ob/security.c b/reactos/ntoskrnl/ob/security.c index ef6d4383c00..0b72810f48f 100644 --- a/reactos/ntoskrnl/ob/security.c +++ b/reactos/ntoskrnl/ob/security.c @@ -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"); diff --git a/reactos/ntoskrnl/ob/symlink.c b/reactos/ntoskrnl/ob/symlink.c index 88dcc5f145f..4f7462b6c00 100644 --- a/reactos/ntoskrnl/ob/symlink.c +++ b/reactos/ntoskrnl/ob/symlink.c @@ -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; } diff --git a/reactos/ntoskrnl/po/power.c b/reactos/ntoskrnl/po/power.c index b50bd0912d5..b478b9cc3c8 100644 --- a/reactos/ntoskrnl/po/power.c +++ b/reactos/ntoskrnl/po/power.c @@ -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",