- Fix a large amount of bugs in ObpAllocateObjectAttributes & Name

svn path=/trunk/; revision=17227
This commit is contained in:
Alex Ionescu 2005-08-09 04:43:54 +00:00
parent 66c8e646dc
commit 56f8494362
3 changed files with 156 additions and 163 deletions

View file

@ -549,13 +549,15 @@ KeWaitForMultipleObjects(ULONG Count,
} }
/* Block the Thread */ /* Block the Thread */
DPRINT("Blocking the Thread: %d, %d, %d, %x\n", Alertable, WaitMode, WaitReason, KeGetCurrentThread()); DPRINT("Blocking the Thread: %d, %d, %d, %x\n", Alertable, WaitMode,
WaitReason, KeGetCurrentThread());
KiBlockThread(&Status, KiBlockThread(&Status,
Alertable, Alertable,
WaitMode, WaitMode,
(UCHAR)WaitReason); (UCHAR)WaitReason);
/* Check if we were executing an APC */ /* Check if we were executing an APC */
DPRINT("Thread is back\n");
if (Status != STATUS_KERNEL_APC) { if (Status != STATUS_KERNEL_APC) {
/* Return Status */ /* Return Status */
@ -568,7 +570,7 @@ KeWaitForMultipleObjects(ULONG Count,
} while (TRUE); } while (TRUE);
/* Release the Lock, we are done */ /* Release the Lock, we are done */
DPRINT("Returning from KeWaitForMultipleObjects(), %x. Status: %d\n", KeGetCurrentThread(), Status); DPRINT("Returning, %x. Status: %d\n", KeGetCurrentThread(), Status);
KeReleaseDispatcherDatabaseLock(CurrentThread->WaitIrql); KeReleaseDispatcherDatabaseLock(CurrentThread->WaitIrql);
return Status; return Status;
@ -577,7 +579,8 @@ DontWait:
KiAdjustQuantumThread(CurrentThread); KiAdjustQuantumThread(CurrentThread);
/* Release & Return */ /* Release & Return */
DPRINT("Returning from KeWaitForMultipleObjects(), %x. Status: %d\n. We did not wait.", KeGetCurrentThread(), Status); DPRINT("Returning, %x. Status: %d\n. We did not wait.",
KeGetCurrentThread(), Status);
KeReleaseDispatcherDatabaseLock(CurrentThread->WaitIrql); KeReleaseDispatcherDatabaseLock(CurrentThread->WaitIrql);
return Status; return Status;
} }

View file

@ -65,30 +65,26 @@ ObReferenceObjectByName(PUNICODE_STRING ObjectPath,
PVOID Object = NULL; PVOID Object = NULL;
UNICODE_STRING RemainingPath; UNICODE_STRING RemainingPath;
UNICODE_STRING ObjectName; UNICODE_STRING ObjectName;
OBJECT_ATTRIBUTES ObjectAttributes;
OBJECT_CREATE_INFORMATION ObjectCreateInfo; OBJECT_CREATE_INFORMATION ObjectCreateInfo;
NTSTATUS Status; NTSTATUS Status;
PAGED_CODE(); PAGED_CODE();
InitializeObjectAttributes(&ObjectAttributes, /* Capture the name */
ObjectPath, DPRINT("Capturing Name\n");
Attributes | OBJ_OPENIF, Status = ObpCaptureObjectName(&ObjectName, ObjectPath, AccessMode);
NULL,
NULL);
/* Capture all the info */
DPRINT("Capturing Create Info\n");
Status = ObpCaptureObjectAttributes(&ObjectAttributes,
AccessMode,
ObjectType,
&ObjectCreateInfo,
&ObjectName);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
DPRINT("ObpCaptureObjectAttributes() failed (Status %lx)\n", Status); DPRINT("ObpCaptureObjectName() failed (Status %lx)\n", Status);
return Status; return Status;
} }
/*
* Create a fake ObjectCreateInfo structure. Note that my upcoming
* ObFindObject refactoring will remove the need for this hack.
*/
ObjectCreateInfo.RootDirectory = NULL;
ObjectCreateInfo.Attributes = Attributes;
Status = ObFindObject(&ObjectCreateInfo, Status = ObFindObject(&ObjectCreateInfo,
&ObjectName, &ObjectName,
@ -96,7 +92,6 @@ ObReferenceObjectByName(PUNICODE_STRING ObjectPath,
&RemainingPath, &RemainingPath,
ObjectType); ObjectType);
ObpReleaseCapturedAttributes(&ObjectCreateInfo);
if (ObjectName.Buffer) ExFreePool(ObjectName.Buffer); if (ObjectName.Buffer) ExFreePool(ObjectName.Buffer);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))

View file

@ -17,6 +17,7 @@
#define UNICODE_PATH_SEP L'\\' #define UNICODE_PATH_SEP L'\\'
#define UNICODE_NO_PATH L"..." #define UNICODE_NO_PATH L"..."
#define OB_NAME_TAG TAG('O','b','N','m')
typedef struct _RETENTION_CHECK_PARAMS typedef struct _RETENTION_CHECK_PARAMS
{ {
@ -33,78 +34,85 @@ ObpCaptureObjectName(IN OUT PUNICODE_STRING CapturedName,
IN KPROCESSOR_MODE AccessMode) IN KPROCESSOR_MODE AccessMode)
{ {
NTSTATUS Status = STATUS_SUCCESS; NTSTATUS Status = STATUS_SUCCESS;
ULONG StringLength;
PWCHAR StringBuffer;
UNICODE_STRING LocalName = {}; /* <= GCC 4.0 + Optimizer */ UNICODE_STRING LocalName = {}; /* <= GCC 4.0 + Optimizer */
/* First Probe the String */ /* Initialize the Input String */
DPRINT("ObpCaptureObjectName: %wZ\n", ObjectName); RtlInitUnicodeString(CapturedName, NULL);
if (AccessMode != KernelMode)
/* Protect everything */
_SEH_TRY
{ {
DPRINT("Probing Struct\n"); /* First Probe the String */
_SEH_TRY DPRINT("ObpCaptureObjectName: %wZ\n", ObjectName);
if (AccessMode != KernelMode)
{ {
/* FIXME: Explorer or win32 broken I think */
#if 0
ProbeForRead(ObjectName, ProbeForRead(ObjectName,
sizeof(UNICODE_STRING), sizeof(UNICODE_STRING),
sizeof(USHORT)); sizeof(USHORT));
#endif LocalName = *ObjectName;
ProbeForRead(LocalName.Buffer,
LocalName.Length,
sizeof(WCHAR));
}
else
{
/* No probing needed */
LocalName = *ObjectName; LocalName = *ObjectName;
} }
_SEH_HANDLE
/* Make sure there really is a string */
DPRINT("Probing OK\n");
if ((StringLength = LocalName.Length))
{ {
Status = _SEH_GetExceptionCode(); /* Check that the size is a valid WCHAR multiple */
} if ((StringLength & (sizeof(WCHAR) - 1)) ||
_SEH_END; /* Check that the NULL-termination below will work */
(StringLength == (MAXUSHORT - sizeof(WCHAR) + 1)))
if (NT_SUCCESS(Status))
{
DPRINT("Probing OK\n");
_SEH_TRY
{ {
#if 0 /* PS: Please keep the checks above expanded for clarity */
DPRINT("Probing buffer\n"); DPRINT1("Invalid String Length\n");
ProbeForRead(LocalName.Buffer, Status = STATUS_OBJECT_NAME_INVALID;
LocalName.Length,
sizeof(USHORT));
#endif
} }
_SEH_HANDLE else
{ {
Status = _SEH_GetExceptionCode(); /* Allocate a non-paged buffer for this string */
DPRINT("Capturing String\n");
CapturedName->Length = StringLength;
CapturedName->MaximumLength = StringLength + sizeof(WCHAR);
if ((StringBuffer = ExAllocatePoolWithTag(NonPagedPool,
StringLength + sizeof(WCHAR),
OB_NAME_TAG)))
{
/* Copy the string and null-terminate it */
RtlMoveMemory(StringBuffer, LocalName.Buffer, StringLength);
StringBuffer[StringLength / sizeof(WCHAR)] = UNICODE_NULL;
CapturedName->Buffer = StringBuffer;
DPRINT("String Captured: %wZ\n", CapturedName);
}
else
{
/* Fail */
DPRINT1("Out of Memory!\n");
Status = STATUS_INSUFFICIENT_RESOURCES;
}
} }
_SEH_END;
}
/* Fail if anything up to here died */
if (!NT_SUCCESS(Status))
{
DPRINT1("Probing failed\n");
return Status;
} }
} }
else _SEH_EXCEPT(_SEH_ExSystemExceptionFilter)
{ {
LocalName = *ObjectName; Status = _SEH_GetExceptionCode();
}
/* Remember to free the buffer in case of failure */
/* Make sure there really is a string */ DPRINT1("Failed\n");
DPRINT("Probing OK\n"); if (StringBuffer) ExFreePool(StringBuffer);
if (LocalName.Length)
{
/* Allocate a non-paged buffer for this string */
DPRINT("Capturing String\n");
CapturedName->Length = LocalName.Length;
CapturedName->MaximumLength = LocalName.Length + sizeof(WCHAR);
CapturedName->Buffer = ExAllocatePoolWithTag(NonPagedPool,
CapturedName->MaximumLength,
TAG('O','b','N','m'));
/* Copy the string and null-terminate it */
RtlMoveMemory(CapturedName->Buffer, LocalName.Buffer, LocalName.Length);
CapturedName->Buffer[LocalName.Length / sizeof(WCHAR)] = UNICODE_NULL;
DPRINT("String Captured: %p, %wZ\n", CapturedName, CapturedName);
} }
_SEH_END;
/* Return */
DPRINT("Returning: %lx\n", Status);
return Status; return Status;
} }
@ -125,115 +133,102 @@ ObpCaptureObjectAttributes(IN POBJECT_ATTRIBUTES ObjectAttributes,
DPRINT("ObpCaptureObjectAttributes\n"); DPRINT("ObpCaptureObjectAttributes\n");
RtlZeroMemory(ObjectCreateInfo, sizeof(OBJECT_CREATE_INFORMATION)); RtlZeroMemory(ObjectCreateInfo, sizeof(OBJECT_CREATE_INFORMATION));
/* Check if we got Oba */ /* SEH everything here for protection */
if (ObjectAttributes) _SEH_TRY
{ {
if (AccessMode != KernelMode) /* Check if we got Oba */
{ if (ObjectAttributes)
DPRINT("Probing OBA\n");
_SEH_TRY
{
/* FIXME: SMSS SENDS BULLSHIT. */
#if 0
ProbeForRead(ObjectAttributes,
sizeof(ObjectAttributes),
sizeof(ULONG));
#endif
}
_SEH_HANDLE
{
Status = _SEH_GetExceptionCode();
}
_SEH_END;
}
/* Validate the Size */
DPRINT("Validating OBA\n");
if (ObjectAttributes->Length != sizeof(OBJECT_ATTRIBUTES))
{
Status = STATUS_INVALID_PARAMETER;
}
/* Fail if SEH or Size Validation failed */
if(!NT_SUCCESS(Status))
{
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,
NonPagedPool,
TRUE,
&ObjectCreateInfo->SecurityDescriptor);
if(!NT_SUCCESS(Status))
{
DPRINT1("Unable to capture the security descriptor!!!\n");
ObjectCreateInfo->SecurityDescriptor = NULL;
goto fail;
}
DPRINT("Probe done\n");
ObjectCreateInfo->SecurityDescriptorCharge = 0; /* FIXME */
ObjectCreateInfo->ProbeMode = AccessMode;
}
/* Validate the QoS */
if (SecurityQos)
{ {
if (AccessMode != KernelMode) if (AccessMode != KernelMode)
{ {
DPRINT("Probing QoS\n"); DPRINT("Probing OBA\n");
_SEH_TRY ProbeForRead(ObjectAttributes,
sizeof(OBJECT_ATTRIBUTES),
sizeof(ULONG));
}
/* Validate the Size and Attributes */
DPRINT("Validating OBA\n");
if ((ObjectAttributes->Length != sizeof(OBJECT_ATTRIBUTES)) ||
(ObjectAttributes->Attributes & ~OBJ_VALID_ATTRIBUTES))
{
Status = STATUS_INVALID_PARAMETER;
DPRINT1("Invalid Size: %lx or Attributes: %lx\n",
ObjectAttributes->Length, ObjectAttributes->Attributes);
goto Quickie;
}
/* 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,
NonPagedPool,
TRUE,
&ObjectCreateInfo->SecurityDescriptor);
if(!NT_SUCCESS(Status))
{ {
DPRINT1("Unable to capture the security descriptor!!!\n");
ObjectCreateInfo->SecurityDescriptor = NULL;
goto Quickie;
}
DPRINT("Probe done\n");
ObjectCreateInfo->SecurityDescriptorCharge = 2048; /* FIXME */
ObjectCreateInfo->ProbeMode = AccessMode;
}
/* Validate the QoS */
if (SecurityQos)
{
if (AccessMode != KernelMode)
{
DPRINT("Probing QoS\n");
ProbeForRead(SecurityQos, ProbeForRead(SecurityQos,
sizeof(SECURITY_QUALITY_OF_SERVICE), sizeof(SECURITY_QUALITY_OF_SERVICE),
sizeof(ULONG)); sizeof(ULONG));
} }
_SEH_HANDLE
{
Status = _SEH_GetExceptionCode();
}
_SEH_END;
}
if(!NT_SUCCESS(Status))
{
DPRINT1("Unable to capture QoS!!!\n");
goto fail;
}
ObjectCreateInfo->SecurityQualityOfService = *SecurityQos; /* Save Info */
ObjectCreateInfo->SecurityQos = &ObjectCreateInfo->SecurityQualityOfService; ObjectCreateInfo->SecurityQualityOfService = *SecurityQos;
ObjectCreateInfo->SecurityQos = &ObjectCreateInfo->SecurityQualityOfService;
}
}
else
{
LocalObjectName = NULL;
} }
} }
_SEH_EXCEPT(_SEH_ExSystemExceptionFilter)
/* Clear Local Object Name */ {
DPRINT("Clearing name\n"); Status = _SEH_GetExceptionCode();
RtlZeroMemory(ObjectName, sizeof(UNICODE_STRING)); DPRINT1("Failed\n");
goto Quickie;
}
_SEH_END;
/* Now check if the Object Attributes had an Object Name */ /* Now check if the Object Attributes had an Object Name */
if (LocalObjectName) if (LocalObjectName)
{ {
DPRINT("Name Buffer: %x\n", LocalObjectName->Buffer); DPRINT("Name Buffer: %wZ\n", LocalObjectName);
Status = ObpCaptureObjectName(ObjectName, Status = ObpCaptureObjectName(ObjectName,
LocalObjectName, LocalObjectName,
AccessMode); AccessMode);
} }
else else
{ {
/* Clear the string */
RtlInitUnicodeString(ObjectName, NULL);
/* He can't have specified a Root Directory */ /* He can't have specified a Root Directory */
if (ObjectCreateInfo->RootDirectory) if (ObjectCreateInfo->RootDirectory)
{ {
@ -242,14 +237,14 @@ ObpCaptureObjectAttributes(IN POBJECT_ATTRIBUTES ObjectAttributes,
} }
} }
fail: Quickie:
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
DPRINT1("Failed to capture, cleaning up\n"); DPRINT1("Failed to capture, cleaning up\n");
ObpReleaseCapturedAttributes(ObjectCreateInfo); ObpReleaseCapturedAttributes(ObjectCreateInfo);
} }
DPRINT("Return to caller\n"); DPRINT("Return to caller %x\n", Status);
return Status; return Status;
} }
@ -795,7 +790,7 @@ 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,
AccessMode, ObjectAttributesAccessMode,
Type, Type,
ObjectCreateInfo, ObjectCreateInfo,
&ObjectName); &ObjectName);