[NTOS:SE] Move SQOS capturing in its own file

* Quality of service kernel stuff bears nothing with security descriptors in anyway, so just have a file specifically for it
* Annotate the function arguments parameters with SAL
* Document the functions
This commit is contained in:
George Bișoc 2021-07-04 18:01:25 +02:00
parent fb8edf90a0
commit 7fb0d13a46
No known key found for this signature in database
GPG key ID: 688C4FBE25D7DEF6
4 changed files with 249 additions and 181 deletions

View file

@ -465,20 +465,20 @@ SepDuplicateToken(
NTSTATUS
NTAPI
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
_In_opt_ POBJECT_ATTRIBUTES ObjectAttributes,
_In_ KPROCESSOR_MODE AccessMode,
_In_ POOL_TYPE PoolType,
_In_ BOOLEAN CaptureIfKernel,
_Out_ PSECURITY_QUALITY_OF_SERVICE *CapturedSecurityQualityOfService,
_Out_ PBOOLEAN Present
);
VOID
NTAPI
SepReleaseSecurityQualityOfService(
IN PSECURITY_QUALITY_OF_SERVICE CapturedSecurityQualityOfService OPTIONAL,
IN KPROCESSOR_MODE AccessMode,
IN BOOLEAN CaptureIfKernel
_In_opt_ PSECURITY_QUALITY_OF_SERVICE CapturedSecurityQualityOfService,
_In_ KPROCESSOR_MODE AccessMode,
_In_ BOOLEAN CaptureIfKernel
);
NTSTATUS

View file

@ -280,6 +280,7 @@ list(APPEND SOURCE
${REACTOS_SOURCE_DIR}/ntoskrnl/se/sd.c
${REACTOS_SOURCE_DIR}/ntoskrnl/se/semgr.c
${REACTOS_SOURCE_DIR}/ntoskrnl/se/sid.c
${REACTOS_SOURCE_DIR}/ntoskrnl/se/sqos.c
${REACTOS_SOURCE_DIR}/ntoskrnl/se/srm.c
${REACTOS_SOURCE_DIR}/ntoskrnl/se/token.c
${REACTOS_SOURCE_DIR}/ntoskrnl/vf/driver.c

View file

@ -215,178 +215,6 @@ SeSetWorldSecurityDescriptor(SECURITY_INFORMATION SecurityInformation,
return STATUS_SUCCESS;
}
NTSTATUS
NTAPI
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;
_SEH2_TRY
{
ProbeForRead(ObjectAttributes,
sizeof(OBJECT_ATTRIBUTES),
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;
}
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
Status = _SEH2_GetExceptionCode();
}
_SEH2_END;
if (NT_SUCCESS(Status))
{
if (*Present)
{
CapturedQos = ExAllocatePoolWithTag(PoolType,
sizeof(SECURITY_QUALITY_OF_SERVICE),
TAG_QOS);
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 = ExAllocatePoolWithTag(PoolType,
sizeof(SECURITY_QUALITY_OF_SERVICE),
TAG_QOS);
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
NTAPI
SepReleaseSecurityQualityOfService(IN PSECURITY_QUALITY_OF_SERVICE CapturedSecurityQualityOfService OPTIONAL,
IN KPROCESSOR_MODE AccessMode,
IN BOOLEAN CaptureIfKernel)
{
PAGED_CODE();
if (CapturedSecurityQualityOfService != NULL &&
(AccessMode != KernelMode || CaptureIfKernel))
{
ExFreePoolWithTag(CapturedSecurityQualityOfService, TAG_QOS);
}
}
/* PUBLIC FUNCTIONS ***********************************************************/
static

239
ntoskrnl/se/sqos.c Normal file
View file

@ -0,0 +1,239 @@
/*
* PROJECT: ReactOS Kernel
* LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
* PURPOSE: Security Quality of Service (SQoS) implementation support
* COPYRIGHT: Copyright David Welch <welch@cwcom.net>
*/
/* INCLUDES *******************************************************************/
#include <ntoskrnl.h>
#define NDEBUG
#include <debug.h>
/* FUNCTIONS *******************************************************************/
/**
* @brief
* Captures the security quality of service data given the object
* attributes from an object.
*
* @param[in] ObjectAttributes
* Attributes of an object where SQOS is to be retrieved. If the caller
* doesn't fill object attributes to the function, it automatically assumes
* SQOS is not present, or if, there's no SQOS present in the object attributes list
* of the object itself.
*
* @param[in] AccessMode
* Processor access mode.
*
* @param[in] PoolType
* The pool type for the captured SQOS to be used for allocation.
*
* @param[in] CaptureIfKernel
* Capture access condition. To be set to TRUE if the capture is done within the kernel,
* FALSE if the capture is done in a kernel mode driver or user mode otherwise.
*
* @param[out] CapturedSecurityQualityOfService
* The captured SQOS data from the object.
*
* @param[out] Present
* Returns TRUE if SQOS is present in an object, FALSE otherwise. FALSE is also immediately
* returned if no object attributes is given to the call.
*
* @return
* STATUS_SUCCESS if SQOS from the object has been fully and successfully captured. STATUS_INVALID_PARAMETER
* if the caller submits an invalid object attributes list. STATUS_INSUFFICIENT_RESOURCES if the function has
* failed to allocate some resources in the pool for the captured SQOS. A failure NTSTATUS code is returned
* otherwise.
*/
NTSTATUS
NTAPI
SepCaptureSecurityQualityOfService(
_In_opt_ POBJECT_ATTRIBUTES ObjectAttributes,
_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;
_SEH2_TRY
{
ProbeForRead(ObjectAttributes,
sizeof(OBJECT_ATTRIBUTES),
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;
}
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
Status = _SEH2_GetExceptionCode();
}
_SEH2_END;
if (NT_SUCCESS(Status))
{
if (*Present)
{
CapturedQos = ExAllocatePoolWithTag(PoolType,
sizeof(SECURITY_QUALITY_OF_SERVICE),
TAG_QOS);
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 = ExAllocatePoolWithTag(PoolType,
sizeof(SECURITY_QUALITY_OF_SERVICE),
TAG_QOS);
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;
}
/**
* @brief
* Releases (frees) the captured SQOS data from an object in the memory pool.
*
* @param[in] CapturedSecurityQualityOfService
* The captured SQOS data to be released.
*
* @param[in] AccessMode
* Processor access mode.
*
* @param[in] CaptureIfKernel
* Capture access condition. To be set to TRUE if the capture is done within the kernel,
* FALSE if the capture is done in a kernel mode driver or user mode otherwise.
*
* @return
* Nothing.
*/
VOID
NTAPI
SepReleaseSecurityQualityOfService(
_In_opt_ PSECURITY_QUALITY_OF_SERVICE CapturedSecurityQualityOfService,
_In_ KPROCESSOR_MODE AccessMode,
_In_ BOOLEAN CaptureIfKernel)
{
PAGED_CODE();
if (CapturedSecurityQualityOfService != NULL &&
(AccessMode != KernelMode || CaptureIfKernel))
{
ExFreePoolWithTag(CapturedSecurityQualityOfService, TAG_QOS);
}
}
/* EOF */