IoCreateFile should be passed kernelmode parameters.

svn path=/trunk/; revision=13252
This commit is contained in:
Gé van Geldorp 2005-01-24 19:42:54 +00:00
parent c011a8410e
commit fe7b4968ce
5 changed files with 896 additions and 83 deletions

View file

@ -21,4 +21,28 @@ RtlReleaseCapturedUnicodeString(IN PUNICODE_STRING CapturedString,
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 */

View file

@ -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 @@ IoCreateFile(OUT PHANDLE FileHandle,
PreviousMode = ExGetPreviousMode();
Status = ObCreateObject(PreviousMode,
Status = ObCreateObject(KernelMode,
IoFileObjectType,
ObjectAttributes,
PreviousMode,
@ -533,32 +533,132 @@ IoCreateFile(OUT PHANDLE FileHandle,
* @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 @@ NtCreateFile(PHANDLE FileHandle,
* @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 */

View file

@ -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 @@ NtCreateMailslotFile(OUT PHANDLE FileHandle,
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 */

View file

@ -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 @@ NtCreateNamedPipeFile(PHANDLE FileHandle,
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 @@ NtCreateNamedPipeFile(PHANDLE FileHandle,
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 @@ NtCreateNamedPipeFile(PHANDLE FileHandle,
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 */

View file

@ -32,6 +32,8 @@
#define NDEBUG
#include <internal/debug.h>
#define TAG_CAPT TAG('C', 'A', 'P', 'T')
/* FUNCTIONS *****************************************************************/
NTSTATUS
@ -95,7 +97,7 @@ RtlCaptureUnicodeString(OUT PUNICODE_STRING Dest,
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 @@ RtlCaptureAnsiString(PANSI_STRING Dest,
*/
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 @@ RtlCaptureAnsiString(PANSI_STRING Dest,
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;
Dest->ObjectName = ExAllocatePoolWithTag(PoolType, sizeof(UNICODE_STRING), TAG_CAPT);
if(NULL == Dest->ObjectName)
{
return STATUS_NO_MEMORY;
}
Status = RtlCaptureUnicodeString(Dest->ObjectName,
PreviousMode,
PoolType,
CaptureIfKernel,
Src.ObjectName);
if(!NT_SUCCESS(Status))
{
ExFreePool(Dest->ObjectName);
return Status;
}
Dest->Attributes = Src.Attributes;
if(NULL == Src.SecurityDescriptor)
{
Dest->SecurityDescriptor = NULL;
}
else
{
Dest->SecurityDescriptor = ExAllocatePoolWithTag(PoolType, sizeof(SECURITY_DESCRIPTOR), TAG_CAPT);
if(NULL == Dest->SecurityDescriptor)
{
RtlReleaseCapturedUnicodeString(Dest->ObjectName,
PreviousMode,
CaptureIfKernel);
ExFreePool(Dest->ObjectName);
return STATUS_NO_MEMORY;
}
Status = RtlCaptureSecurityDescriptor(Dest->SecurityDescriptor,
PreviousMode,
PoolType,
CaptureIfKernel,
Src.SecurityDescriptor);
if(!NT_SUCCESS(Status))
{
ExFreePool(Dest->SecurityDescriptor);
RtlReleaseCapturedUnicodeString(Dest->ObjectName,
PreviousMode,
CaptureIfKernel);
ExFreePool(Dest->ObjectName);
return Status;
}
}
if(NULL == Src.SecurityQualityOfService)
{
Dest->SecurityQualityOfService = NULL;
}
else
{
Dest->SecurityQualityOfService = ExAllocatePoolWithTag(PoolType, sizeof(SECURITY_QUALITY_OF_SERVICE), TAG_CAPT);
if(NULL == Dest->SecurityQualityOfService)
{
Status = STATUS_NO_MEMORY;
}
else
{
/*
* Copy the data to kernel space.
*/
_SEH_TRY
{
RtlCopyMemory(Dest->SecurityQualityOfService,
Src.SecurityQualityOfService,
sizeof(SECURITY_QUALITY_OF_SERVICE));
}
_SEH_HANDLE
{
Status = _SEH_GetExceptionCode();
}
_SEH_END;
if(!NT_SUCCESS(Status))
{
ExFreePool(Dest->SecurityQualityOfService);
}
}
if(!NT_SUCCESS(Status))
{
if(NULL != Dest->SecurityDescriptor)
{
RtlReleaseCapturedSecurityDescriptor(Dest->SecurityDescriptor,
PreviousMode,
CaptureIfKernel);
ExFreePool(Dest->SecurityDescriptor);
}
RtlReleaseCapturedUnicodeString(Dest->ObjectName,
PreviousMode,
CaptureIfKernel);
ExFreePool(Dest->ObjectName);
return Status;
}
}
return Status;
}
VOID
RtlReleaseCapturedObjectAttributes(IN POBJECT_ATTRIBUTES CapturedObjectAttributes,
IN KPROCESSOR_MODE PreviousMode,
IN BOOLEAN CaptureIfKernel)
{
ASSERT(NULL != CapturedObjectAttributes->ObjectName);
if(PreviousMode == KernelMode && !CaptureIfKernel)
{
return;
}
if(NULL != CapturedObjectAttributes->SecurityQualityOfService)
{
ExFreePool(CapturedObjectAttributes->SecurityQualityOfService);
}
if(NULL != CapturedObjectAttributes->SecurityDescriptor)
{
RtlReleaseCapturedSecurityDescriptor(CapturedObjectAttributes->SecurityDescriptor,
PreviousMode,
CaptureIfKernel);
ExFreePool(CapturedObjectAttributes->SecurityDescriptor);
}
RtlReleaseCapturedUnicodeString(CapturedObjectAttributes->ObjectName,
PreviousMode,
CaptureIfKernel);
ExFreePool(CapturedObjectAttributes->ObjectName);
}
/*
* @unimplemented
*/