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

View file

@ -153,13 +153,14 @@ typedef struct _SECURITY_DESCRIPTOR_CONTEXT
#define TOKEN_ADJUST_PRIVILEGES (0x0020L)
#define TOKEN_ADJUST_GROUPS (0x0040L)
#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_WRITE (0x200e0L)
#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_DYNAMIC_TRACKING (1)
@ -192,12 +193,13 @@ typedef enum _TOKEN_INFORMATION_CLASS
TokenOrigin
} TOKEN_INFORMATION_CLASS;
typedef ULONG SECURITY_IMPERSONATION_LEVEL, *PSECURITY_IMPERSONATION_LEVEL;
#define SecurityAnonymous ((SECURITY_IMPERSONATION_LEVEL)0)
#define SecurityIdentification ((SECURITY_IMPERSONATION_LEVEL)1)
#define SecurityImpersonation ((SECURITY_IMPERSONATION_LEVEL)2)
#define SecurityDelegation ((SECURITY_IMPERSONATION_LEVEL)3)
typedef enum _SECURITY_IMPERSONATION_LEVEL
{
SecurityAnonymous,
SecurityIdentification,
SecurityImpersonation,
SecurityDelegation
} SECURITY_IMPERSONATION_LEVEL, *PSECURITY_IMPERSONATION_LEVEL;
typedef ULONG ACCESS_MASK, *PACCESS_MASK;
typedef ULONG TOKEN_TYPE, *PTOKEN_TYPE;
@ -339,6 +341,20 @@ typedef struct _TOKEN_GROUPS
SID_AND_ATTRIBUTES Groups[ANYSIZE_ARRAY];
} 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
{
DWORD PrivilegeCount;

View file

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

View file

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

View file

@ -148,6 +148,60 @@ SepPrivilegeCheck(PTOKEN Token,
ULONG PrivilegeControl,
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 */

View file

@ -38,13 +38,41 @@ NtNotifyChangeDirectoryFile (
PIRP Irp;
PDEVICE_OBJECT DeviceObject;
PFILE_OBJECT FileObject;
NTSTATUS Status;
PIO_STACK_LOCATION IoStack;
KPROCESSOR_MODE PreviousMode;
NTSTATUS Status = STATUS_SUCCESS;
DPRINT("NtNotifyChangeDirectoryFile()\n");
PAGED_CODE();
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,
FILE_LIST_DIRECTORY,
@ -155,13 +183,38 @@ NtQueryDirectoryFile(
PIRP Irp;
PDEVICE_OBJECT DeviceObject;
PFILE_OBJECT FileObject;
NTSTATUS Status;
PIO_STACK_LOCATION IoStack;
KPROCESSOR_MODE PreviousMode;
NTSTATUS Status = STATUS_SUCCESS;
DPRINT("NtQueryDirectoryFile()\n");
PAGED_CODE();
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,
FILE_LIST_DIRECTORY,

View file

@ -102,6 +102,7 @@ ObpCaptureObjectAttributes(IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,
CapturedObjectAttributes->RootDirectory = ObjectAttributes->RootDirectory;
CapturedObjectAttributes->Attributes = ObjectAttributes->Attributes;
CapturedObjectAttributes->SecurityDescriptor = ObjectAttributes->SecurityDescriptor;
CapturedObjectAttributes->SecurityQualityOfService = ObjectAttributes->SecurityQualityOfService;
}
return STATUS_SUCCESS;
@ -147,6 +148,53 @@ ObpCaptureObjectAttributes(IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,
{
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)
@ -259,6 +307,8 @@ ObpCaptureObjectAttributes(IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,
{
ExFreePool(ObjectName->Buffer);
}
failcleanupsdescriptor:
if(CapturedObjectAttributes != NULL)
{
/* cleanup allocated resources */
@ -293,11 +343,18 @@ ObpReleaseObjectAttributes(IN PCAPTURED_OBJECT_ATTRIBUTES CapturedObjectAttribut
to ObpCaptureObjectAttributes() to avoid memory leaks */
if(AccessMode != KernelMode || CaptureIfKernel)
{
if(CapturedObjectAttributes != NULL &&
CapturedObjectAttributes->SecurityDescriptor != NULL)
if(CapturedObjectAttributes != NULL)
{
ExFreePool(CapturedObjectAttributes->SecurityDescriptor);
CapturedObjectAttributes->SecurityDescriptor = NULL;
if(CapturedObjectAttributes->SecurityDescriptor != NULL)
{
ExFreePool(CapturedObjectAttributes->SecurityDescriptor);
CapturedObjectAttributes->SecurityDescriptor = NULL;
}
if(CapturedObjectAttributes->SecurityQualityOfService != NULL)
{
ExFreePool(CapturedObjectAttributes->SecurityQualityOfService);
CapturedObjectAttributes->SecurityQualityOfService = NULL;
}
}
if(ObjectName != NULL &&
ObjectName->Length > 0)

View file

@ -263,4 +263,105 @@ SepCreateImpersonationTokenDacl(PTOKEN Token,
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 */

View file

@ -102,32 +102,4 @@ NtAllocateLocallyUniqueId(OUT LUID *LocallyUniqueId)
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 */

View file

@ -108,6 +108,174 @@ SepInitSDs(VOID)
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
*/
@ -572,6 +740,8 @@ SeReleaseSecurityDescriptor(
IN BOOLEAN CaptureIfKernelMode
)
{
PAGED_CODE();
/* WARNING! You need to call this function with the same value for CurrentMode
and CaptureIfKernelMode that you previously passed to
SeCaptureSecurityDescriptor() in order to avoid memory leaks! */

View file

@ -466,4 +466,107 @@ SepInitSecurityIDs(VOID)
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 */

File diff suppressed because it is too large Load diff