mirror of
https://github.com/reactos/reactos.git
synced 2025-06-26 12:49:42 +00:00
revert my last changes back to Alex's version of ObpCaptureObjectAttributes as I'm being an incompetent ass. This will introduce several vulnerabilities and bugs again.
svn path=/trunk/; revision=17217
This commit is contained in:
parent
4280eeb5a3
commit
3ed0977d46
7 changed files with 152 additions and 326 deletions
|
@ -192,19 +192,20 @@ NtCreateKey(OUT PHANDLE KeyHandle,
|
||||||
PWSTR Start;
|
PWSTR Start;
|
||||||
UNICODE_STRING ObjectName;
|
UNICODE_STRING ObjectName;
|
||||||
OBJECT_CREATE_INFORMATION ObjectCreateInfo;
|
OBJECT_CREATE_INFORMATION ObjectCreateInfo;
|
||||||
KPROCESSOR_MODE PreviousMode;
|
|
||||||
unsigned i;
|
unsigned i;
|
||||||
|
|
||||||
PAGED_CODE();
|
PAGED_CODE();
|
||||||
|
|
||||||
PreviousMode = KeGetPreviousMode();
|
DPRINT("NtCreateKey (Name %wZ KeyHandle 0x%p Root 0x%p)\n",
|
||||||
|
ObjectAttributes->ObjectName,
|
||||||
|
KeyHandle,
|
||||||
|
ObjectAttributes->RootDirectory);
|
||||||
|
|
||||||
/* Capture all the info */
|
/* Capture all the info */
|
||||||
DPRINT("Capturing Create Info\n");
|
DPRINT("Capturing Create Info\n");
|
||||||
Status = ObpCaptureObjectAttributes(ObjectAttributes,
|
Status = ObpCaptureObjectAttributes(ObjectAttributes,
|
||||||
PreviousMode,
|
KeGetPreviousMode(),
|
||||||
PagedPool,
|
CmiKeyType,
|
||||||
FALSE,
|
|
||||||
&ObjectCreateInfo,
|
&ObjectCreateInfo,
|
||||||
&ObjectName);
|
&ObjectName);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
|
@ -218,10 +219,8 @@ NtCreateKey(OUT PHANDLE KeyHandle,
|
||||||
(PVOID*)&Object,
|
(PVOID*)&Object,
|
||||||
&RemainingPath,
|
&RemainingPath,
|
||||||
CmiKeyType);
|
CmiKeyType);
|
||||||
ObpReleaseCapturedAttributes(&ObjectCreateInfo,
|
ObpReleaseCapturedAttributes(&ObjectCreateInfo);
|
||||||
&ObjectName,
|
if (ObjectName.Buffer) ExFreePool(ObjectName.Buffer);
|
||||||
PreviousMode,
|
|
||||||
FALSE);
|
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
DPRINT("CmpFindObject failed, Status: 0x%x\n", Status);
|
DPRINT("CmpFindObject failed, Status: 0x%x\n", Status);
|
||||||
|
@ -1170,8 +1169,7 @@ NtOpenKey(OUT PHANDLE KeyHandle,
|
||||||
DPRINT("Capturing Create Info\n");
|
DPRINT("Capturing Create Info\n");
|
||||||
Status = ObpCaptureObjectAttributes(ObjectAttributes,
|
Status = ObpCaptureObjectAttributes(ObjectAttributes,
|
||||||
PreviousMode,
|
PreviousMode,
|
||||||
PagedPool,
|
CmiKeyType,
|
||||||
FALSE,
|
|
||||||
&ObjectCreateInfo,
|
&ObjectCreateInfo,
|
||||||
&ObjectName);
|
&ObjectName);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
|
@ -1187,10 +1185,8 @@ NtOpenKey(OUT PHANDLE KeyHandle,
|
||||||
(PVOID*)&Object,
|
(PVOID*)&Object,
|
||||||
&RemainingPath,
|
&RemainingPath,
|
||||||
CmiKeyType);
|
CmiKeyType);
|
||||||
ObpReleaseCapturedAttributes(&ObjectCreateInfo,
|
ObpReleaseCapturedAttributes(&ObjectCreateInfo);
|
||||||
&ObjectName,
|
if (ObjectName.Buffer) ExFreePool(ObjectName.Buffer);
|
||||||
PreviousMode,
|
|
||||||
FALSE);
|
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
DPRINT("CmpFindObject() returned 0x%08lx\n", Status);
|
DPRINT("CmpFindObject() returned 0x%08lx\n", Status);
|
||||||
|
|
|
@ -705,8 +705,7 @@ CmiConnectHive(IN POBJECT_ATTRIBUTES KeyObjectAttributes,
|
||||||
DPRINT("Capturing Create Info\n");
|
DPRINT("Capturing Create Info\n");
|
||||||
Status = ObpCaptureObjectAttributes(KeyObjectAttributes,
|
Status = ObpCaptureObjectAttributes(KeyObjectAttributes,
|
||||||
KernelMode,
|
KernelMode,
|
||||||
PagedPool,
|
CmiKeyType,
|
||||||
FALSE,
|
|
||||||
&ObjectCreateInfo,
|
&ObjectCreateInfo,
|
||||||
&ObjectName);
|
&ObjectName);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
|
@ -720,10 +719,8 @@ CmiConnectHive(IN POBJECT_ATTRIBUTES KeyObjectAttributes,
|
||||||
(PVOID*)&ParentKey,
|
(PVOID*)&ParentKey,
|
||||||
&RemainingPath,
|
&RemainingPath,
|
||||||
CmiKeyType);
|
CmiKeyType);
|
||||||
ObpReleaseCapturedAttributes(&ObjectCreateInfo,
|
ObpReleaseCapturedAttributes(&ObjectCreateInfo);
|
||||||
&ObjectName,
|
if (ObjectName.Buffer) ExFreePool(ObjectName.Buffer);
|
||||||
KernelMode,
|
|
||||||
FALSE);
|
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
return Status;
|
return Status;
|
||||||
|
|
|
@ -173,6 +173,14 @@ ObFastDereferenceObject(IN PEX_FAST_REF FastRef,
|
||||||
|
|
||||||
/* Secure object information functions */
|
/* Secure object information functions */
|
||||||
|
|
||||||
|
typedef struct _CAPTURED_OBJECT_ATTRIBUTES
|
||||||
|
{
|
||||||
|
HANDLE RootDirectory;
|
||||||
|
ULONG Attributes;
|
||||||
|
PSECURITY_DESCRIPTOR SecurityDescriptor;
|
||||||
|
PSECURITY_QUALITY_OF_SERVICE SecurityQualityOfService;
|
||||||
|
} CAPTURED_OBJECT_ATTRIBUTES, *PCAPTURED_OBJECT_ATTRIBUTES;
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
STDCALL
|
STDCALL
|
||||||
ObpCaptureObjectName(IN PUNICODE_STRING CapturedName,
|
ObpCaptureObjectName(IN PUNICODE_STRING CapturedName,
|
||||||
|
@ -181,19 +189,16 @@ ObpCaptureObjectName(IN PUNICODE_STRING CapturedName,
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
STDCALL
|
STDCALL
|
||||||
ObpCaptureObjectAttributes(IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,
|
ObpCaptureObjectAttributes(IN POBJECT_ATTRIBUTES ObjectAttributes,
|
||||||
IN KPROCESSOR_MODE AccessMode,
|
IN KPROCESSOR_MODE AccessMode,
|
||||||
IN POOL_TYPE PoolType,
|
IN POBJECT_TYPE ObjectType,
|
||||||
IN BOOLEAN CaptureIfKernel,
|
IN POBJECT_CREATE_INFORMATION ObjectCreateInfo,
|
||||||
OUT POBJECT_CREATE_INFORMATION CapturedObjectAttributes OPTIONAL,
|
OUT PUNICODE_STRING ObjectName);
|
||||||
OUT PUNICODE_STRING ObjectName OPTIONAL);
|
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
STDCALL
|
STDCALL
|
||||||
ObpReleaseCapturedAttributes(IN POBJECT_CREATE_INFORMATION CapturedObjectAttributes OPTIONAL,
|
ObpReleaseCapturedAttributes(IN POBJECT_CREATE_INFORMATION ObjectCreateInfo);
|
||||||
IN PUNICODE_STRING ObjectName OPTIONAL,
|
|
||||||
IN KPROCESSOR_MODE AccessMode,
|
|
||||||
IN BOOLEAN CaptureIfKernel);
|
|
||||||
/* object information classes */
|
/* object information classes */
|
||||||
|
|
||||||
#define ICIF_QUERY 0x1
|
#define ICIF_QUERY 0x1
|
||||||
|
|
|
@ -410,7 +410,7 @@ NtConnectPort (PHANDLE UnsafeConnectedPortHandle,
|
||||||
NULL,
|
NULL,
|
||||||
PORT_ALL_ACCESS, /* DesiredAccess */
|
PORT_ALL_ACCESS, /* DesiredAccess */
|
||||||
LpcPortObjectType,
|
LpcPortObjectType,
|
||||||
PreviousMode,
|
UserMode,
|
||||||
NULL,
|
NULL,
|
||||||
(PVOID*)&NamedPort);
|
(PVOID*)&NamedPort);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
|
@ -430,7 +430,7 @@ NtConnectPort (PHANDLE UnsafeConnectedPortHandle,
|
||||||
Status = ObReferenceObjectByHandle(WriteMap.SectionHandle,
|
Status = ObReferenceObjectByHandle(WriteMap.SectionHandle,
|
||||||
SECTION_MAP_READ | SECTION_MAP_WRITE,
|
SECTION_MAP_READ | SECTION_MAP_WRITE,
|
||||||
MmSectionObjectType,
|
MmSectionObjectType,
|
||||||
PreviousMode,
|
UserMode,
|
||||||
(PVOID*)&SectionObject,
|
(PVOID*)&SectionObject,
|
||||||
NULL);
|
NULL);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
|
|
|
@ -955,7 +955,7 @@ ObInsertObject(IN PVOID Object,
|
||||||
/* First try to find the Object */
|
/* First try to find the Object */
|
||||||
if (ObjectNameInfo && ObjectNameInfo->Name.Buffer)
|
if (ObjectNameInfo && ObjectNameInfo->Name.Buffer)
|
||||||
{
|
{
|
||||||
DPRINT("Object has a name. Trying to find it: \"%wZ\".\n", &ObjectNameInfo->Name);
|
DPRINT("Object has a name. Trying to find it: %wZ.\n", &ObjectNameInfo->Name);
|
||||||
Status = ObFindObject(ObjectCreateInfo,
|
Status = ObFindObject(ObjectCreateInfo,
|
||||||
&ObjectNameInfo->Name,
|
&ObjectNameInfo->Name,
|
||||||
&FoundObject,
|
&FoundObject,
|
||||||
|
@ -1132,10 +1132,7 @@ ObInsertObject(IN PVOID Object,
|
||||||
|
|
||||||
/* We can delete the Create Info now */
|
/* We can delete the Create Info now */
|
||||||
Header->ObjectCreateInfo = NULL;
|
Header->ObjectCreateInfo = NULL;
|
||||||
ObpReleaseCapturedAttributes(ObjectCreateInfo,
|
ObpReleaseCapturedAttributes(ObjectCreateInfo);
|
||||||
NULL,
|
|
||||||
ObjectCreateInfo->ProbeMode,
|
|
||||||
FALSE);
|
|
||||||
ExFreePool(ObjectCreateInfo);
|
ExFreePool(ObjectCreateInfo);
|
||||||
|
|
||||||
DPRINT("Status %x\n", Status);
|
DPRINT("Status %x\n", Status);
|
||||||
|
|
|
@ -70,35 +70,20 @@ ObReferenceObjectByName(PUNICODE_STRING ObjectPath,
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
|
||||||
PAGED_CODE();
|
PAGED_CODE();
|
||||||
|
|
||||||
/* capture the ObjectPath */
|
|
||||||
Status = RtlCaptureUnicodeString(&ObjectName,
|
|
||||||
AccessMode,
|
|
||||||
NonPagedPool, /* FIXME */
|
|
||||||
FALSE,
|
|
||||||
ObjectPath);
|
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
DPRINT("RtlCaptureUnicodeString() failed (Status %lx)\n", Status);
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
InitializeObjectAttributes(&ObjectAttributes,
|
InitializeObjectAttributes(&ObjectAttributes,
|
||||||
&ObjectName,
|
ObjectPath,
|
||||||
Attributes | OBJ_OPENIF,
|
Attributes | OBJ_OPENIF,
|
||||||
NULL,
|
NULL,
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
/* "Capture" all the info, it doesn't make sense to capture from the kernel
|
/* Capture all the info */
|
||||||
stack as the information should be safe anyway...just do a raw copy of the
|
|
||||||
data into the OBJECT_CREATE_INFORMATION structure */
|
|
||||||
DPRINT("Capturing Create Info\n");
|
DPRINT("Capturing Create Info\n");
|
||||||
Status = ObpCaptureObjectAttributes(&ObjectAttributes,
|
Status = ObpCaptureObjectAttributes(&ObjectAttributes,
|
||||||
KernelMode, /* raw copy! */
|
AccessMode,
|
||||||
NonPagedPool,
|
ObjectType,
|
||||||
FALSE,
|
|
||||||
&ObjectCreateInfo,
|
&ObjectCreateInfo,
|
||||||
NULL);
|
&ObjectName);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
DPRINT("ObpCaptureObjectAttributes() failed (Status %lx)\n", Status);
|
DPRINT("ObpCaptureObjectAttributes() failed (Status %lx)\n", Status);
|
||||||
|
@ -111,18 +96,8 @@ ObReferenceObjectByName(PUNICODE_STRING ObjectPath,
|
||||||
&RemainingPath,
|
&RemainingPath,
|
||||||
ObjectType);
|
ObjectType);
|
||||||
|
|
||||||
/* we don't need to release the "captured" object attributes! Nothing was allocated! */
|
ObpReleaseCapturedAttributes(&ObjectCreateInfo);
|
||||||
#if 0
|
if (ObjectName.Buffer) ExFreePool(ObjectName.Buffer);
|
||||||
ObpReleaseCapturedAttributes(&ObjectCreateInfo,
|
|
||||||
NULL,
|
|
||||||
AccessMode,
|
|
||||||
FALSE);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* free the captured ObjectPath if needed */
|
|
||||||
RtlReleaseCapturedUnicodeString(&ObjectName,
|
|
||||||
AccessMode,
|
|
||||||
FALSE);
|
|
||||||
|
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
|
@ -194,8 +169,7 @@ ObOpenObjectByName(IN POBJECT_ATTRIBUTES ObjectAttributes,
|
||||||
DPRINT("Capturing Create Info\n");
|
DPRINT("Capturing Create Info\n");
|
||||||
Status = ObpCaptureObjectAttributes(ObjectAttributes,
|
Status = ObpCaptureObjectAttributes(ObjectAttributes,
|
||||||
AccessMode,
|
AccessMode,
|
||||||
PagedPool,
|
ObjectType,
|
||||||
FALSE,
|
|
||||||
&ObjectCreateInfo,
|
&ObjectCreateInfo,
|
||||||
&ObjectName);
|
&ObjectName);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
|
@ -209,10 +183,8 @@ ObOpenObjectByName(IN POBJECT_ATTRIBUTES ObjectAttributes,
|
||||||
&Object,
|
&Object,
|
||||||
&RemainingPath,
|
&RemainingPath,
|
||||||
ObjectType);
|
ObjectType);
|
||||||
ObpReleaseCapturedAttributes(&ObjectCreateInfo,
|
ObpReleaseCapturedAttributes(&ObjectCreateInfo);
|
||||||
&ObjectName,
|
if (ObjectName.Buffer) ExFreePool(ObjectName.Buffer);
|
||||||
AccessMode,
|
|
||||||
FALSE);
|
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
DPRINT("ObFindObject() failed (Status %lx)\n", Status);
|
DPRINT("ObFindObject() failed (Status %lx)\n", Status);
|
||||||
|
|
|
@ -110,297 +110,162 @@ ObpCaptureObjectName(IN OUT PUNICODE_STRING CapturedName,
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
STDCALL
|
STDCALL
|
||||||
ObpCaptureObjectAttributes(IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,
|
ObpCaptureObjectAttributes(IN POBJECT_ATTRIBUTES ObjectAttributes,
|
||||||
IN KPROCESSOR_MODE AccessMode,
|
IN KPROCESSOR_MODE AccessMode,
|
||||||
IN POOL_TYPE PoolType,
|
IN POBJECT_TYPE ObjectType,
|
||||||
IN BOOLEAN CaptureIfKernel,
|
IN POBJECT_CREATE_INFORMATION ObjectCreateInfo,
|
||||||
OUT POBJECT_CREATE_INFORMATION CapturedObjectAttributes OPTIONAL,
|
OUT PUNICODE_STRING ObjectName)
|
||||||
OUT PUNICODE_STRING ObjectName OPTIONAL)
|
|
||||||
{
|
{
|
||||||
OBJECT_ATTRIBUTES AttributesCopy;
|
|
||||||
NTSTATUS Status = STATUS_SUCCESS;
|
NTSTATUS Status = STATUS_SUCCESS;
|
||||||
|
PSECURITY_DESCRIPTOR SecurityDescriptor;
|
||||||
|
PSECURITY_QUALITY_OF_SERVICE SecurityQos;
|
||||||
|
PUNICODE_STRING LocalObjectName = NULL;
|
||||||
|
|
||||||
/* at least one output parameter must be != NULL! */
|
/* Zero out the Capture Data */
|
||||||
ASSERT(CapturedObjectAttributes != NULL || ObjectName != NULL);
|
DPRINT("ObpCaptureObjectAttributes\n");
|
||||||
|
RtlZeroMemory(ObjectCreateInfo, sizeof(OBJECT_CREATE_INFORMATION));
|
||||||
if (ObjectAttributes == NULL)
|
|
||||||
|
/* Check if we got Oba */
|
||||||
|
if (ObjectAttributes)
|
||||||
{
|
{
|
||||||
/* we're going to return STATUS_SUCCESS! */
|
if (AccessMode != KernelMode)
|
||||||
goto failbasiccleanup;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (AccessMode != KernelMode)
|
|
||||||
{
|
|
||||||
_SEH_TRY
|
|
||||||
{
|
{
|
||||||
ProbeForRead(ObjectAttributes,
|
DPRINT("Probing OBA\n");
|
||||||
sizeof(ObjectAttributes),
|
_SEH_TRY
|
||||||
sizeof(ULONG));
|
|
||||||
/* make a copy on the stack */
|
|
||||||
AttributesCopy = *ObjectAttributes;
|
|
||||||
}
|
|
||||||
_SEH_HANDLE
|
|
||||||
{
|
|
||||||
Status = _SEH_GetExceptionCode();
|
|
||||||
}
|
|
||||||
_SEH_END;
|
|
||||||
|
|
||||||
if(!NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
DPRINT1("ObpCaptureObjectAttributes failed to probe object attributes 0x%p\n", ObjectAttributes);
|
|
||||||
goto failbasiccleanup;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (!CaptureIfKernel)
|
|
||||||
{
|
|
||||||
if (ObjectAttributes->Length == sizeof(OBJECT_ATTRIBUTES))
|
|
||||||
{
|
|
||||||
if (ObjectName != NULL)
|
|
||||||
{
|
{
|
||||||
/* we don't have to capture any memory, the caller considers the passed data
|
/* FIXME: SMSS SENDS BULLSHIT. */
|
||||||
as valid */
|
#if 0
|
||||||
if (ObjectAttributes->ObjectName != NULL)
|
ProbeForRead(ObjectAttributes,
|
||||||
{
|
sizeof(ObjectAttributes),
|
||||||
*ObjectName = *ObjectAttributes->ObjectName;
|
sizeof(ULONG));
|
||||||
}
|
#endif
|
||||||
else
|
|
||||||
{
|
|
||||||
ObjectName->Length = ObjectName->MaximumLength = 0;
|
|
||||||
ObjectName->Buffer = NULL;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (CapturedObjectAttributes != NULL)
|
_SEH_HANDLE
|
||||||
{
|
{
|
||||||
CapturedObjectAttributes->RootDirectory = ObjectAttributes->RootDirectory;
|
Status = _SEH_GetExceptionCode();
|
||||||
CapturedObjectAttributes->Attributes = ObjectAttributes->Attributes;
|
|
||||||
CapturedObjectAttributes->SecurityDescriptor = ObjectAttributes->SecurityDescriptor;
|
|
||||||
CapturedObjectAttributes->SecurityDescriptorCharge = 0; /* FIXME */
|
|
||||||
CapturedObjectAttributes->ProbeMode = AccessMode;
|
|
||||||
}
|
}
|
||||||
|
_SEH_END;
|
||||||
return STATUS_SUCCESS;
|
|
||||||
}
|
}
|
||||||
else
|
|
||||||
|
/* Validate the Size */
|
||||||
|
DPRINT("Validating OBA\n");
|
||||||
|
if (ObjectAttributes->Length != sizeof(OBJECT_ATTRIBUTES))
|
||||||
{
|
{
|
||||||
Status = STATUS_INVALID_PARAMETER;
|
Status = STATUS_INVALID_PARAMETER;
|
||||||
goto failbasiccleanup;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
AttributesCopy = *ObjectAttributes;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* if Length isn't as expected, bail with an invalid parameter status code so
|
/* Fail if SEH or Size Validation failed */
|
||||||
the caller knows he passed garbage... */
|
if(!NT_SUCCESS(Status))
|
||||||
if (AttributesCopy.Length != sizeof(OBJECT_ATTRIBUTES))
|
|
||||||
{
|
|
||||||
Status = STATUS_INVALID_PARAMETER;
|
|
||||||
goto failbasiccleanup;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (CapturedObjectAttributes != NULL)
|
|
||||||
{
|
|
||||||
CapturedObjectAttributes->RootDirectory = AttributesCopy.RootDirectory;
|
|
||||||
CapturedObjectAttributes->Attributes = AttributesCopy.Attributes;
|
|
||||||
|
|
||||||
if (AttributesCopy.SecurityDescriptor != NULL)
|
|
||||||
{
|
{
|
||||||
Status = SeCaptureSecurityDescriptor(AttributesCopy.SecurityDescriptor,
|
DPRINT1("ObpCaptureObjectAttributes failed to probe object attributes\n");
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set some Create Info */
|
||||||
|
DPRINT("Creating OBCI\n");
|
||||||
|
ObjectCreateInfo->RootDirectory = ObjectAttributes->RootDirectory;
|
||||||
|
ObjectCreateInfo->Attributes = ObjectAttributes->Attributes;
|
||||||
|
LocalObjectName = ObjectAttributes->ObjectName;
|
||||||
|
SecurityDescriptor = ObjectAttributes->SecurityDescriptor;
|
||||||
|
SecurityQos = ObjectAttributes->SecurityQualityOfService;
|
||||||
|
|
||||||
|
/* Validate the SD */
|
||||||
|
if (SecurityDescriptor)
|
||||||
|
{
|
||||||
|
DPRINT("Probing SD: %x\n", SecurityDescriptor);
|
||||||
|
Status = SeCaptureSecurityDescriptor(SecurityDescriptor,
|
||||||
AccessMode,
|
AccessMode,
|
||||||
PoolType,
|
NonPagedPool,
|
||||||
TRUE,
|
TRUE,
|
||||||
&CapturedObjectAttributes->SecurityDescriptor);
|
&ObjectCreateInfo->SecurityDescriptor);
|
||||||
if (!NT_SUCCESS(Status))
|
if(!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
DPRINT1("Unable to capture the security descriptor!!!\n");
|
DPRINT1("Unable to capture the security descriptor!!!\n");
|
||||||
goto failbasiccleanup;
|
ObjectCreateInfo->SecurityDescriptor = NULL;
|
||||||
|
goto fail;
|
||||||
}
|
}
|
||||||
CapturedObjectAttributes->SecurityDescriptorCharge = 0; /* FIXME */
|
|
||||||
|
DPRINT("Probe done\n");
|
||||||
|
ObjectCreateInfo->SecurityDescriptorCharge = 0; /* FIXME */
|
||||||
|
ObjectCreateInfo->ProbeMode = AccessMode;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
|
/* Validate the QoS */
|
||||||
|
if (SecurityQos)
|
||||||
{
|
{
|
||||||
CapturedObjectAttributes->SecurityDescriptor = NULL;
|
|
||||||
CapturedObjectAttributes->SecurityDescriptorCharge = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ObjectName != NULL)
|
|
||||||
{
|
|
||||||
ObjectName->Buffer = NULL;
|
|
||||||
|
|
||||||
if (AttributesCopy.ObjectName != NULL)
|
|
||||||
{
|
|
||||||
UNICODE_STRING OriginalCopy = {0};
|
|
||||||
|
|
||||||
if (AccessMode != KernelMode)
|
if (AccessMode != KernelMode)
|
||||||
{
|
{
|
||||||
|
DPRINT("Probing QoS\n");
|
||||||
_SEH_TRY
|
_SEH_TRY
|
||||||
{
|
{
|
||||||
/* probe the ObjectName structure and make a local stack copy of it */
|
ProbeForRead(SecurityQos,
|
||||||
ProbeForRead(AttributesCopy.ObjectName,
|
sizeof(SECURITY_QUALITY_OF_SERVICE),
|
||||||
sizeof(UNICODE_STRING),
|
|
||||||
sizeof(ULONG));
|
sizeof(ULONG));
|
||||||
OriginalCopy = *AttributesCopy.ObjectName;
|
|
||||||
if (OriginalCopy.Length > 0)
|
|
||||||
{
|
|
||||||
ProbeForRead(OriginalCopy.Buffer,
|
|
||||||
OriginalCopy.Length,
|
|
||||||
sizeof(WCHAR));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
_SEH_HANDLE
|
_SEH_HANDLE
|
||||||
{
|
{
|
||||||
Status = _SEH_GetExceptionCode();
|
Status = _SEH_GetExceptionCode();
|
||||||
}
|
}
|
||||||
_SEH_END;
|
_SEH_END;
|
||||||
|
|
||||||
if (NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
ObjectName->Length = OriginalCopy.Length;
|
|
||||||
|
|
||||||
if(OriginalCopy.Length > 0)
|
|
||||||
{
|
|
||||||
ObjectName->MaximumLength = OriginalCopy.Length + sizeof(WCHAR);
|
|
||||||
ObjectName->Buffer = ExAllocatePool(PoolType,
|
|
||||||
ObjectName->MaximumLength);
|
|
||||||
if (ObjectName->Buffer != NULL)
|
|
||||||
{
|
|
||||||
_SEH_TRY
|
|
||||||
{
|
|
||||||
/* no need to probe OriginalCopy.Buffer again, we already did that
|
|
||||||
when capturing the UNICODE_STRING structure itself */
|
|
||||||
RtlCopyMemory(ObjectName->Buffer, OriginalCopy.Buffer, OriginalCopy.Length);
|
|
||||||
ObjectName->Buffer[OriginalCopy.Length / sizeof(WCHAR)] = L'\0';
|
|
||||||
}
|
|
||||||
_SEH_HANDLE
|
|
||||||
{
|
|
||||||
Status = _SEH_GetExceptionCode();
|
|
||||||
}
|
|
||||||
_SEH_END;
|
|
||||||
|
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
DPRINT1("ObpCaptureObjectAttributes failed to copy the unicode string!\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Status = STATUS_INSUFFICIENT_RESOURCES;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if(AttributesCopy.RootDirectory != NULL /* && OriginalCopy.Length == 0 */)
|
|
||||||
{
|
|
||||||
/* if the caller specified a root directory, there must be an object name! */
|
|
||||||
Status = STATUS_OBJECT_NAME_INVALID;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ObjectName->Length = ObjectName->MaximumLength = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#ifdef DBG
|
|
||||||
else
|
|
||||||
{
|
|
||||||
DPRINT1("ObpCaptureObjectAttributes failed to probe the object name UNICODE_STRING structure!\n");
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
else /* AccessMode == KernelMode */
|
|
||||||
|
if(!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
OriginalCopy = *AttributesCopy.ObjectName;
|
DPRINT1("Unable to capture QoS!!!\n");
|
||||||
ObjectName->Length = OriginalCopy.Length;
|
goto fail;
|
||||||
|
|
||||||
if (OriginalCopy.Length > 0)
|
|
||||||
{
|
|
||||||
ObjectName->MaximumLength = OriginalCopy.Length + sizeof(WCHAR);
|
|
||||||
ObjectName->Buffer = ExAllocatePool(PoolType,
|
|
||||||
ObjectName->MaximumLength);
|
|
||||||
if (ObjectName->Buffer != NULL)
|
|
||||||
{
|
|
||||||
RtlCopyMemory(ObjectName->Buffer, OriginalCopy.Buffer, OriginalCopy.Length);
|
|
||||||
ObjectName->Buffer[OriginalCopy.Length / sizeof(WCHAR)] = L'\0';
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Status = STATUS_INSUFFICIENT_RESOURCES;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (AttributesCopy.RootDirectory != NULL /* && OriginalCopy.Length == 0 */)
|
|
||||||
{
|
|
||||||
/* if the caller specified a root directory, there must be an object name! */
|
|
||||||
Status = STATUS_OBJECT_NAME_INVALID;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ObjectName->Length = ObjectName->MaximumLength = 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else
|
ObjectCreateInfo->SecurityQualityOfService = *SecurityQos;
|
||||||
{
|
ObjectCreateInfo->SecurityQos = &ObjectCreateInfo->SecurityQualityOfService;
|
||||||
ObjectName->Length = ObjectName->MaximumLength = 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CapturedObjectAttributes->ProbeMode = AccessMode;
|
/* Clear Local Object Name */
|
||||||
|
DPRINT("Clearing name\n");
|
||||||
if (!NT_SUCCESS(Status))
|
RtlZeroMemory(ObjectName, sizeof(UNICODE_STRING));
|
||||||
|
|
||||||
|
/* Now check if the Object Attributes had an Object Name */
|
||||||
|
if (LocalObjectName)
|
||||||
{
|
{
|
||||||
if (ObjectName != NULL && ObjectName->Buffer)
|
DPRINT("Name Buffer: %x\n", LocalObjectName->Buffer);
|
||||||
|
Status = ObpCaptureObjectName(ObjectName,
|
||||||
|
LocalObjectName,
|
||||||
|
AccessMode);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* He can't have specified a Root Directory */
|
||||||
|
if (ObjectCreateInfo->RootDirectory)
|
||||||
{
|
{
|
||||||
ExFreePool(ObjectName->Buffer);
|
DPRINT1("Invalid name\n");
|
||||||
}
|
Status = STATUS_OBJECT_NAME_INVALID;
|
||||||
if (CapturedObjectAttributes != NULL)
|
|
||||||
{
|
|
||||||
/* cleanup allocated resources */
|
|
||||||
SeReleaseSecurityDescriptor(CapturedObjectAttributes->SecurityDescriptor,
|
|
||||||
AccessMode,
|
|
||||||
TRUE);
|
|
||||||
}
|
|
||||||
|
|
||||||
failbasiccleanup:
|
|
||||||
if (ObjectName != NULL)
|
|
||||||
{
|
|
||||||
ObjectName->Length = ObjectName->MaximumLength = 0;
|
|
||||||
ObjectName->Buffer = NULL;
|
|
||||||
}
|
|
||||||
if (CapturedObjectAttributes != NULL)
|
|
||||||
{
|
|
||||||
RtlZeroMemory(CapturedObjectAttributes, sizeof(OBJECT_CREATE_INFORMATION));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fail:
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DPRINT1("Failed to capture, cleaning up\n");
|
||||||
|
ObpReleaseCapturedAttributes(ObjectCreateInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
DPRINT("Return to caller\n");
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
STDCALL
|
STDCALL
|
||||||
ObpReleaseCapturedAttributes(IN POBJECT_CREATE_INFORMATION CapturedObjectAttributes OPTIONAL,
|
ObpReleaseCapturedAttributes(IN POBJECT_CREATE_INFORMATION ObjectCreateInfo)
|
||||||
IN PUNICODE_STRING ObjectName OPTIONAL,
|
|
||||||
IN KPROCESSOR_MODE AccessMode,
|
|
||||||
IN BOOLEAN CaptureIfKernel)
|
|
||||||
{
|
{
|
||||||
/* WARNING - You need to pass the same parameters to this function as you passed
|
/* Release the SD, it's the only thing we allocated */
|
||||||
to ObpCaptureObjectAttributes() to avoid memory leaks */
|
if (ObjectCreateInfo->SecurityDescriptor)
|
||||||
if(AccessMode != KernelMode || CaptureIfKernel)
|
|
||||||
{
|
|
||||||
if(CapturedObjectAttributes != NULL &&
|
|
||||||
CapturedObjectAttributes->SecurityDescriptor != NULL)
|
|
||||||
{
|
{
|
||||||
ExFreePool(CapturedObjectAttributes->SecurityDescriptor);
|
SeReleaseSecurityDescriptor(ObjectCreateInfo->SecurityDescriptor,
|
||||||
|
ObjectCreateInfo->ProbeMode,
|
||||||
#ifdef DBG
|
TRUE);
|
||||||
RtlZeroMemory(CapturedObjectAttributes, sizeof(OBJECT_CREATE_INFORMATION));
|
ObjectCreateInfo->SecurityDescriptor = NULL;
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
if(ObjectName != NULL &&
|
|
||||||
ObjectName->Length > 0)
|
|
||||||
{
|
|
||||||
ExFreePool(ObjectName->Buffer);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -483,7 +348,7 @@ ObFindObject(POBJECT_CREATE_INFORMATION ObjectCreateInfo,
|
||||||
ObjectName->Buffer[0] != L'\\')
|
ObjectName->Buffer[0] != L'\\')
|
||||||
{
|
{
|
||||||
ObDereferenceObject (CurrentObject);
|
ObDereferenceObject (CurrentObject);
|
||||||
DPRINT1("failed: \"%wZ\"\n", ObjectName);
|
DPRINT1("failed\n");
|
||||||
return STATUS_UNSUCCESSFUL;
|
return STATUS_UNSUCCESSFUL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -930,9 +795,8 @@ ObCreateObject(IN KPROCESSOR_MODE ObjectAttributesAccessMode OPTIONAL,
|
||||||
/* Capture all the info */
|
/* Capture all the info */
|
||||||
DPRINT("Capturing Create Info\n");
|
DPRINT("Capturing Create Info\n");
|
||||||
Status = ObpCaptureObjectAttributes(ObjectAttributes,
|
Status = ObpCaptureObjectAttributes(ObjectAttributes,
|
||||||
ObjectAttributesAccessMode,
|
AccessMode,
|
||||||
NonPagedPool,
|
Type,
|
||||||
TRUE,
|
|
||||||
ObjectCreateInfo,
|
ObjectCreateInfo,
|
||||||
&ObjectName);
|
&ObjectName);
|
||||||
|
|
||||||
|
@ -958,10 +822,8 @@ ObCreateObject(IN KPROCESSOR_MODE ObjectAttributesAccessMode OPTIONAL,
|
||||||
|
|
||||||
/* Release the Capture Info, we don't need it */
|
/* Release the Capture Info, we don't need it */
|
||||||
DPRINT1("Allocation failed\n");
|
DPRINT1("Allocation failed\n");
|
||||||
ObpReleaseCapturedAttributes(ObjectCreateInfo,
|
ObpReleaseCapturedAttributes(ObjectCreateInfo);
|
||||||
&ObjectName,
|
if (ObjectName.Buffer) ExFreePool(ObjectName.Buffer);
|
||||||
ObjectAttributesAccessMode,
|
|
||||||
TRUE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* We failed, so release the Buffer */
|
/* We failed, so release the Buffer */
|
||||||
|
@ -1115,10 +977,7 @@ ObpDeleteObject(POBJECT_HEADER Header)
|
||||||
}
|
}
|
||||||
if (Header->ObjectCreateInfo)
|
if (Header->ObjectCreateInfo)
|
||||||
{
|
{
|
||||||
ObpReleaseCapturedAttributes(Header->ObjectCreateInfo,
|
ObpReleaseCapturedAttributes(Header->ObjectCreateInfo);
|
||||||
NULL,
|
|
||||||
Header->ObjectCreateInfo->ProbeMode,
|
|
||||||
FALSE);
|
|
||||||
ExFreePool(Header->ObjectCreateInfo);
|
ExFreePool(Header->ObjectCreateInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue