mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 10:04:49 +00:00
added more irql checks and secured access to buffers in symbolic link code
svn path=/trunk/; revision=13718
This commit is contained in:
parent
87428f5f55
commit
310c7ac816
10 changed files with 288 additions and 83 deletions
|
@ -431,6 +431,7 @@ typedef struct _REGISTRY_CALLBACK
|
||||||
PEX_CALLBACK_FUNCTION Function;
|
PEX_CALLBACK_FUNCTION Function;
|
||||||
PVOID Context;
|
PVOID Context;
|
||||||
LARGE_INTEGER Cookie;
|
LARGE_INTEGER Cookie;
|
||||||
|
BOOLEAN PendingDelete;
|
||||||
} REGISTRY_CALLBACK, *PREGISTRY_CALLBACK;
|
} REGISTRY_CALLBACK, *PREGISTRY_CALLBACK;
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
|
|
|
@ -50,6 +50,7 @@ CmRegisterCallback(IN PEX_CALLBACK_FUNCTION Function,
|
||||||
ExInitializeRundownProtection(&Callback->RundownRef);
|
ExInitializeRundownProtection(&Callback->RundownRef);
|
||||||
Callback->Function = Function;
|
Callback->Function = Function;
|
||||||
Callback->Context = Context;
|
Callback->Context = Context;
|
||||||
|
Callback->PendingDelete = FALSE;
|
||||||
|
|
||||||
/* add it to the callback list and receive a cookie for the callback */
|
/* add it to the callback list and receive a cookie for the callback */
|
||||||
ExAcquireFastMutex(&CmiCallbackLock);
|
ExAcquireFastMutex(&CmiCallbackLock);
|
||||||
|
@ -87,22 +88,32 @@ CmUnRegisterCallback(IN LARGE_INTEGER Cookie)
|
||||||
CurrentCallback = CONTAINING_RECORD(CurrentEntry, REGISTRY_CALLBACK, ListEntry);
|
CurrentCallback = CONTAINING_RECORD(CurrentEntry, REGISTRY_CALLBACK, ListEntry);
|
||||||
if(CurrentCallback->Cookie.QuadPart == Cookie.QuadPart)
|
if(CurrentCallback->Cookie.QuadPart == Cookie.QuadPart)
|
||||||
{
|
{
|
||||||
/* found the callback, don't unlink it from the list yet so we don't screw
|
if(!CurrentCallback->PendingDelete)
|
||||||
the calling loop */
|
{
|
||||||
ExReleaseFastMutex(&CmiCallbackLock);
|
/* 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 */
|
/* if the callback is currently executing, wait until it finished */
|
||||||
ExWaitForRundownProtectionRelease(&CurrentCallback->RundownRef);
|
ExWaitForRundownProtectionRelease(&CurrentCallback->RundownRef);
|
||||||
|
|
||||||
/* time to unlink it. It's now safe because every attempt to acquire a
|
/* time to unlink it. It's now safe because every attempt to acquire a
|
||||||
runtime protection on this callback will fail */
|
runtime protection on this callback will fail */
|
||||||
ExAcquireFastMutex(&CmiCallbackLock);
|
ExAcquireFastMutex(&CmiCallbackLock);
|
||||||
RemoveEntryList(&CurrentCallback->ListEntry);
|
RemoveEntryList(&CurrentCallback->ListEntry);
|
||||||
ExReleaseFastMutex(&CmiCallbackLock);
|
ExReleaseFastMutex(&CmiCallbackLock);
|
||||||
|
|
||||||
/* free the callback */
|
/* free the callback */
|
||||||
ExFreePool(CurrentCallback);
|
ExFreePool(CurrentCallback);
|
||||||
return STATUS_SUCCESS;
|
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;
|
PREGISTRY_CALLBACK CurrentCallback;
|
||||||
|
|
||||||
CurrentCallback = CONTAINING_RECORD(CurrentEntry, REGISTRY_CALLBACK, ListEntry);
|
CurrentCallback = CONTAINING_RECORD(CurrentEntry, REGISTRY_CALLBACK, ListEntry);
|
||||||
if(ExAcquireRundownProtectionEx(&CurrentCallback->RundownRef, 1))
|
if(!CurrentCallback->PendingDelete &&
|
||||||
|
ExAcquireRundownProtectionEx(&CurrentCallback->RundownRef, 1))
|
||||||
{
|
{
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
|
||||||
|
|
|
@ -50,6 +50,8 @@ NtOpenDirectoryObject (OUT PHANDLE DirectoryHandle,
|
||||||
KPROCESSOR_MODE PreviousMode;
|
KPROCESSOR_MODE PreviousMode;
|
||||||
NTSTATUS Status = STATUS_SUCCESS;
|
NTSTATUS Status = STATUS_SUCCESS;
|
||||||
|
|
||||||
|
PAGED_CODE();
|
||||||
|
|
||||||
PreviousMode = ExGetPreviousMode();
|
PreviousMode = ExGetPreviousMode();
|
||||||
|
|
||||||
if(PreviousMode != KernelMode)
|
if(PreviousMode != KernelMode)
|
||||||
|
@ -169,6 +171,8 @@ NtQueryDirectoryObject (IN HANDLE DirectoryHandle,
|
||||||
ULONG NextEntry = 0;
|
ULONG NextEntry = 0;
|
||||||
NTSTATUS Status = STATUS_SUCCESS;
|
NTSTATUS Status = STATUS_SUCCESS;
|
||||||
|
|
||||||
|
PAGED_CODE();
|
||||||
|
|
||||||
PreviousMode = ExGetPreviousMode();
|
PreviousMode = ExGetPreviousMode();
|
||||||
|
|
||||||
if(PreviousMode != KernelMode)
|
if(PreviousMode != KernelMode)
|
||||||
|
@ -427,6 +431,8 @@ NtCreateDirectoryObject (OUT PHANDLE DirectoryHandle,
|
||||||
KPROCESSOR_MODE PreviousMode;
|
KPROCESSOR_MODE PreviousMode;
|
||||||
NTSTATUS Status = STATUS_SUCCESS;
|
NTSTATUS Status = STATUS_SUCCESS;
|
||||||
|
|
||||||
|
PAGED_CODE();
|
||||||
|
|
||||||
DPRINT("NtCreateDirectoryObject(DirectoryHandle %x, "
|
DPRINT("NtCreateDirectoryObject(DirectoryHandle %x, "
|
||||||
"DesiredAccess %x, ObjectAttributes %x\n",
|
"DesiredAccess %x, ObjectAttributes %x\n",
|
||||||
DirectoryHandle, DesiredAccess, ObjectAttributes);
|
DirectoryHandle, DesiredAccess, ObjectAttributes);
|
||||||
|
|
|
@ -287,7 +287,7 @@ NtDuplicateObject (IN HANDLE SourceProcessHandle,
|
||||||
HANDLE TargetHandle;
|
HANDLE TargetHandle;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
|
||||||
ASSERT_IRQL(PASSIVE_LEVEL);
|
PAGED_CODE();
|
||||||
|
|
||||||
Status = ObReferenceObjectByHandle(SourceProcessHandle,
|
Status = ObReferenceObjectByHandle(SourceProcessHandle,
|
||||||
PROCESS_DUP_HANDLE,
|
PROCESS_DUP_HANDLE,
|
||||||
|
@ -553,6 +553,8 @@ ObDeleteHandle(PEPROCESS Process,
|
||||||
POBJECT_HEADER Header;
|
POBJECT_HEADER Header;
|
||||||
HANDLE_BLOCK *Block;
|
HANDLE_BLOCK *Block;
|
||||||
|
|
||||||
|
PAGED_CODE();
|
||||||
|
|
||||||
DPRINT("ObDeleteHandle(Handle %x)\n",Handle);
|
DPRINT("ObDeleteHandle(Handle %x)\n",Handle);
|
||||||
|
|
||||||
HandleTable = &Process->HandleTable;
|
HandleTable = &Process->HandleTable;
|
||||||
|
@ -631,6 +633,8 @@ ObCreateHandle(PEPROCESS Process,
|
||||||
PHANDLE_TABLE HandleTable;
|
PHANDLE_TABLE HandleTable;
|
||||||
KIRQL oldlvl;
|
KIRQL oldlvl;
|
||||||
|
|
||||||
|
PAGED_CODE();
|
||||||
|
|
||||||
DPRINT("ObCreateHandle(Process %x, obj %x)\n",Process,ObjectBody);
|
DPRINT("ObCreateHandle(Process %x, obj %x)\n",Process,ObjectBody);
|
||||||
|
|
||||||
ASSERT(Process);
|
ASSERT(Process);
|
||||||
|
@ -724,6 +728,8 @@ ObQueryObjectAuditingByHandle(IN HANDLE Handle,
|
||||||
KIRQL oldIrql;
|
KIRQL oldIrql;
|
||||||
PHANDLE_ENTRY HandleEntry;
|
PHANDLE_ENTRY HandleEntry;
|
||||||
|
|
||||||
|
PAGED_CODE();
|
||||||
|
|
||||||
DPRINT("ObQueryObjectAuditingByHandle(Handle %x)\n", Handle);
|
DPRINT("ObQueryObjectAuditingByHandle(Handle %x)\n", Handle);
|
||||||
|
|
||||||
Process = PsGetCurrentProcess();
|
Process = PsGetCurrentProcess();
|
||||||
|
@ -777,7 +783,7 @@ ObReferenceObjectByHandle(HANDLE Handle,
|
||||||
ULONG Attributes;
|
ULONG Attributes;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
|
||||||
ASSERT_IRQL(PASSIVE_LEVEL);
|
PAGED_CODE();
|
||||||
|
|
||||||
DPRINT("ObReferenceObjectByHandle(Handle %x, DesiredAccess %x, "
|
DPRINT("ObReferenceObjectByHandle(Handle %x, DesiredAccess %x, "
|
||||||
"ObjectType %x, AccessMode %d, Object %x)\n",Handle,DesiredAccess,
|
"ObjectType %x, AccessMode %d, Object %x)\n",Handle,DesiredAccess,
|
||||||
|
@ -930,7 +936,7 @@ NtClose(IN HANDLE Handle)
|
||||||
POBJECT_HEADER Header;
|
POBJECT_HEADER Header;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
|
||||||
ASSERT_IRQL(PASSIVE_LEVEL);
|
PAGED_CODE();
|
||||||
|
|
||||||
DPRINT("NtClose(Handle %x)\n",Handle);
|
DPRINT("NtClose(Handle %x)\n",Handle);
|
||||||
|
|
||||||
|
@ -967,6 +973,8 @@ ObInsertObject(IN PVOID Object,
|
||||||
POBJECT_HEADER ObjectHeader;
|
POBJECT_HEADER ObjectHeader;
|
||||||
ACCESS_MASK Access;
|
ACCESS_MASK Access;
|
||||||
|
|
||||||
|
PAGED_CODE();
|
||||||
|
|
||||||
Access = DesiredAccess;
|
Access = DesiredAccess;
|
||||||
ObjectHeader = BODY_TO_HEADER(Object);
|
ObjectHeader = BODY_TO_HEADER(Object);
|
||||||
|
|
||||||
|
|
|
@ -56,6 +56,8 @@ ObReferenceObjectByName(PUNICODE_STRING ObjectPath,
|
||||||
OBJECT_ATTRIBUTES ObjectAttributes;
|
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
|
||||||
|
PAGED_CODE();
|
||||||
|
|
||||||
InitializeObjectAttributes(&ObjectAttributes,
|
InitializeObjectAttributes(&ObjectAttributes,
|
||||||
ObjectPath,
|
ObjectPath,
|
||||||
Attributes,
|
Attributes,
|
||||||
|
@ -127,6 +129,8 @@ ObOpenObjectByName(IN POBJECT_ATTRIBUTES ObjectAttributes,
|
||||||
PVOID Object = NULL;
|
PVOID Object = NULL;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
|
||||||
|
PAGED_CODE();
|
||||||
|
|
||||||
DPRINT("ObOpenObjectByName(...)\n");
|
DPRINT("ObOpenObjectByName(...)\n");
|
||||||
|
|
||||||
Status = ObFindObject(ObjectAttributes,
|
Status = ObFindObject(ObjectAttributes,
|
||||||
|
|
|
@ -38,6 +38,8 @@ NtSetInformationObject (IN HANDLE ObjectHandle,
|
||||||
PVOID Object;
|
PVOID Object;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
|
||||||
|
PAGED_CODE();
|
||||||
|
|
||||||
if (ObjectInformationClass != ObjectHandleInformation)
|
if (ObjectInformationClass != ObjectHandleInformation)
|
||||||
return STATUS_INVALID_INFO_CLASS;
|
return STATUS_INVALID_INFO_CLASS;
|
||||||
|
|
||||||
|
@ -89,6 +91,8 @@ NtQueryObject (IN HANDLE ObjectHandle,
|
||||||
PVOID Object;
|
PVOID Object;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
|
||||||
|
PAGED_CODE();
|
||||||
|
|
||||||
Status = ObReferenceObjectByHandle (ObjectHandle,
|
Status = ObReferenceObjectByHandle (ObjectHandle,
|
||||||
0,
|
0,
|
||||||
NULL,
|
NULL,
|
||||||
|
@ -261,6 +265,8 @@ NtMakeTemporaryObject(IN HANDLE ObjectHandle)
|
||||||
PVOID ObjectBody;
|
PVOID ObjectBody;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
|
||||||
|
PAGED_CODE();
|
||||||
|
|
||||||
Status = ObReferenceObjectByHandle(ObjectHandle,
|
Status = ObReferenceObjectByHandle(ObjectHandle,
|
||||||
0,
|
0,
|
||||||
NULL,
|
NULL,
|
||||||
|
@ -300,6 +306,8 @@ NtMakePermanentObject(IN HANDLE ObjectHandle)
|
||||||
PVOID ObjectBody;
|
PVOID ObjectBody;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
|
||||||
|
PAGED_CODE();
|
||||||
|
|
||||||
Status = ObReferenceObjectByHandle(ObjectHandle,
|
Status = ObReferenceObjectByHandle(ObjectHandle,
|
||||||
0,
|
0,
|
||||||
NULL,
|
NULL,
|
||||||
|
|
|
@ -347,6 +347,8 @@ ObFindObject(POBJECT_ATTRIBUTES ObjectAttributes,
|
||||||
ULONG Attributes;
|
ULONG Attributes;
|
||||||
PUNICODE_STRING ObjectName;
|
PUNICODE_STRING ObjectName;
|
||||||
|
|
||||||
|
PAGED_CODE();
|
||||||
|
|
||||||
DPRINT("ObFindObject(ObjectAttributes %x, ReturnedObject %x, "
|
DPRINT("ObFindObject(ObjectAttributes %x, ReturnedObject %x, "
|
||||||
"RemainingPath %x)\n",ObjectAttributes,ReturnedObject,RemainingPath);
|
"RemainingPath %x)\n",ObjectAttributes,ReturnedObject,RemainingPath);
|
||||||
DPRINT("ObjectAttributes->ObjectName %wZ\n",
|
DPRINT("ObjectAttributes->ObjectName %wZ\n",
|
||||||
|
@ -484,6 +486,8 @@ ObQueryNameString (IN PVOID Object,
|
||||||
ULONG LocalReturnLength;
|
ULONG LocalReturnLength;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
|
||||||
|
PAGED_CODE();
|
||||||
|
|
||||||
*ReturnLength = 0;
|
*ReturnLength = 0;
|
||||||
|
|
||||||
if (Length < sizeof(OBJECT_NAME_INFORMATION) + sizeof(WCHAR))
|
if (Length < sizeof(OBJECT_NAME_INFORMATION) + sizeof(WCHAR))
|
||||||
|
@ -611,7 +615,7 @@ ObCreateObject (IN KPROCESSOR_MODE ObjectAttributesAccessMode OPTIONAL,
|
||||||
PSECURITY_DESCRIPTOR NewSecurityDescriptor = NULL;
|
PSECURITY_DESCRIPTOR NewSecurityDescriptor = NULL;
|
||||||
SECURITY_SUBJECT_CONTEXT SubjectContext;
|
SECURITY_SUBJECT_CONTEXT SubjectContext;
|
||||||
|
|
||||||
ASSERT_IRQL(APC_LEVEL);
|
PAGED_CODE();
|
||||||
|
|
||||||
if(ObjectAttributesAccessMode == UserMode && ObjectAttributes != NULL)
|
if(ObjectAttributesAccessMode == UserMode && ObjectAttributes != NULL)
|
||||||
{
|
{
|
||||||
|
@ -815,6 +819,8 @@ ObReferenceObjectByPointer(IN PVOID Object,
|
||||||
{
|
{
|
||||||
POBJECT_HEADER Header;
|
POBJECT_HEADER Header;
|
||||||
|
|
||||||
|
/* NOTE: should be possible to reference an object above APC_LEVEL! */
|
||||||
|
|
||||||
DPRINT("ObReferenceObjectByPointer(Object %x, ObjectType %x)\n",
|
DPRINT("ObReferenceObjectByPointer(Object %x, ObjectType %x)\n",
|
||||||
Object,ObjectType);
|
Object,ObjectType);
|
||||||
|
|
||||||
|
@ -876,6 +882,8 @@ ObOpenObjectByPointer(IN POBJECT Object,
|
||||||
{
|
{
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
|
||||||
|
PAGED_CODE();
|
||||||
|
|
||||||
DPRINT("ObOpenObjectByPointer()\n");
|
DPRINT("ObOpenObjectByPointer()\n");
|
||||||
|
|
||||||
Status = ObReferenceObjectByPointer(Object,
|
Status = ObReferenceObjectByPointer(Object,
|
||||||
|
@ -1118,6 +1126,8 @@ ObGetObjectPointerCount(PVOID Object)
|
||||||
{
|
{
|
||||||
POBJECT_HEADER Header;
|
POBJECT_HEADER Header;
|
||||||
|
|
||||||
|
PAGED_CODE();
|
||||||
|
|
||||||
ASSERT(Object);
|
ASSERT(Object);
|
||||||
Header = BODY_TO_HEADER(Object);
|
Header = BODY_TO_HEADER(Object);
|
||||||
|
|
||||||
|
@ -1143,6 +1153,8 @@ ObGetObjectHandleCount(PVOID Object)
|
||||||
{
|
{
|
||||||
POBJECT_HEADER Header;
|
POBJECT_HEADER Header;
|
||||||
|
|
||||||
|
PAGED_CODE();
|
||||||
|
|
||||||
ASSERT(Object);
|
ASSERT(Object);
|
||||||
Header = BODY_TO_HEADER(Object);
|
Header = BODY_TO_HEADER(Object);
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $Id:$
|
/* $Id$
|
||||||
*
|
*
|
||||||
* COPYRIGHT: See COPYING in the top level directory
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
|
@ -28,6 +28,8 @@ ObAssignSecurity(IN PACCESS_STATE AccessState,
|
||||||
PSECURITY_DESCRIPTOR NewDescriptor;
|
PSECURITY_DESCRIPTOR NewDescriptor;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
|
||||||
|
PAGED_CODE();
|
||||||
|
|
||||||
/* Build the new security descriptor */
|
/* Build the new security descriptor */
|
||||||
Status = SeAssignSecurity(SecurityDescriptor,
|
Status = SeAssignSecurity(SecurityDescriptor,
|
||||||
AccessState->SecurityDescriptor,
|
AccessState->SecurityDescriptor,
|
||||||
|
@ -74,6 +76,8 @@ ObGetObjectSecurity(IN PVOID Object,
|
||||||
ULONG Length;
|
ULONG Length;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
|
||||||
|
PAGED_CODE();
|
||||||
|
|
||||||
Header = BODY_TO_HEADER(Object);
|
Header = BODY_TO_HEADER(Object);
|
||||||
if (Header->ObjectType == NULL)
|
if (Header->ObjectType == NULL)
|
||||||
return STATUS_UNSUCCESSFUL;
|
return STATUS_UNSUCCESSFUL;
|
||||||
|
@ -129,6 +133,8 @@ VOID STDCALL
|
||||||
ObReleaseObjectSecurity(IN PSECURITY_DESCRIPTOR SecurityDescriptor,
|
ObReleaseObjectSecurity(IN PSECURITY_DESCRIPTOR SecurityDescriptor,
|
||||||
IN BOOLEAN MemoryAllocated)
|
IN BOOLEAN MemoryAllocated)
|
||||||
{
|
{
|
||||||
|
PAGED_CODE();
|
||||||
|
|
||||||
if (SecurityDescriptor == NULL)
|
if (SecurityDescriptor == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -157,6 +163,8 @@ NtQuerySecurityObject(IN HANDLE Handle,
|
||||||
PVOID Object;
|
PVOID Object;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
|
||||||
|
PAGED_CODE();
|
||||||
|
|
||||||
DPRINT("NtQuerySecurityObject() called\n");
|
DPRINT("NtQuerySecurityObject() called\n");
|
||||||
|
|
||||||
Status = ObReferenceObjectByHandle(Handle,
|
Status = ObReferenceObjectByHandle(Handle,
|
||||||
|
@ -227,6 +235,8 @@ NtSetSecurityObject(IN HANDLE Handle,
|
||||||
ULONG_PTR Current;
|
ULONG_PTR Current;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
|
||||||
|
PAGED_CODE();
|
||||||
|
|
||||||
DPRINT("NtSetSecurityObject() called\n");
|
DPRINT("NtSetSecurityObject() called\n");
|
||||||
|
|
||||||
Status = ObReferenceObjectByHandle(Handle,
|
Status = ObReferenceObjectByHandle(Handle,
|
||||||
|
|
|
@ -206,61 +206,104 @@ NtCreateSymbolicLinkObject(OUT PHANDLE LinkHandle,
|
||||||
IN POBJECT_ATTRIBUTES ObjectAttributes,
|
IN POBJECT_ATTRIBUTES ObjectAttributes,
|
||||||
IN PUNICODE_STRING LinkTarget)
|
IN PUNICODE_STRING LinkTarget)
|
||||||
{
|
{
|
||||||
|
HANDLE hLink;
|
||||||
PSYMLINK_OBJECT SymbolicLink;
|
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",
|
DPRINT("NtCreateSymbolicLinkObject(LinkHandle %p, DesiredAccess %ul, ObjectAttributes %p, LinkTarget %wZ)\n",
|
||||||
LinkHandle,
|
LinkHandle,
|
||||||
DesiredAccess,
|
DesiredAccess,
|
||||||
ObjectAttributes,
|
ObjectAttributes,
|
||||||
LinkTarget);
|
&CapturedLinkTarget);
|
||||||
|
|
||||||
Status = ObCreateObject(ExGetPreviousMode(),
|
Status = ObCreateObject(ExGetPreviousMode(),
|
||||||
ObSymbolicLinkType,
|
ObSymbolicLinkType,
|
||||||
ObjectAttributes,
|
ObjectAttributes,
|
||||||
ExGetPreviousMode(),
|
PreviousMode,
|
||||||
NULL,
|
NULL,
|
||||||
sizeof(SYMLINK_OBJECT),
|
sizeof(SYMLINK_OBJECT),
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
(PVOID*)&SymbolicLink);
|
(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);
|
||||||
|
}
|
||||||
|
|
||||||
Status = ObInsertObject ((PVOID)SymbolicLink,
|
RtlReleaseCapturedUnicodeString(&CapturedLinkTarget,
|
||||||
NULL,
|
PreviousMode,
|
||||||
DesiredAccess,
|
FALSE);
|
||||||
0,
|
|
||||||
NULL,
|
|
||||||
LinkHandle);
|
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
ObDereferenceObject (SymbolicLink);
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
SymbolicLink->TargetName.Length = 0;
|
return Status;
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -282,16 +325,58 @@ NtOpenSymbolicLinkObject(OUT PHANDLE LinkHandle,
|
||||||
IN ACCESS_MASK DesiredAccess,
|
IN ACCESS_MASK DesiredAccess,
|
||||||
IN POBJECT_ATTRIBUTES ObjectAttributes)
|
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",
|
DPRINT("NtOpenSymbolicLinkObject (Name %wZ)\n",
|
||||||
ObjectAttributes->ObjectName);
|
ObjectAttributes->ObjectName);
|
||||||
|
|
||||||
return(ObOpenObjectByName(ObjectAttributes,
|
Status = ObOpenObjectByName(ObjectAttributes,
|
||||||
ObSymbolicLinkType,
|
ObSymbolicLinkType,
|
||||||
NULL,
|
NULL,
|
||||||
(KPROCESSOR_MODE)KeGetPreviousMode(),
|
PreviousMode,
|
||||||
DesiredAccess,
|
DesiredAccess,
|
||||||
NULL,
|
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 PUNICODE_STRING LinkTarget,
|
||||||
OUT PULONG ResultLength OPTIONAL)
|
OUT PULONG ResultLength OPTIONAL)
|
||||||
{
|
{
|
||||||
|
UNICODE_STRING SafeLinkTarget;
|
||||||
PSYMLINK_OBJECT SymlinkObject;
|
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,
|
Status = ObReferenceObjectByHandle(LinkHandle,
|
||||||
SYMBOLIC_LINK_QUERY,
|
SYMBOLIC_LINK_QUERY,
|
||||||
ObSymbolicLinkType,
|
ObSymbolicLinkType,
|
||||||
(KPROCESSOR_MODE)KeGetPreviousMode(),
|
PreviousMode,
|
||||||
(PVOID *)&SymlinkObject,
|
(PVOID *)&SymlinkObject,
|
||||||
NULL);
|
NULL);
|
||||||
if (!NT_SUCCESS(Status))
|
if (NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
return Status;
|
ULONG LengthRequired = SymlinkObject->TargetName.Length + sizeof(WCHAR);
|
||||||
}
|
|
||||||
|
|
||||||
if (ResultLength != NULL)
|
_SEH_TRY
|
||||||
{
|
{
|
||||||
*ResultLength = (ULONG)SymlinkObject->TargetName.Length + sizeof(WCHAR);
|
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 (LinkTarget->MaximumLength >= SymlinkObject->TargetName.Length + sizeof(WCHAR))
|
if(ResultLength != NULL)
|
||||||
{
|
{
|
||||||
RtlCopyUnicodeString(LinkTarget,
|
*ResultLength = LengthRequired;
|
||||||
&SymlinkObject->TargetName);
|
}
|
||||||
Status = STATUS_SUCCESS;
|
|
||||||
}
|
}
|
||||||
else
|
_SEH_HANDLE
|
||||||
{
|
{
|
||||||
Status = STATUS_BUFFER_TOO_SMALL;
|
Status = _SEH_GetExceptionCode();
|
||||||
}
|
}
|
||||||
|
_SEH_END;
|
||||||
|
|
||||||
ObDereferenceObject(SymlinkObject);
|
ObDereferenceObject(SymlinkObject);
|
||||||
|
}
|
||||||
|
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
|
@ -92,6 +92,8 @@ PoSetPowerState(
|
||||||
{
|
{
|
||||||
POWER_STATE ps;
|
POWER_STATE ps;
|
||||||
|
|
||||||
|
ASSERT_IRQL(DISPATCH_LEVEL);
|
||||||
|
|
||||||
ps.SystemState = PowerSystemWorking; // Fully on
|
ps.SystemState = PowerSystemWorking; // Fully on
|
||||||
ps.DeviceState = PowerDeviceD0; // Fully on
|
ps.DeviceState = PowerDeviceD0; // Fully on
|
||||||
|
|
||||||
|
@ -229,6 +231,8 @@ NtPowerInformation(
|
||||||
{
|
{
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
|
||||||
|
PAGED_CODE();
|
||||||
|
|
||||||
DPRINT("NtPowerInformation(PowerInformationLevel 0x%x, InputBuffer 0x%x, "
|
DPRINT("NtPowerInformation(PowerInformationLevel 0x%x, InputBuffer 0x%x, "
|
||||||
"InputBufferLength 0x%x, OutputBuffer 0x%x, OutputBufferLength 0x%x)\n",
|
"InputBufferLength 0x%x, OutputBuffer 0x%x, OutputBufferLength 0x%x)\n",
|
||||||
PowerInformationLevel,
|
PowerInformationLevel,
|
||||||
|
|
Loading…
Reference in a new issue