mirror of
https://github.com/reactos/reactos.git
synced 2024-06-29 01:12:06 +00:00
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:
parent
6830474b06
commit
322dbd6fba
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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; \
|
||||||
} \
|
} \
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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! */
|
||||||
|
|
|
@ -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
Loading…
Reference in a new issue