Thomas Weidenmueller <w3seek@reactos.com>

- Fix various security structures and constants
- Add code to capture quality of service structures and ACLs
- Secure buffer access in NtQueryInformationToken, NtSetInformationToken, NtNotifyChangeDirectoryFile and NtQueryDirectoryFile

svn path=/trunk/; revision=13984
This commit is contained in:
Thomas Bluemel 2005-03-12 22:16:02 +00:00
parent 6830474b06
commit 322dbd6fba
12 changed files with 1375 additions and 475 deletions

View file

@ -98,37 +98,36 @@ typedef struct _SEP_AUDIT_POLICY {
} SEP_AUDIT_POLICY, *PSEP_AUDIT_POLICY; } SEP_AUDIT_POLICY, *PSEP_AUDIT_POLICY;
typedef struct _TOKEN { typedef struct _TOKEN {
TOKEN_SOURCE TokenSource; /* 0x00 */ TOKEN_SOURCE TokenSource; /* 0x00 */
LUID TokenId; /* 0x10 */ LUID TokenId; /* 0x10 */
LUID AuthenticationId; /* 0x18 */ LUID AuthenticationId; /* 0x18 */
LUID ParentTokenId; /* 0x20 */ LUID ParentTokenId; /* 0x20 */
LARGE_INTEGER ExpirationTime; /* 0x28 */ LARGE_INTEGER ExpirationTime; /* 0x28 */
struct _ERESOURCE *TokenLock; /* 0x30 */ struct _ERESOURCE *TokenLock; /* 0x30 */
ULONG Padding; /* 0x34 */ SEP_AUDIT_POLICY AuditPolicy; /* 0x38 */
SEP_AUDIT_POLICY AuditPolicy; /* 0x38 */ LUID ModifiedId; /* 0x40 */
LUID ModifiedId; /* 0x40 */ ULONG SessionId; /* 0x48 */
ULONG SessionId; /* 0x48 */ ULONG UserAndGroupCount; /* 0x4C */
ULONG UserAndGroupCount; /* 0x4C */ ULONG RestrictedSidCount; /* 0x50 */
ULONG RestrictedSidCount; /* 0x50 */ ULONG PrivilegeCount; /* 0x54 */
ULONG PrivilegeCount; /* 0x54 */ ULONG VariableLength; /* 0x58 */
ULONG VariableLength; /* 0x58 */ ULONG DynamicCharged; /* 0x5C */
ULONG DynamicCharged; /* 0x5C */ ULONG DynamicAvailable; /* 0x60 */
ULONG DynamicAvailable; /* 0x60 */ ULONG DefaultOwnerIndex; /* 0x64 */
ULONG DefaultOwnerIndex; /* 0x64 */ PSID_AND_ATTRIBUTES UserAndGroups; /* 0x68 */
PSID_AND_ATTRIBUTES UserAndGroups; /* 0x68 */ PSID_AND_ATTRIBUTES RestrictedSids; /* 0x6C */
PSID_AND_ATTRIBUTES RestrictedSids; /* 0x6C */ PSID PrimaryGroup; /* 0x70 */
PSID PrimaryGroup; /* 0x70 */ PLUID_AND_ATTRIBUTES Privileges; /* 0x74 */
PLUID_AND_ATTRIBUTES Privileges; /* 0x74 */ PULONG DynamicPart; /* 0x78 */
PULONG DynamicPart; /* 0x78 */ PACL DefaultDacl; /* 0x7C */
PACL DefaultDacl; /* 0x7C */ TOKEN_TYPE TokenType; /* 0x80 */
TOKEN_TYPE TokenType; /* 0x80 */ SECURITY_IMPERSONATION_LEVEL ImpersonationLevel; /* 0x84 */
SECURITY_IMPERSONATION_LEVEL ImpersonationLevel; /* 0x84 */ ULONG TokenFlags; /* 0x88 */
ULONG TokenFlags; /* 0x88 */ BOOLEAN TokenInUse; /* 0x8C */
ULONG TokenInUse; /* 0x8C */ PVOID ProxyData; /* 0x90 */
PVOID ProxyData; /* 0x90 */ PVOID AuditData; /* 0x94 */
PVOID AuditData; /* 0x94 */ LUID OriginatingLogonSession; /* 0x98 */
LUID OriginatingLogonSession; /* 0x98 */ ULONG VariablePart; /* 0xA0 */
UCHAR VariablePart[1]; /* 0xA0 */
} TOKEN, *PTOKEN; } TOKEN, *PTOKEN;
typedef PVOID PACCESS_TOKEN; typedef PVOID PACCESS_TOKEN;

View file

@ -153,13 +153,14 @@ typedef struct _SECURITY_DESCRIPTOR_CONTEXT
#define TOKEN_ADJUST_PRIVILEGES (0x0020L) #define TOKEN_ADJUST_PRIVILEGES (0x0020L)
#define TOKEN_ADJUST_GROUPS (0x0040L) #define TOKEN_ADJUST_GROUPS (0x0040L)
#define TOKEN_ADJUST_DEFAULT (0x0080L) #define TOKEN_ADJUST_DEFAULT (0x0080L)
#define TOKEN_ADJUST_SESSIONID (0x0100L)
#define TOKEN_ALL_ACCESS (0xf00ffL) #define TOKEN_ALL_ACCESS (0xf01ffL)
#define TOKEN_READ (0x20008L) #define TOKEN_READ (0x20008L)
#define TOKEN_WRITE (0x200e0L) #define TOKEN_WRITE (0x200e0L)
#define TOKEN_EXECUTE (0x20000L) #define TOKEN_EXECUTE (0x20000L)
typedef BOOL SECURITY_CONTEXT_TRACKING_MODE; typedef BOOLEAN SECURITY_CONTEXT_TRACKING_MODE, *PSECURITY_CONTEXT_TRACKING_MODE;
#define SECURITY_STATIC_TRACKING (0) #define SECURITY_STATIC_TRACKING (0)
#define SECURITY_DYNAMIC_TRACKING (1) #define SECURITY_DYNAMIC_TRACKING (1)
@ -192,12 +193,13 @@ typedef enum _TOKEN_INFORMATION_CLASS
TokenOrigin TokenOrigin
} TOKEN_INFORMATION_CLASS; } TOKEN_INFORMATION_CLASS;
typedef ULONG SECURITY_IMPERSONATION_LEVEL, *PSECURITY_IMPERSONATION_LEVEL; typedef enum _SECURITY_IMPERSONATION_LEVEL
{
#define SecurityAnonymous ((SECURITY_IMPERSONATION_LEVEL)0) SecurityAnonymous,
#define SecurityIdentification ((SECURITY_IMPERSONATION_LEVEL)1) SecurityIdentification,
#define SecurityImpersonation ((SECURITY_IMPERSONATION_LEVEL)2) SecurityImpersonation,
#define SecurityDelegation ((SECURITY_IMPERSONATION_LEVEL)3) SecurityDelegation
} SECURITY_IMPERSONATION_LEVEL, *PSECURITY_IMPERSONATION_LEVEL;
typedef ULONG ACCESS_MASK, *PACCESS_MASK; typedef ULONG ACCESS_MASK, *PACCESS_MASK;
typedef ULONG TOKEN_TYPE, *PTOKEN_TYPE; typedef ULONG TOKEN_TYPE, *PTOKEN_TYPE;
@ -339,6 +341,20 @@ typedef struct _TOKEN_GROUPS
SID_AND_ATTRIBUTES Groups[ANYSIZE_ARRAY]; SID_AND_ATTRIBUTES Groups[ANYSIZE_ARRAY];
} TOKEN_GROUPS, *PTOKEN_GROUPS, *LPTOKEN_GROUPS; } TOKEN_GROUPS, *PTOKEN_GROUPS, *LPTOKEN_GROUPS;
typedef struct _TOKEN_GROUPS_AND_PRIVILEGES
{
ULONG SidCount;
ULONG SidLength;
PSID_AND_ATTRIBUTES Sids;
ULONG RestrictedSidCount;
ULONG RestrictedSidLength;
PSID_AND_ATTRIBUTES RestrictedSids;
ULONG PrivilegeCount;
ULONG PrivilegeLength;
PLUID_AND_ATTRIBUTES Privileges;
LUID AuthenticationId;
} TOKEN_GROUPS_AND_PRIVILEGES, *PTOKEN_GROUPS_AND_PRIVILEGES;
typedef struct _TOKEN_PRIVILEGES typedef struct _TOKEN_PRIVILEGES
{ {
DWORD PrivilegeCount; DWORD PrivilegeCount;

View file

@ -200,7 +200,7 @@ RtlCopySidAndAttributesArray(ULONG Count,
RtlCopySid(SidLength, RtlCopySid(SidLength,
SidArea, SidArea,
Src[i].Sid); Src[i].Sid);
SidArea = SidArea + SidLength; SidArea = (PVOID)((ULONG_PTR)SidArea + SidLength);
} }
*RemainingSidArea = SidArea; *RemainingSidArea = SidArea;
*RemainingSidAreaSize = Length; *RemainingSidAreaSize = Length;

View file

@ -326,7 +326,7 @@ typedef struct _CAPTURED_OBJECT_ATTRIBUTES
HANDLE RootDirectory; HANDLE RootDirectory;
ULONG Attributes; ULONG Attributes;
PSECURITY_DESCRIPTOR SecurityDescriptor; PSECURITY_DESCRIPTOR SecurityDescriptor;
/* PVOID SecurityQualityOfService; */ PSECURITY_QUALITY_OF_SERVICE SecurityQualityOfService;
} CAPTURED_OBJECT_ATTRIBUTES, *PCAPTURED_OBJECT_ATTRIBUTES; } CAPTURED_OBJECT_ATTRIBUTES, *PCAPTURED_OBJECT_ATTRIBUTES;
NTSTATUS NTSTATUS
@ -377,10 +377,8 @@ typedef struct _INFORMATION_CLASS_INFO
else if(ClassList[Class].RequiredSize##Mode > 0 && \ else if(ClassList[Class].RequiredSize##Mode > 0 && \
(BufferLen) != ClassList[Class].RequiredSize##Mode) \ (BufferLen) != ClassList[Class].RequiredSize##Mode) \
{ \ { \
if((!(ClassList[Class].Flags & ICIF_##Mode##_SIZE_VARIABLE) && \ if(!(ClassList[Class].Flags & ICIF_##Mode##_SIZE_VARIABLE) && \
(BufferLen) != ClassList[Class].RequiredSize##Mode) || \ (BufferLen) != ClassList[Class].RequiredSize##Mode) \
((ClassList[Class].Flags & ICIF_##Mode##_SIZE_VARIABLE) && \
(BufferLen) < ClassList[Class].RequiredSize##Mode)) \
{ \ { \
*(StatusVar) = STATUS_INFO_LENGTH_MISMATCH; \ *(StatusVar) = STATUS_INFO_LENGTH_MISMATCH; \
} \ } \

View file

@ -148,6 +148,60 @@ SepPrivilegeCheck(PTOKEN Token,
ULONG PrivilegeControl, ULONG PrivilegeControl,
KPROCESSOR_MODE PreviousMode); KPROCESSOR_MODE PreviousMode);
NTSTATUS
SepCaptureSecurityQualityOfService(IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,
IN KPROCESSOR_MODE AccessMode,
IN POOL_TYPE PoolType,
IN BOOLEAN CaptureIfKernel,
OUT PSECURITY_QUALITY_OF_SERVICE *CapturedSecurityQualityOfService,
OUT PBOOLEAN Present);
VOID
SepReleaseSecurityQualityOfService(IN PSECURITY_QUALITY_OF_SERVICE CapturedSecurityQualityOfService OPTIONAL,
IN KPROCESSOR_MODE AccessMode,
IN BOOLEAN CaptureIfKernel);
NTSTATUS
SepCaptureSid(IN PSID InputSid,
IN KPROCESSOR_MODE AccessMode,
IN POOL_TYPE PoolType,
IN BOOLEAN CaptureIfKernel,
OUT PSID *CapturedSid);
VOID
SepReleaseSid(IN PSID CapturedSid,
IN KPROCESSOR_MODE AccessMode,
IN BOOLEAN CaptureIfKernel);
NTSTATUS
SepCaptureAcl(IN PACL InputAcl,
IN KPROCESSOR_MODE AccessMode,
IN POOL_TYPE PoolType,
IN BOOLEAN CaptureIfKernel,
OUT PACL *CapturedAcl);
VOID
SepReleaseAcl(IN PACL CapturedAcl,
IN KPROCESSOR_MODE AccessMode,
IN BOOLEAN CaptureIfKernel);
#define SepAcquireTokenLockExclusive(Token) \
do { \
KeEnterCriticalRegion(); \
ExAcquireResourceExclusive(((PTOKEN)Token)->TokenLock, TRUE); \
while(0)
#define SepAcquireTokenLockShared(Token) \
do { \
KeEnterCriticalRegion(); \
ExAcquireResourceShared(((PTOKEN)Token)->TokenLock, TRUE); \
while(0)
#define SepReleaseTokenLock(Token) \
do { \
ExReleaseResource(((PTOKEN)Token)->TokenLock); \
KeLeaveCriticalRegion(); \
while(0)
#endif /* __NTOSKRNL_INCLUDE_INTERNAL_SE_H */ #endif /* __NTOSKRNL_INCLUDE_INTERNAL_SE_H */

View file

@ -38,13 +38,41 @@ NtNotifyChangeDirectoryFile (
PIRP Irp; PIRP Irp;
PDEVICE_OBJECT DeviceObject; PDEVICE_OBJECT DeviceObject;
PFILE_OBJECT FileObject; PFILE_OBJECT FileObject;
NTSTATUS Status;
PIO_STACK_LOCATION IoStack; PIO_STACK_LOCATION IoStack;
KPROCESSOR_MODE PreviousMode; KPROCESSOR_MODE PreviousMode;
NTSTATUS Status = STATUS_SUCCESS;
DPRINT("NtNotifyChangeDirectoryFile()\n"); DPRINT("NtNotifyChangeDirectoryFile()\n");
PAGED_CODE();
PreviousMode = ExGetPreviousMode(); PreviousMode = ExGetPreviousMode();
if(PreviousMode != KernelMode)
{
_SEH_TRY
{
ProbeForWrite(IoStatusBlock,
sizeof(IO_STATUS_BLOCK),
sizeof(ULONG));
if(BufferSize != 0)
{
ProbeForWrite(Buffer,
BufferSize,
sizeof(ULONG));
}
}
_SEH_HANDLE
{
Status = _SEH_GetExceptionCode();
}
_SEH_END;
if(!NT_SUCCESS(Status))
{
return Status;
}
}
Status = ObReferenceObjectByHandle(FileHandle, Status = ObReferenceObjectByHandle(FileHandle,
FILE_LIST_DIRECTORY, FILE_LIST_DIRECTORY,
@ -155,13 +183,38 @@ NtQueryDirectoryFile(
PIRP Irp; PIRP Irp;
PDEVICE_OBJECT DeviceObject; PDEVICE_OBJECT DeviceObject;
PFILE_OBJECT FileObject; PFILE_OBJECT FileObject;
NTSTATUS Status;
PIO_STACK_LOCATION IoStack; PIO_STACK_LOCATION IoStack;
KPROCESSOR_MODE PreviousMode; KPROCESSOR_MODE PreviousMode;
NTSTATUS Status = STATUS_SUCCESS;
DPRINT("NtQueryDirectoryFile()\n"); DPRINT("NtQueryDirectoryFile()\n");
PAGED_CODE();
PreviousMode = ExGetPreviousMode(); PreviousMode = ExGetPreviousMode();
if(PreviousMode != KernelMode)
{
_SEH_TRY
{
ProbeForWrite(IoStatusBlock,
sizeof(IO_STATUS_BLOCK),
sizeof(ULONG));
ProbeForWrite(FileInformation,
Length,
sizeof(ULONG));
}
_SEH_HANDLE
{
Status = _SEH_GetExceptionCode();
}
_SEH_END;
if(!NT_SUCCESS(Status))
{
return Status;
}
}
Status = ObReferenceObjectByHandle(FileHandle, Status = ObReferenceObjectByHandle(FileHandle,
FILE_LIST_DIRECTORY, FILE_LIST_DIRECTORY,

View file

@ -102,6 +102,7 @@ ObpCaptureObjectAttributes(IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,
CapturedObjectAttributes->RootDirectory = ObjectAttributes->RootDirectory; CapturedObjectAttributes->RootDirectory = ObjectAttributes->RootDirectory;
CapturedObjectAttributes->Attributes = ObjectAttributes->Attributes; CapturedObjectAttributes->Attributes = ObjectAttributes->Attributes;
CapturedObjectAttributes->SecurityDescriptor = ObjectAttributes->SecurityDescriptor; CapturedObjectAttributes->SecurityDescriptor = ObjectAttributes->SecurityDescriptor;
CapturedObjectAttributes->SecurityQualityOfService = ObjectAttributes->SecurityQualityOfService;
} }
return STATUS_SUCCESS; return STATUS_SUCCESS;
@ -147,6 +148,53 @@ ObpCaptureObjectAttributes(IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,
{ {
CapturedObjectAttributes->SecurityDescriptor = NULL; CapturedObjectAttributes->SecurityDescriptor = NULL;
} }
if(AttributesCopy.SecurityQualityOfService != NULL)
{
SECURITY_QUALITY_OF_SERVICE SafeQoS;
_SEH_TRY
{
ProbeForRead(AttributesCopy.SecurityQualityOfService,
sizeof(SECURITY_QUALITY_OF_SERVICE),
sizeof(ULONG));
SafeQoS = *(PSECURITY_QUALITY_OF_SERVICE)AttributesCopy.SecurityQualityOfService;
}
_SEH_HANDLE
{
Status = _SEH_GetExceptionCode();
}
_SEH_END;
if(!NT_SUCCESS(Status))
{
DPRINT1("Unable to capture QoS!!!\n");
goto failcleanupsdescriptor;
}
if(SafeQoS.Length != sizeof(SECURITY_QUALITY_OF_SERVICE))
{
DPRINT1("Unable to capture QoS, wrong size!!!\n");
Status = STATUS_INVALID_PARAMETER;
goto failcleanupsdescriptor;
}
CapturedObjectAttributes->SecurityQualityOfService = ExAllocatePool(PoolType,
sizeof(SECURITY_QUALITY_OF_SERVICE));
if(CapturedObjectAttributes->SecurityQualityOfService != NULL)
{
*CapturedObjectAttributes->SecurityQualityOfService = SafeQoS;
}
else
{
Status = STATUS_INSUFFICIENT_RESOURCES;
goto failcleanupsdescriptor;
}
}
else
{
CapturedObjectAttributes->SecurityQualityOfService = NULL;
}
} }
if(ObjectName != NULL) if(ObjectName != NULL)
@ -259,6 +307,8 @@ ObpCaptureObjectAttributes(IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,
{ {
ExFreePool(ObjectName->Buffer); ExFreePool(ObjectName->Buffer);
} }
failcleanupsdescriptor:
if(CapturedObjectAttributes != NULL) if(CapturedObjectAttributes != NULL)
{ {
/* cleanup allocated resources */ /* cleanup allocated resources */
@ -293,11 +343,18 @@ ObpReleaseObjectAttributes(IN PCAPTURED_OBJECT_ATTRIBUTES CapturedObjectAttribut
to ObpCaptureObjectAttributes() to avoid memory leaks */ to ObpCaptureObjectAttributes() to avoid memory leaks */
if(AccessMode != KernelMode || CaptureIfKernel) if(AccessMode != KernelMode || CaptureIfKernel)
{ {
if(CapturedObjectAttributes != NULL && if(CapturedObjectAttributes != NULL)
CapturedObjectAttributes->SecurityDescriptor != NULL)
{ {
ExFreePool(CapturedObjectAttributes->SecurityDescriptor); if(CapturedObjectAttributes->SecurityDescriptor != NULL)
CapturedObjectAttributes->SecurityDescriptor = NULL; {
ExFreePool(CapturedObjectAttributes->SecurityDescriptor);
CapturedObjectAttributes->SecurityDescriptor = NULL;
}
if(CapturedObjectAttributes->SecurityQualityOfService != NULL)
{
ExFreePool(CapturedObjectAttributes->SecurityQualityOfService);
CapturedObjectAttributes->SecurityQualityOfService = NULL;
}
} }
if(ObjectName != NULL && if(ObjectName != NULL &&
ObjectName->Length > 0) ObjectName->Length > 0)

View file

@ -263,4 +263,105 @@ SepCreateImpersonationTokenDacl(PTOKEN Token,
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
NTSTATUS
SepCaptureAcl(IN PACL InputAcl,
IN KPROCESSOR_MODE AccessMode,
IN POOL_TYPE PoolType,
IN BOOLEAN CaptureIfKernel,
OUT PACL *CapturedAcl)
{
PACL NewAcl;
ULONG AclSize = 0;
NTSTATUS Status = STATUS_SUCCESS;
PAGED_CODE();
if(AccessMode != KernelMode)
{
_SEH_TRY
{
ProbeForRead(InputAcl,
sizeof(ACL),
sizeof(ULONG));
AclSize = InputAcl->AclSize;
ProbeForRead(InputAcl,
AclSize,
sizeof(ULONG));
}
_SEH_HANDLE
{
Status = _SEH_GetExceptionCode();
}
_SEH_END;
if(NT_SUCCESS(Status))
{
NewAcl = ExAllocatePool(PoolType,
AclSize);
if(NewAcl != NULL)
{
_SEH_TRY
{
RtlCopyMemory(NewAcl,
InputAcl,
AclSize);
*CapturedAcl = NewAcl;
}
_SEH_HANDLE
{
ExFreePool(NewAcl);
Status = _SEH_GetExceptionCode();
}
_SEH_END;
}
else
{
Status = STATUS_INSUFFICIENT_RESOURCES;
}
}
}
else if(!CaptureIfKernel)
{
*CapturedAcl = InputAcl;
}
else
{
AclSize = InputAcl->AclSize;
NewAcl = ExAllocatePool(PoolType,
AclSize);
if(NewAcl != NULL)
{
RtlCopyMemory(NewAcl,
InputAcl,
AclSize);
*CapturedAcl = NewAcl;
}
else
{
Status = STATUS_INSUFFICIENT_RESOURCES;
}
}
return Status;
}
VOID
SepReleaseAcl(IN PACL CapturedAcl,
IN KPROCESSOR_MODE AccessMode,
IN BOOLEAN CaptureIfKernel)
{
PAGED_CODE();
if(CapturedAcl != NULL &&
(AccessMode == UserMode ||
(AccessMode == KernelMode && CaptureIfKernel)))
{
ExFreePool(CapturedAcl);
}
}
/* EOF */ /* EOF */

View file

@ -102,32 +102,4 @@ NtAllocateLocallyUniqueId(OUT LUID *LocallyUniqueId)
return Status; return Status;
} }
/*
* @implemented
*/
VOID STDCALL
RtlCopyLuid(IN PLUID LuidDest,
IN PLUID LuidSrc)
{
PAGED_CODE_RTL();
LuidDest->LowPart = LuidSrc->LowPart;
LuidDest->HighPart = LuidSrc->HighPart;
}
/*
* @implemented
*/
BOOLEAN STDCALL
RtlEqualLuid(IN PLUID Luid1,
IN PLUID Luid2)
{
PAGED_CODE_RTL();
return (Luid1->LowPart == Luid2->LowPart &&
Luid1->HighPart == Luid2->HighPart);
}
/* EOF */ /* EOF */

View file

@ -108,6 +108,174 @@ SepInitSDs(VOID)
return TRUE; return TRUE;
} }
NTSTATUS
SepCaptureSecurityQualityOfService(IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,
IN KPROCESSOR_MODE AccessMode,
IN POOL_TYPE PoolType,
IN BOOLEAN CaptureIfKernel,
OUT PSECURITY_QUALITY_OF_SERVICE *CapturedSecurityQualityOfService,
OUT PBOOLEAN Present)
{
PSECURITY_QUALITY_OF_SERVICE CapturedQos;
NTSTATUS Status = STATUS_SUCCESS;
PAGED_CODE();
ASSERT(CapturedSecurityQualityOfService);
ASSERT(Present);
if(ObjectAttributes != NULL)
{
if(AccessMode != KernelMode)
{
SECURITY_QUALITY_OF_SERVICE SafeQos;
_SEH_TRY
{
ProbeForRead(ObjectAttributes,
sizeof(ObjectAttributes),
sizeof(ULONG));
if(ObjectAttributes->Length == sizeof(OBJECT_ATTRIBUTES))
{
if(ObjectAttributes->SecurityQualityOfService != NULL)
{
ProbeForRead(ObjectAttributes->SecurityQualityOfService,
sizeof(SECURITY_QUALITY_OF_SERVICE),
sizeof(ULONG));
if(((PSECURITY_QUALITY_OF_SERVICE)ObjectAttributes->SecurityQualityOfService)->Length ==
sizeof(SECURITY_QUALITY_OF_SERVICE))
{
/* don't allocate memory here because ExAllocate should bugcheck
the system if it's buggy, SEH would catch that! So make a local
copy of the qos structure.*/
RtlCopyMemory(&SafeQos,
ObjectAttributes->SecurityQualityOfService,
sizeof(SECURITY_QUALITY_OF_SERVICE));
*Present = TRUE;
}
else
{
Status = STATUS_INVALID_PARAMETER;
}
}
else
{
*CapturedSecurityQualityOfService = NULL;
*Present = FALSE;
}
}
else
{
Status = STATUS_INVALID_PARAMETER;
}
}
_SEH_HANDLE
{
Status = _SEH_GetExceptionCode();
}
_SEH_END;
if(NT_SUCCESS(Status))
{
if(*Present)
{
CapturedQos = ExAllocatePool(PoolType,
sizeof(SECURITY_QUALITY_OF_SERVICE));
if(CapturedQos != NULL)
{
RtlCopyMemory(CapturedQos,
&SafeQos,
sizeof(SECURITY_QUALITY_OF_SERVICE));
*CapturedSecurityQualityOfService = CapturedQos;
}
else
{
Status = STATUS_INSUFFICIENT_RESOURCES;
}
}
else
{
*CapturedSecurityQualityOfService = NULL;
}
}
}
else
{
if(ObjectAttributes->Length == sizeof(OBJECT_ATTRIBUTES))
{
if(CaptureIfKernel)
{
if(ObjectAttributes->SecurityQualityOfService != NULL)
{
if(((PSECURITY_QUALITY_OF_SERVICE)ObjectAttributes->SecurityQualityOfService)->Length ==
sizeof(SECURITY_QUALITY_OF_SERVICE))
{
CapturedQos = ExAllocatePool(PoolType,
sizeof(SECURITY_QUALITY_OF_SERVICE));
if(CapturedQos != NULL)
{
RtlCopyMemory(CapturedQos,
ObjectAttributes->SecurityQualityOfService,
sizeof(SECURITY_QUALITY_OF_SERVICE));
*CapturedSecurityQualityOfService = CapturedQos;
*Present = TRUE;
}
else
{
Status = STATUS_INSUFFICIENT_RESOURCES;
}
}
else
{
Status = STATUS_INVALID_PARAMETER;
}
}
else
{
*CapturedSecurityQualityOfService = NULL;
*Present = FALSE;
}
}
else
{
*CapturedSecurityQualityOfService = (PSECURITY_QUALITY_OF_SERVICE)ObjectAttributes->SecurityQualityOfService;
*Present = (ObjectAttributes->SecurityQualityOfService != NULL);
}
}
else
{
Status = STATUS_INVALID_PARAMETER;
}
}
}
else
{
*CapturedSecurityQualityOfService = NULL;
*Present = FALSE;
}
return Status;
}
VOID
SepReleaseSecurityQualityOfService(IN PSECURITY_QUALITY_OF_SERVICE CapturedSecurityQualityOfService OPTIONAL,
IN KPROCESSOR_MODE AccessMode,
IN BOOLEAN CaptureIfKernel)
{
PAGED_CODE();
if(CapturedSecurityQualityOfService != NULL &&
(AccessMode == UserMode ||
(AccessMode == KernelMode && CaptureIfKernel)))
{
ExFreePool(CapturedSecurityQualityOfService);
}
}
/* /*
* @implemented * @implemented
*/ */
@ -572,6 +740,8 @@ SeReleaseSecurityDescriptor(
IN BOOLEAN CaptureIfKernelMode IN BOOLEAN CaptureIfKernelMode
) )
{ {
PAGED_CODE();
/* WARNING! You need to call this function with the same value for CurrentMode /* WARNING! You need to call this function with the same value for CurrentMode
and CaptureIfKernelMode that you previously passed to and CaptureIfKernelMode that you previously passed to
SeCaptureSecurityDescriptor() in order to avoid memory leaks! */ SeCaptureSecurityDescriptor() in order to avoid memory leaks! */

View file

@ -466,4 +466,107 @@ SepInitSecurityIDs(VOID)
return(TRUE); return(TRUE);
} }
NTSTATUS
SepCaptureSid(IN PSID InputSid,
IN KPROCESSOR_MODE AccessMode,
IN POOL_TYPE PoolType,
IN BOOLEAN CaptureIfKernel,
OUT PSID *CapturedSid)
{
ULONG SidSize = 0;
PISID NewSid, Sid = (PISID)InputSid;
NTSTATUS Status = STATUS_SUCCESS;
PAGED_CODE();
if(AccessMode != KernelMode)
{
_SEH_TRY
{
ProbeForRead(Sid,
sizeof(*Sid) - sizeof(Sid->SubAuthority),
sizeof(UCHAR));
SidSize = RtlLengthRequiredSid(Sid->SubAuthorityCount);
ProbeForRead(Sid,
SidSize,
sizeof(UCHAR));
}
_SEH_HANDLE
{
Status = _SEH_GetExceptionCode();
}
_SEH_END;
if(NT_SUCCESS(Status))
{
/* allocate a SID and copy it */
NewSid = ExAllocatePool(PoolType,
SidSize);
if(NewSid != NULL)
{
_SEH_TRY
{
RtlCopyMemory(NewSid,
Sid,
SidSize);
*CapturedSid = NewSid;
}
_SEH_HANDLE
{
ExFreePool(NewSid);
Status = _SEH_GetExceptionCode();
}
_SEH_END;
}
else
{
Status = STATUS_INSUFFICIENT_RESOURCES;
}
}
}
else if(!CaptureIfKernel)
{
*CapturedSid = InputSid;
return STATUS_SUCCESS;
}
else
{
SidSize = RtlLengthRequiredSid(Sid->SubAuthorityCount);
/* allocate a SID and copy it */
NewSid = ExAllocatePool(PoolType,
SidSize);
if(NewSid != NULL)
{
RtlCopyMemory(NewSid,
Sid,
SidSize);
*CapturedSid = NewSid;
}
else
{
Status = STATUS_INSUFFICIENT_RESOURCES;
}
}
return Status;
}
VOID
SepReleaseSid(IN PSID CapturedSid,
IN KPROCESSOR_MODE AccessMode,
IN BOOLEAN CaptureIfKernel)
{
PAGED_CODE();
if(CapturedSid != NULL &&
(AccessMode == UserMode ||
(AccessMode == KernelMode && CaptureIfKernel)))
{
ExFreePool(CapturedSid);
}
}
/* EOF */ /* EOF */

File diff suppressed because it is too large Load diff