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

View file

@ -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);
@ -86,9 +87,12 @@ 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)
{
if(!CurrentCallback->PendingDelete)
{ {
/* found the callback, don't unlink it from the list yet so we don't screw /* found the callback, don't unlink it from the list yet so we don't screw
the calling loop */ the calling loop */
CurrentCallback->PendingDelete = TRUE;
ExReleaseFastMutex(&CmiCallbackLock); ExReleaseFastMutex(&CmiCallbackLock);
/* if the callback is currently executing, wait until it finished */ /* if the callback is currently executing, wait until it finished */
@ -104,6 +108,13 @@ CmUnRegisterCallback(IN LARGE_INTEGER Cookie)
ExFreePool(CurrentCallback); ExFreePool(CurrentCallback);
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
else
{
/* pending delete, pretend like it already is deleted */
ExReleaseFastMutex(&CmiCallbackLock);
return STATUS_UNSUCCESSFUL;
}
}
} }
ExReleaseFastMutex(&CmiCallbackLock); ExReleaseFastMutex(&CmiCallbackLock);
@ -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;

View file

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

View file

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

View file

@ -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,

View file

@ -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,

View file

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

View file

@ -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,

View file

@ -206,43 +206,64 @@ 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))
{ {
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.Length = 0;
SymbolicLink->TargetName.MaximumLength = SymbolicLink->TargetName.MaximumLength =
((wcslen(LinkTarget->Buffer) + 1) * sizeof(WCHAR)); ((wcslen(LinkTarget->Buffer) + 1) * sizeof(WCHAR));
@ -251,16 +272,38 @@ NtCreateSymbolicLinkObject(OUT PHANDLE LinkHandle,
SymbolicLink->TargetName.MaximumLength, SymbolicLink->TargetName.MaximumLength,
TAG_SYMLINK_TARGET); TAG_SYMLINK_TARGET);
RtlCopyUnicodeString(&SymbolicLink->TargetName, RtlCopyUnicodeString(&SymbolicLink->TargetName,
LinkTarget); &CapturedLinkTarget);
DPRINT("DeviceName %S\n", SymbolicLink->TargetName.Buffer); DPRINT("DeviceName %S\n", SymbolicLink->TargetName.Buffer);
ZwQuerySystemTime (&SymbolicLink->CreateTime); 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); ObDereferenceObject(SymbolicLink);
}
return(STATUS_SUCCESS); RtlReleaseCapturedUnicodeString(&CapturedLinkTarget,
PreviousMode,
FALSE);
return Status;
} }
@ -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;
Status = ObReferenceObjectByHandle(LinkHandle,
SYMBOLIC_LINK_QUERY,
ObSymbolicLinkType,
(KPROCESSOR_MODE)KeGetPreviousMode(),
(PVOID *)&SymlinkObject,
NULL);
if(!NT_SUCCESS(Status)) if(!NT_SUCCESS(Status))
{ {
return 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); &SymlinkObject->TargetName);
Status = STATUS_SUCCESS; SafeLinkTarget.Buffer[SafeLinkTarget.Length / sizeof(WCHAR)] = L'\0';
/* copy back the new UNICODE_STRING structure */
*LinkTarget = SafeLinkTarget;
} }
else else
{ {
Status = STATUS_BUFFER_TOO_SMALL; Status = STATUS_BUFFER_TOO_SMALL;
} }
if(ResultLength != NULL)
{
*ResultLength = LengthRequired;
}
}
_SEH_HANDLE
{
Status = _SEH_GetExceptionCode();
}
_SEH_END;
ObDereferenceObject(SymlinkObject); ObDereferenceObject(SymlinkObject);
}
return Status; return Status;
} }

View file

@ -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,