added helper functions ObpCaptureObjectAttributes() and
ObpReleaseObjectAttributes() to be used to safely capture
OBJECT_ATTRIBUTES structures
Modified: trunk/reactos/ntoskrnl/include/internal/ob.h
Modified: trunk/reactos/ntoskrnl/ob/object.c
_____
Modified: trunk/reactos/ntoskrnl/include/internal/ob.h
--- trunk/reactos/ntoskrnl/include/internal/ob.h 2005-01-21
02:39:59 UTC (rev 13178)
+++ trunk/reactos/ntoskrnl/include/internal/ob.h 2005-01-21
10:28:13 UTC (rev 13179)
@@ -315,5 +315,29 @@
VOID
ObpDereferenceCachedSecurityDescriptor(IN PSECURITY_DESCRIPTOR
SecurityDescriptor);
+/* Secure object information functions */
+typedef struct _CAPTURED_OBJECT_ATTRIBUTES
+{
+ HANDLE RootDirectory;
+ ULONG Attributes;
+ PSECURITY_DESCRIPTOR SecurityDescriptor;
+ /* PVOID SecurityQualityOfService; */
+} CAPTURED_OBJECT_ATTRIBUTES, *PCAPTURED_OBJECT_ATTRIBUTES;
+
+NTSTATUS
+ObpCaptureObjectAttributes(IN POBJECT_ATTRIBUTES ObjectAttributes
OPTIONAL,
+ IN POBJECT_TYPE ObjectType,
+ IN KPROCESSOR_MODE AccessMode,
+ IN BOOLEAN CaptureIfKernel,
+ OUT PCAPTURED_OBJECT_ATTRIBUTES
CapturedObjectAttributes OPTIONAL,
+ OUT PUNICODE_STRING ObjectName OPTIONAL);
+
+VOID
+ObpReleaseObjectAttributes(IN PCAPTURED_OBJECT_ATTRIBUTES
CapturedObjectAttributes OPTIONAL,
+ IN PUNICODE_STRING ObjectName OPTIONAL,
+ IN KPROCESSOR_MODE AccessMode,
+ IN BOOLEAN CaptureIfKernel);
+
+
#endif /* __INCLUDE_INTERNAL_OBJMGR_H */
_____
Modified: trunk/reactos/ntoskrnl/ob/object.c
--- trunk/reactos/ntoskrnl/ob/object.c 2005-01-21 02:39:59 UTC (rev
13178)
+++ trunk/reactos/ntoskrnl/ob/object.c 2005-01-21 10:28:13 UTC (rev
13179)
@@ -39,7 +39,257 @@
return(CONTAINING_RECORD((&(chdr->Type)),OBJECT_HEADER,Type));
}
+NTSTATUS
+ObpCaptureObjectAttributes(IN POBJECT_ATTRIBUTES ObjectAttributes
OPTIONAL,
+ IN POBJECT_TYPE ObjectType,
+ IN KPROCESSOR_MODE AccessMode,
+ IN BOOLEAN CaptureIfKernel,
+ OUT PCAPTURED_OBJECT_ATTRIBUTES
CapturedObjectAttributes OPTIONAL,
+ OUT PUNICODE_STRING ObjectName OPTIONAL)
+{
+ OBJECT_ATTRIBUTES AttributesCopy;
+ NTSTATUS Status = STATUS_SUCCESS;
+
+ /* at least one output parameter must be != NULL! */
+ ASSERT((ULONG_PTR)SecureObjectInformation ^ (ULONG_PTR)ObjectName !=
0);
+
+ if(ObjectAttributes == NULL)
+ {
+failbasiccleanup:
+ if(ObjectName != NULL)
+ {
+ RtlInitUnicodeString(ObjectName, NULL);
+ }
+ if(CapturedObjectAttributes != NULL)
+ {
+ RtlZeroMemory(CapturedObjectAttributes,
sizeof(CAPTURED_OBJECT_ATTRIBUTES));
+ }
+ return Status; /* STATUS_SUCCESS */
+ }
+
+ if(AccessMode != KernelMode)
+ {
+ _SEH_TRY
+ {
+ ProbeForRead(ObjectAttributes,
+ sizeof(ObjectAttributes),
+ sizeof(ULONG));
+ /* make a copy on the stack */
+ AttributesCopy = *ObjectAttributes;
+ }
+ _SEH_HANDLE
+ {
+ Status = _SEH_GetExceptionCode();
+ }
+ _SEH_END;
+
+ if(!NT_SUCCESS(Status))
+ {
+ return Status;
+ }
+ }
+ else if(AccessMode == KernelMode && !CaptureIfKernel)
+ {
+ if(AttributesCopy.Length != sizeof(OBJECT_ATTRIBUTES))
+ {
+ if(ObjectName != NULL)
+ {
+ *ObjectName = *ObjectAttributes->ObjectName;
+ }
+ if(CapturedObjectAttributes != NULL)
+ {
+ CapturedObjectAttributes->RootDirectory =
ObjectAttributes->RootDirectory;
+ CapturedObjectAttributes->Attributes =
ObjectAttributes->Attributes;
+ CapturedObjectAttributes->SecurityDescriptor =
ObjectAttributes->SecurityDescriptor;
+ }
+ }
+ else
+ {
+ Status = STATUS_INVALID_PARAMETER;
+ goto failbasiccleanup;
+ }
+ return STATUS_SUCCESS;
+ }
+ else
+ {
+ AttributesCopy = *ObjectAttributes;
+ }
+
+ /* if Length isn't as expected, bail with an invalid parameter status
code so
+ the caller knows he passed garbage... */
+ 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,
+ AccessMode,
+ PagedPool,
+ TRUE,
+
&CapturedObjectAttributes->SecurityDescriptor);
+ if(!NT_SUCCESS(Status))
+ {
+ DPRINT1("Unable to capture the security descriptor!!!\n");
+ goto failbasiccleanup;
+ }
+ }
+ else
+ {
+ CapturedObjectAttributes->SecurityDescriptor = NULL;
+ }
+ }
+
+ if(ObjectName != NULL)
+ {
+ if(AttributesCopy.ObjectName != NULL)
+ {
+ UNICODE_STRING OriginalCopy;
+
+ if(AccessMode != KernelMode)
+ {
+ _SEH_TRY
+ {
+ /* probe the ObjectName structure and make a local stack copy
of it */
+ ProbeForRead(AttributesCopy.ObjectName,
+ sizeof(UNICODE_STRING),
+ sizeof(ULONG));
+ OriginalCopy = *AttributesCopy.ObjectName;
+ if(OriginalCopy.Length > 0)
+ {
+ ProbeForRead(OriginalCopy.Buffer,
+ OriginalCopy.Length,
+ sizeof(ULONG));
+ }
+ }
+ _SEH_HANDLE
+ {
+ Status = _SEH_GetExceptionCode();
+ }
+ _SEH_END;
+
+ if(OriginalCopy.Length > 0)
+ {
+ ObjectName->MaximumLength = OriginalCopy.Length +
sizeof(WCHAR);
+ ObjectName->Buffer = ExAllocatePool(NonPagedPool,
+
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;
+ }
+ 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;
+ }
+
+ if(!NT_SUCCESS(Status))
+ {
+failallocatedcleanup:
+ if(ObjectName->Buffer)
+ {
+ ExFreePool(ObjectName->Buffer);
+ }
+ if(CapturedObjectAttributes != NULL)
+ {
+ /* cleanup allocated resources */
+
SeReleaseSecurityDescriptor(CapturedObjectAttributes->SecurityDescriptor
,
+ AccessMode,
+ TRUE);
+ }
+ goto failbasiccleanup;
+ }
+ }
+ else /* AccessMode == KernelMode */
+ {
+ OriginalCopy = *AttributesCopy.ObjectName;
+
+ if(OriginalCopy.Length > 0)
+ {
+ ObjectName->MaximumLength = OriginalCopy.Length +
sizeof(WCHAR);
+ ObjectName->Buffer = ExAllocatePool(NonPagedPool,
+
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;
+ }
+
+ if(!NT_SUCCESS(Status))
+ {
+ goto failallocatedcleanup;
+ }
+ }
+ }
+ else
+ {
+ RtlInitUnicodeString(ObjectName, NULL);
+ }
+ }
+
+ return Status;
+}
+
+VOID
+ObpReleaseObjectAttributes(IN PCAPTURED_OBJECT_ATTRIBUTES
CapturedObjectAttributes OPTIONAL,
+ 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
+ to ObpCaptureObjectAttributes() to avoid memory leaks */
+ if(AccessMode != KernelMode ||
+ (AccessMode == KernelMode && CaptureIfKernel))
+ {
+ if(CapturedObjectAttributes != NULL &&
+ CapturedObjectAttributes->SecurityDescriptor != NULL)
+ {
+ ExFreePool(CapturedObjectAttributes->SecurityDescriptor);
+ CapturedObjectAttributes->SecurityDescriptor = NULL;
+ }
+ if(ObjectName != NULL &&
+ ObjectName->Length > 0)
+ {
+ ExFreePool(ObjectName->Buffer);
+ }
+ }
+}
+
+
/**********************************************************************
* NAME PRIVATE
* ObFindObject@16
@@ -344,6 +594,27 @@
SECURITY_SUBJECT_CONTEXT SubjectContext;
ASSERT_IRQL(APC_LEVEL);
+
+ if(AccessMode == UserMode)
+ {
+ Status = STATUS_SUCCESS;
+ _SEH_TRY
+ {
+ ProbeForRead(ObjectAttributes,
+ sizeof(OBJECT_ATTRIBUTES),
+ sizeof(ULONG));
+ }
+ _SEH_HANDLE
+ {
+ Status = _SEH_GetExceptionCode();
+ }
+ _SEH_END;
+
+ if(!NT_SUCCESS(Status))
+ {
+ return Status;
+ }
+ }
DPRINT("ObCreateObject(Type %p ObjectAttributes %p, Object %p)\n",
Type, ObjectAttributes, Object);