Modified: trunk/reactos/ntoskrnl/include/internal/safe.h
Modified: trunk/reactos/ntoskrnl/io/create.c
Modified: trunk/reactos/ntoskrnl/io/mailslot.c
Modified: trunk/reactos/ntoskrnl/io/npipe.c
Modified: trunk/reactos/ntoskrnl/rtl/capture.c
--- trunk/reactos/ntoskrnl/include/internal/safe.h 2005-01-24 19:32:40 UTC (rev 13251)
+++ trunk/reactos/ntoskrnl/include/internal/safe.h 2005-01-24 19:42:54 UTC (rev 13252)
@@ -21,4 +21,28 @@
IN KPROCESSOR_MODE CurrentMode,
IN BOOLEAN CaptureIfKernel);
-#endif /* __NTOSKRNL_INCLUDE_INTERNAL_SAFE_Hb */
+NTSTATUS
+RtlCaptureSecurityDescriptor(OUT PSECURITY_DESCRIPTOR Dest,
+ IN KPROCESSOR_MODE PreviousMode,
+ IN POOL_TYPE PoolType,
+ IN BOOLEAN CaptureIfKernel,
+ IN PSECURITY_DESCRIPTOR UnsafeSrc);
+
+VOID
+RtlReleaseCapturedSecurityDescriptor(IN PSECURITY_DESCRIPTOR CapturedSecurityDescriptor,
+ IN KPROCESSOR_MODE CurrentMode,
+ IN BOOLEAN CaptureIfKernel);
+
+NTSTATUS
+RtlCaptureObjectAttributes(OUT POBJECT_ATTRIBUTES Dest,
+ IN KPROCESSOR_MODE CurrentMode,
+ IN POOL_TYPE PoolType,
+ IN BOOLEAN CaptureIfKernel,
+ IN POBJECT_ATTRIBUTES UnsafeSrc);
+
+VOID
+RtlReleaseCapturedObjectAttributes(IN POBJECT_ATTRIBUTES CapturedObjectAttributes,
+ IN KPROCESSOR_MODE CurrentMode,
+ IN BOOLEAN CaptureIfKernel);
+
+#endif /* __NTOSKRNL_INCLUDE_INTERNAL_SAFE_H */
--- trunk/reactos/ntoskrnl/io/create.c 2005-01-24 19:32:40 UTC (rev 13251)
+++ trunk/reactos/ntoskrnl/io/create.c 2005-01-24 19:42:54 UTC (rev 13252)
@@ -17,7 +17,7 @@
/* GLOBALS *******************************************************************/
-#define TAG_FILE_NAME TAG('F', 'N', 'A', 'M')
+#define TAG_IO_CREATE TAG('I', 'O', 'C', 'R')
/* FUNCTIONS *************************************************************/
@@ -357,7 +357,7 @@
PreviousMode = ExGetPreviousMode();
- Status = ObCreateObject(PreviousMode,
+ Status = ObCreateObject(KernelMode,
IoFileObjectType,
ObjectAttributes,
PreviousMode,
@@ -533,32 +533,132 @@
* @implemented
*/
NTSTATUS STDCALL
-NtCreateFile(PHANDLE FileHandle,
+NtCreateFile(PHANDLE FileHandleUnsafe,
ACCESS_MASK DesiredAccess,
- POBJECT_ATTRIBUTES ObjectAttributes,
- PIO_STATUS_BLOCK IoStatusBlock,
- PLARGE_INTEGER AllocateSize,
+ POBJECT_ATTRIBUTES ObjectAttributesUnsafe,
+ PIO_STATUS_BLOCK IoStatusBlockUnsafe,
+ PLARGE_INTEGER AllocateSizeUnsafe,
ULONG FileAttributes,
ULONG ShareAccess,
ULONG CreateDisposition,
ULONG CreateOptions,
- PVOID EaBuffer,
+ PVOID EaBufferUnsafe,
ULONG EaLength)
{
- return IoCreateFile(FileHandle,
- DesiredAccess,
- ObjectAttributes,
- IoStatusBlock,
- AllocateSize,
- FileAttributes,
- ShareAccess,
- CreateDisposition,
- CreateOptions,
- EaBuffer,
- EaLength,
- CreateFileTypeNone,
- NULL,
- 0);
+ KPROCESSOR_MODE PreviousMode;
+ NTSTATUS Status;
+ HANDLE FileHandle;
+ OBJECT_ATTRIBUTES ObjectAttributes;
+ IO_STATUS_BLOCK IoStatusBlock;
+ LARGE_INTEGER AllocateSize;
+ PVOID EaBuffer;
+
+ PreviousMode = ExGetPreviousMode();
+ if (KernelMode == PreviousMode)
+ {
+ return IoCreateFile(FileHandleUnsafe,
+ DesiredAccess,
+ ObjectAttributesUnsafe,
+ IoStatusBlockUnsafe,
+ AllocateSizeUnsafe,
+ FileAttributes,
+ ShareAccess,
+ CreateDisposition,
+ CreateOptions,
+ EaBufferUnsafe,
+ EaLength,
+ CreateFileTypeNone,
+ NULL,
+ 0);
+ }
+
+ Status = RtlCaptureObjectAttributes(&ObjectAttributes,
+ PreviousMode,
+ PagedPool,
+ FALSE,
+ ObjectAttributesUnsafe);
+ if (! NT_SUCCESS(Status))
+ {
+ return Status;
+ }
+
+ if (0 != EaLength)
+ {
+ EaBuffer = ExAllocatePoolWithTag(PagedPool, EaLength, TAG_IO_CREATE);
+ if (NULL == EaBuffer)
+ {
+ RtlReleaseCapturedObjectAttributes(&ObjectAttributes,
+ PreviousMode,
+ FALSE);
+ return STATUS_NO_MEMORY;
+ }
+ }
+
+ _SEH_TRY
+ {
+ if (NULL != AllocateSizeUnsafe)
+ {
+ ProbeForRead(AllocateSizeUnsafe,
+ sizeof(LARGE_INTEGER),
+ sizeof(ULONG));
+ AllocateSize = *AllocateSizeUnsafe;
+ }
+ if (0 != EaLength)
+ {
+ ProbeForRead(EaBufferUnsafe,
+ EaLength,
+ sizeof(UCHAR));
+ RtlCopyMemory(EaBuffer, EaBufferUnsafe, EaLength);
+ }
+ }
+ _SEH_HANDLE
+ {
+ Status = _SEH_GetExceptionCode();
+ }
+ _SEH_END;
+
+ if (! NT_SUCCESS(Status))
+ {
+ return Status;
+ }
+
+ Status = IoCreateFile(&FileHandle,
+ DesiredAccess,
+ &ObjectAttributes,
+ &IoStatusBlock,
+ (NULL == AllocateSizeUnsafe ? NULL : &AllocateSize),
+ FileAttributes,
+ ShareAccess,
+ CreateDisposition,
+ CreateOptions,
+ (0 == EaLength ? NULL : EaBuffer),
+ EaLength,
+ CreateFileTypeNone,
+ NULL,
+ 0);
+ if (! NT_SUCCESS(Status))
+ {
+ return Status;
+ }
+
+ _SEH_TRY
+ {
+ ProbeForWrite(FileHandleUnsafe,
+ sizeof(HANDLE),
+ sizeof(ULONG));
+ *FileHandleUnsafe = FileHandle;
+ ProbeForWrite(IoStatusBlockUnsafe,
+ sizeof(IO_STATUS_BLOCK),
+ sizeof(ULONG));
+ *IoStatusBlockUnsafe = IoStatusBlock;
+ }
+ _SEH_HANDLE
+ {
+ Status = _SEH_GetExceptionCode();
+ }
+ _SEH_END;
+
+ return Status;
}
@@ -598,27 +698,90 @@
* @implemented
*/
NTSTATUS STDCALL
-NtOpenFile(PHANDLE FileHandle,
+NtOpenFile(PHANDLE FileHandleUnsafe,
ACCESS_MASK DesiredAccess,
- POBJECT_ATTRIBUTES ObjectAttributes,
- PIO_STATUS_BLOCK IoStatusBlock,
+ POBJECT_ATTRIBUTES ObjectAttributesUnsafe,
+ PIO_STATUS_BLOCK IoStatusBlockUnsafe,
ULONG ShareAccess,
ULONG OpenOptions)
{
- return IoCreateFile(FileHandle,
- DesiredAccess,
- ObjectAttributes,
- IoStatusBlock,
- NULL,
- 0,
- ShareAccess,
- FILE_OPEN,
- OpenOptions,
- NULL,
- 0,
- CreateFileTypeNone,
- NULL,
- 0);
+ KPROCESSOR_MODE PreviousMode;
+ NTSTATUS Status;
+ HANDLE FileHandle;
+ OBJECT_ATTRIBUTES ObjectAttributes;
+ IO_STATUS_BLOCK IoStatusBlock;
+
+ PreviousMode = ExGetPreviousMode();
+ if (KernelMode == PreviousMode)
+ {
+ return IoCreateFile(FileHandleUnsafe,
+ DesiredAccess,
+ ObjectAttributesUnsafe,
+ IoStatusBlockUnsafe,
+ NULL,
+ 0,
+ ShareAccess,
+ FILE_OPEN,
+ OpenOptions,
+ NULL,
+ 0,
+ CreateFileTypeNone,
+ NULL,
+ 0);
+ }
+
+ Status = RtlCaptureObjectAttributes(&ObjectAttributes,
+ PreviousMode,
+ PagedPool,
+ FALSE,
+ ObjectAttributesUnsafe);
+ if (! NT_SUCCESS(Status))
+ {
+ return Status;
+ }
+
+ if (! NT_SUCCESS(Status))
+ {
+ return Status;
+ }
+
+ Status = IoCreateFile(&FileHandle,
+ DesiredAccess,
+ &ObjectAttributes,
+ &IoStatusBlock,
+ NULL,
+ 0,
+ ShareAccess,
+ FILE_OPEN,
+ OpenOptions,
+ NULL,
+ 0,
+ CreateFileTypeNone,
+ NULL,
+ 0);
+ if (! NT_SUCCESS(Status))
+ {
+ return Status;
+ }
+
+ _SEH_TRY
+ {
+ ProbeForWrite(FileHandleUnsafe,
+ sizeof(HANDLE),
+ sizeof(ULONG));
+ *FileHandleUnsafe = FileHandle;
+ ProbeForWrite(IoStatusBlockUnsafe,
+ sizeof(IO_STATUS_BLOCK),
+ sizeof(ULONG));
+ *IoStatusBlockUnsafe = IoStatusBlock;
+ }
+ _SEH_HANDLE
+ {
+ Status = _SEH_GetExceptionCode();
+ }
+ _SEH_END;
+
+ return Status;
}
/* EOF */
--- trunk/reactos/ntoskrnl/io/mailslot.c 2005-01-24 19:32:40 UTC (rev 13251)
+++ trunk/reactos/ntoskrnl/io/mailslot.c 2005-01-24 19:42:54 UTC (rev 13252)
@@ -18,16 +18,21 @@
/* FUNCTIONS *****************************************************************/
NTSTATUS STDCALL
-NtCreateMailslotFile(OUT PHANDLE FileHandle,
+NtCreateMailslotFile(OUT PHANDLE FileHandleUnsafe,
IN ACCESS_MASK DesiredAccess,
- IN POBJECT_ATTRIBUTES ObjectAttributes,
- OUT PIO_STATUS_BLOCK IoStatusBlock,
+ IN POBJECT_ATTRIBUTES ObjectAttributesUnsafe,
+ OUT PIO_STATUS_BLOCK IoStatusBlockUnsafe,
IN ULONG CreateOptions,
IN ULONG MailslotQuota,
IN ULONG MaxMessageSize,
- IN PLARGE_INTEGER TimeOut)
+ IN PLARGE_INTEGER TimeOutUnsafe)
{
MAILSLOT_CREATE_PARAMETERS Buffer;
+ KPROCESSOR_MODE PreviousMode;
+ NTSTATUS Status;
+ HANDLE FileHandle;
+ OBJECT_ATTRIBUTES ObjectAttributes;
+ IO_STATUS_BLOCK IoStatusBlock;
DPRINT("NtCreateMailslotFile(FileHandle %x, DesiredAccess %x, "
"ObjectAttributes %x ObjectAttributes->ObjectName->Buffer %S)\n",
@@ -36,32 +41,103 @@
ASSERT_IRQL(PASSIVE_LEVEL);
- if (TimeOut != NULL)
+ if (TimeOutUnsafe != NULL)
{
- Buffer.ReadTimeout.QuadPart = TimeOut->QuadPart;
- Buffer.TimeoutSpecified = TRUE;
+ if (UserMode == PreviousMode)
+ {
+ Status = STATUS_SUCCESS;
+ _SEH_TRY
+ {
+ ProbeForRead(TimeOutUnsafe,
+ sizeof(LARGE_INTEGER),
+ sizeof(LARGE_INTEGER));
+ Buffer.ReadTimeout.QuadPart = TimeOutUnsafe->QuadPart;
+ }
+ _SEH_HANDLE
+ {
+ Status = _SEH_GetExceptionCode();
+ }
+ _SEH_END;
+ }
+ else
+ {
+ Buffer.ReadTimeout.QuadPart = TimeOutUnsafe->QuadPart;
+ }
+ Buffer.TimeoutSpecified = TRUE;
}
else
{
- Buffer.TimeoutSpecified = FALSE;
+ Buffer.TimeoutSpecified = FALSE;
}
Buffer.MailslotQuota = MailslotQuota;
Buffer.MaximumMessageSize = MaxMessageSize;
- return IoCreateFile(FileHandle,
- DesiredAccess,
- ObjectAttributes,
- IoStatusBlock,
- NULL,
- FILE_ATTRIBUTE_NORMAL,
- FILE_SHARE_READ | FILE_SHARE_WRITE,
- FILE_CREATE,
- CreateOptions,
- NULL,
- 0,
- CreateFileTypeMailslot,
- (PVOID)&Buffer,
- 0);
+ PreviousMode = ExGetPreviousMode();
+ if (KernelMode == PreviousMode)
+ {
+ return IoCreateFile(FileHandleUnsafe,
+ DesiredAccess,
+ ObjectAttributesUnsafe,
+ IoStatusBlockUnsafe,
+ NULL,
+ FILE_ATTRIBUTE_NORMAL,
+ FILE_SHARE_READ | FILE_SHARE_WRITE,
+ FILE_CREATE,
+ CreateOptions,
+ NULL,
+ 0,
+ CreateFileTypeMailslot,
+ (PVOID)&Buffer,
+ 0);
+ }
+
+ Status = RtlCaptureObjectAttributes(&ObjectAttributes,
+ PreviousMode,
+ PagedPool,
+ FALSE,
+ ObjectAttributesUnsafe);
+ if (! NT_SUCCESS(Status))
+ {
+ return Status;
+ }
+
+ Status = IoCreateFile(&FileHandle,
+ DesiredAccess,
+ &ObjectAttributes,
+ &IoStatusBlock,
+ NULL,
+ FILE_ATTRIBUTE_NORMAL,
+ FILE_SHARE_READ | FILE_SHARE_WRITE,
+ FILE_CREATE,
+ CreateOptions,
+ NULL,
+ 0,
+ CreateFileTypeMailslot,
+ (PVOID)&Buffer,
+ 0);
+ if (! NT_SUCCESS(Status))
+ {
+ return Status;
+ }
+
+ _SEH_TRY
+ {
+ ProbeForWrite(FileHandleUnsafe,
+ sizeof(HANDLE),
+ sizeof(ULONG));
+ *FileHandleUnsafe = FileHandle;
+ ProbeForWrite(IoStatusBlockUnsafe,
+ sizeof(IO_STATUS_BLOCK),
+ sizeof(ULONG));
+ *IoStatusBlockUnsafe = IoStatusBlock;
+ }
+ _SEH_HANDLE
+ {
+ Status = _SEH_GetExceptionCode();
+ }
+ _SEH_END;
+
+ return Status;
}
/* EOF */
--- trunk/reactos/ntoskrnl/io/npipe.c 2005-01-24 19:32:40 UTC (rev 13251)
+++ trunk/reactos/ntoskrnl/io/npipe.c 2005-01-24 19:42:54 UTC (rev 13252)
@@ -17,10 +17,10 @@
/* FUNCTIONS *****************************************************************/
NTSTATUS STDCALL
-NtCreateNamedPipeFile(PHANDLE FileHandle,
+NtCreateNamedPipeFile(PHANDLE FileHandleUnsafe,
ACCESS_MASK DesiredAccess,
- POBJECT_ATTRIBUTES ObjectAttributes,
- PIO_STATUS_BLOCK IoStatusBlock,
+ POBJECT_ATTRIBUTES ObjectAttributesUnsafe,
+ PIO_STATUS_BLOCK IoStatusBlockUnsafe,
ULONG ShareAccess,
ULONG CreateDisposition,
ULONG CreateOptions,
@@ -30,9 +30,14 @@
ULONG MaximumInstances,
ULONG InboundQuota,
ULONG OutboundQuota,
- PLARGE_INTEGER DefaultTimeout)
+ PLARGE_INTEGER DefaultTimeoutUnsafe)
{
NAMED_PIPE_CREATE_PARAMETERS Buffer;
+ KPROCESSOR_MODE PreviousMode;
+ NTSTATUS Status;
+ HANDLE FileHandle;
+ OBJECT_ATTRIBUTES ObjectAttributes;
+ IO_STATUS_BLOCK IoStatusBlock;
DPRINT("NtCreateNamedPipeFile(FileHandle %x, DesiredAccess %x, "
"ObjectAttributes %x ObjectAttributes->ObjectName->Buffer %S)\n",
@@ -41,9 +46,28 @@
ASSERT_IRQL(PASSIVE_LEVEL);
- if (DefaultTimeout != NULL)
+ if (DefaultTimeoutUnsafe != NULL)
{
- Buffer.DefaultTimeout.QuadPart = DefaultTimeout->QuadPart;
+ if (UserMode == PreviousMode)
+ {
+ Status = STATUS_SUCCESS;
+ _SEH_TRY
+ {
+ ProbeForRead(DefaultTimeoutUnsafe,
+ sizeof(LARGE_INTEGER),
+ sizeof(LARGE_INTEGER));
+ Buffer.DefaultTimeout.QuadPart = DefaultTimeoutUnsafe->QuadPart;
+ }
+ _SEH_HANDLE
+ {
+ Status = _SEH_GetExceptionCode();
+ }
+ _SEH_END;
+ }
+ else
+ {
+ Buffer.DefaultTimeout.QuadPart = DefaultTimeoutUnsafe->QuadPart;
+ }
Buffer.TimeoutSpecified = TRUE;
}
else
@@ -57,20 +81,72 @@
Buffer.InboundQuota = InboundQuota;
Buffer.OutboundQuota = OutboundQuota;
- return IoCreateFile(FileHandle,
- DesiredAccess,
- ObjectAttributes,
- IoStatusBlock,
- NULL,
- FILE_ATTRIBUTE_NORMAL,
- ShareAccess,
- CreateDisposition,
- CreateOptions,
- NULL,
- 0,
- CreateFileTypeNamedPipe,
- (PVOID)&Buffer,
- 0);
+ PreviousMode = ExGetPreviousMode();
+ if (KernelMode == PreviousMode)
+ {
+ return IoCreateFile(FileHandleUnsafe,
+ DesiredAccess,
+ ObjectAttributesUnsafe,
+ IoStatusBlockUnsafe,
+ NULL,
+ FILE_ATTRIBUTE_NORMAL,
+ ShareAccess,
+ CreateDisposition,
+ CreateOptions,
+ NULL,
+ 0,
+ CreateFileTypeNamedPipe,
+ (PVOID)&Buffer,
+ 0);
+ }
+
+ Status = RtlCaptureObjectAttributes(&ObjectAttributes,
+ PreviousMode,
+ PagedPool,
+ FALSE,
+ ObjectAttributesUnsafe);
+ if (! NT_SUCCESS(Status))
+ {
+ return Status;
+ }
+
+ Status = IoCreateFile(&FileHandle,
+ DesiredAccess,
+ &ObjectAttributes,
+ &IoStatusBlock,
+ NULL,
+ FILE_ATTRIBUTE_NORMAL,
+ ShareAccess,
+ CreateDisposition,
+ CreateOptions,
+ NULL,
+ 0,
+ CreateFileTypeNamedPipe,
+ (PVOID)&Buffer,
+ 0);
+ if (! NT_SUCCESS(Status))
+ {
+ return Status;
+ }
+
+ _SEH_TRY
+ {
+ ProbeForWrite(FileHandleUnsafe,
+ sizeof(HANDLE),
+ sizeof(ULONG));
+ *FileHandleUnsafe = FileHandle;
+ ProbeForWrite(IoStatusBlockUnsafe,
+ sizeof(IO_STATUS_BLOCK),
+ sizeof(ULONG));
+ *IoStatusBlockUnsafe = IoStatusBlock;
+ }
+ _SEH_HANDLE
+ {
+ Status = _SEH_GetExceptionCode();
+ }
+ _SEH_END;
+
+ return Status;
}
/* EOF */
--- trunk/reactos/ntoskrnl/rtl/capture.c 2005-01-24 19:32:40 UTC (rev 13251)
+++ trunk/reactos/ntoskrnl/rtl/capture.c 2005-01-24 19:42:54 UTC (rev 13252)
@@ -32,6 +32,8 @@
#define NDEBUG
#include <internal/debug.h>
+#define TAG_CAPT TAG('C', 'A', 'P', 'T')
+
/* FUNCTIONS *****************************************************************/
NTSTATUS
@@ -95,7 +97,7 @@
if(Src.Length > 0)
{
Dest->MaximumLength = Src.Length + sizeof(WCHAR);
- Dest->Buffer = ExAllocatePool(PoolType, Dest->MaximumLength);
+ Dest->Buffer = ExAllocatePoolWithTag(PoolType, Dest->MaximumLength, TAG_CAPT);
if (Dest->Buffer == NULL)
{
Dest->Length = Dest->MaximumLength = 0;
@@ -164,7 +166,7 @@
*/
Dest->Length = Src->Length;
Dest->MaximumLength = Src->MaximumLength;
- Dest->Buffer = ExAllocatePool(NonPagedPool, Dest->MaximumLength);
+ Dest->Buffer = ExAllocatePoolWithTag(NonPagedPool, Dest->MaximumLength, TAG_CAPT);
if (Dest->Buffer == NULL)
{
return(Status);
@@ -183,6 +185,478 @@
return(STATUS_SUCCESS);
}
+static NTSTATUS
+CaptureSID(OUT PSID *Dest,
+ IN KPROCESSOR_MODE PreviousMode,
+ IN POOL_TYPE PoolType,
+ IN PSID UnsafeSrc)
+{
+ SID Src;
+ ULONG Length;
+ NTSTATUS Status = STATUS_SUCCESS;
+
+ ASSERT(Dest != NULL);
+
+ if(UserMode == PreviousMode)
+ {
+ _SEH_TRY
+ {
+ ProbeForRead(UnsafeSrc,
+ sizeof(SID),
+ sizeof(ULONG));
+ RtlCopyMemory(&Src, UnsafeSrc, sizeof(SID));
+ }
+ _SEH_HANDLE
+ {
+ Status = _SEH_GetExceptionCode();
+ }
+ _SEH_END;
+
+ if(!NT_SUCCESS(Status))
+ {
+ return Status;
+ }
+ }
+ else
+ {
+ /* capture even though it is considered to be valid */
+ RtlCopyMemory(&Src, UnsafeSrc, sizeof(SID));
+ }
+
+ if(SID_REVISION != Src.Revision)
+ {
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ Length = RtlLengthSid(&Src);
+ *Dest = ExAllocatePoolWithTag(PoolType, Length, TAG_CAPT);
+ if(NULL == *Dest)
+ {
+ return STATUS_NO_MEMORY;
+ }
+
+ if(UserMode == PreviousMode)
+ {
+ _SEH_TRY
+ {
+ ProbeForRead(UnsafeSrc,
+ Length,
+ sizeof(ULONG));
+ RtlCopyMemory(*Dest, UnsafeSrc, Length);
+ }
+ _SEH_HANDLE
+ {
+ Status = _SEH_GetExceptionCode();
+ }
+ _SEH_END;
+
+ if(!NT_SUCCESS(Status))
+ {
+ return Status;
+ }
+ }
+ else
+ {
+ RtlCopyMemory(*Dest, UnsafeSrc, Length);
+ }
+
+ return Status;
+}
+
+static NTSTATUS
+CaptureACL(OUT PACL *Dest,
+ IN KPROCESSOR_MODE PreviousMode,
+ IN POOL_TYPE PoolType,
+ IN PACL UnsafeSrc)
+{
+ ACL Src;
+ ULONG Length;
+ NTSTATUS Status = STATUS_SUCCESS;
+
+ ASSERT(Dest != NULL);
+
+ if(UserMode == PreviousMode)
+ {
+ _SEH_TRY
+ {
+ ProbeForRead(UnsafeSrc,
+ sizeof(ACL),
+ sizeof(ULONG));
+ RtlCopyMemory(&Src, UnsafeSrc, sizeof(ACL));
+ }
+ _SEH_HANDLE
+ {
+ Status = _SEH_GetExceptionCode();
+ }
+ _SEH_END;
+
+ if(!NT_SUCCESS(Status))
+ {
+ return Status;
+ }
+ }
+ else
+ {
+ /* capture even though it is considered to be valid */
+ RtlCopyMemory(&Src, UnsafeSrc, sizeof(ACL));
+ }
+
+ if(Src.AclRevision < MIN_ACL_REVISION || MAX_ACL_REVISION < Src.AclRevision)
+ {
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ Length = Src.AclSize;
+ *Dest = ExAllocatePoolWithTag(PoolType, Length, TAG_CAPT);
+ if(NULL == *Dest)
+ {
+ return STATUS_NO_MEMORY;
+ }
+
+ if(UserMode == PreviousMode)
+ {
+ _SEH_TRY
+ {
+ ProbeForRead(UnsafeSrc,
+ Length,
+ sizeof(ULONG));
+ RtlCopyMemory(*Dest, UnsafeSrc, Length);
+ }
+ _SEH_HANDLE
+ {
+ Status = _SEH_GetExceptionCode();
+ }
+ _SEH_END;
+
+ if(!NT_SUCCESS(Status))
+ {
+ return Status;
+ }
+ }
+ else
+ {
+ RtlCopyMemory(*Dest, UnsafeSrc, Length);
+ }
+
+ return Status;
+}
+
+NTSTATUS
+RtlCaptureSecurityDescriptor(OUT PSECURITY_DESCRIPTOR Dest,
+ IN KPROCESSOR_MODE PreviousMode,
+ IN POOL_TYPE PoolType,
+ IN BOOLEAN CaptureIfKernel,
+ IN PSECURITY_DESCRIPTOR UnsafeSrc)
+{
+ SECURITY_DESCRIPTOR Src;
+ NTSTATUS Status = STATUS_SUCCESS;
+
+ ASSERT(Dest != NULL);
+
+ /*
+ * Copy the object attributes to kernel space.
+ */
+
+ if(PreviousMode == UserMode)
+ {
+ _SEH_TRY
+ {
+ ProbeForRead(UnsafeSrc,
+ sizeof(SECURITY_DESCRIPTOR),
+ sizeof(ULONG));
+ Src = *UnsafeSrc;
+ }
+ _SEH_HANDLE
+ {
+ Status = _SEH_GetExceptionCode();
+ }
+ _SEH_END;
+
+ if(!NT_SUCCESS(Status))
+ {
+ return Status;
+ }
+ }
+ else if(!CaptureIfKernel)
+ {
+ /* just copy the structure, the pointers are considered valid */
+ *Dest = *UnsafeSrc;
+ return STATUS_SUCCESS;
+ }
+ else
+ {
+ /* capture the object attributes even though it is considered to be valid */
+ Src = *UnsafeSrc;
+ }
+
+ if(SECURITY_DESCRIPTOR_REVISION1 != Src.Revision)
+ {
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ Dest->Revision = Src.Revision;
+ Dest->Sbz1 = Src.Sbz1;
+ Dest->Control = Src.Control;
+ Status = CaptureSID(&Dest->Owner, PreviousMode, PoolType, Src.Owner);
+ if(!NT_SUCCESS(Status))
+ {
+ return Status;
+ }
+ Status = CaptureSID(&Dest->Group, PreviousMode, PoolType, Src.Group);
+ if(!NT_SUCCESS(Status))
+ {
+ if(NULL != Dest->Owner)
+ {
+ ExFreePool(Dest->Owner);
+ }
+ return Status;
+ }
+ Status = CaptureACL(&Dest->Sacl, PreviousMode, PoolType, Src.Sacl);
+ if(!NT_SUCCESS(Status))
+ {
+ if(NULL != Dest->Group)
+ {
+ ExFreePool(Dest->Group);
+ }
+ if(NULL != Dest->Owner)
+ {
+ ExFreePool(Dest->Owner);
+ }
+ return Status;
+ }
+ Status = CaptureACL(&Dest->Dacl, PreviousMode, PoolType, Src.Dacl);
+ if(!NT_SUCCESS(Status))
+ {
+ if(NULL != Dest->Sacl)
+ {
+ ExFreePool(Dest->Sacl);
+ }
+ if(NULL != Dest->Group)
+ {
+ ExFreePool(Dest->Group);
+ }
+ if(NULL != Dest->Owner)
+ {
+ ExFreePool(Dest->Owner);
+ }
+ return Status;
+ }
+
+ return Status;
+}
+
+VOID
+RtlReleaseCapturedSecurityDescriptor(IN PSECURITY_DESCRIPTOR CapturedSecurityDescriptor,
+ IN KPROCESSOR_MODE PreviousMode,
+ IN BOOLEAN CaptureIfKernel)
+{
+ ASSERT(SECURITY_DESCRIPTOR_REVISION1 == CapturedSecurityDescriptor->Revision);
+
+ if(PreviousMode == KernelMode && !CaptureIfKernel)
+ {
+ return;
+ }
+
+ if(NULL != CapturedSecurityDescriptor->Dacl)
+ {
+ ExFreePool(CapturedSecurityDescriptor->Dacl);
+ }
+ if(NULL != CapturedSecurityDescriptor->Sacl)
+ {
+ ExFreePool(CapturedSecurityDescriptor->Sacl);
+ }
+ if(NULL != CapturedSecurityDescriptor->Group)
+ {
+ ExFreePool(CapturedSecurityDescriptor->Group);
+ }
+ if(NULL != CapturedSecurityDescriptor->Owner)
+ {
+ ExFreePool(CapturedSecurityDescriptor->Owner);
+ }
+}
+
+NTSTATUS
+RtlCaptureObjectAttributes(OUT POBJECT_ATTRIBUTES Dest,
+ IN KPROCESSOR_MODE PreviousMode,
+ IN POOL_TYPE PoolType,
+ IN BOOLEAN CaptureIfKernel,
+ IN POBJECT_ATTRIBUTES UnsafeSrc)
+{
+ OBJECT_ATTRIBUTES Src;
+ NTSTATUS Status = STATUS_SUCCESS;
+
+ ASSERT(Dest != NULL);
+
+ /*
+ * Copy the object attributes to kernel space.
+ */
+
+ if(PreviousMode == UserMode)
+ {
+ _SEH_TRY
+ {
+ ProbeForRead(UnsafeSrc,
+ sizeof(OBJECT_ATTRIBUTES),
+ sizeof(ULONG));
+ Src = *UnsafeSrc;
+ }
+ _SEH_HANDLE
+ {
+ Status = _SEH_GetExceptionCode();
+ }
+ _SEH_END;
+
+ if(!NT_SUCCESS(Status))
+ {
+ return Status;
+ }
+ }
+ else if(!CaptureIfKernel)
+ {
+ /* just copy the structure, the pointers are considered valid */
+ *Dest = *UnsafeSrc;
+ return STATUS_SUCCESS;
+ }
+ else
+ {
+ /* capture the object attributes even though it is considered to be valid */
+ Src = *UnsafeSrc;
+ }
+
+ if(Src.Length < sizeof(OBJECT_ATTRIBUTES) || NULL == Src.ObjectName)
+ {
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ Dest->Length = sizeof(OBJECT_ATTRIBUTES);
+ Dest->RootDirectory = Src.RootDirectory;
[truncated at 1000 lines; 130 more skipped]