1 /* 2 * PROJECT: ReactOS Kernel 3 * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later) 4 * PURPOSE: Security object type list support routines 5 * COPYRIGHT: Copyright Timo Kreuzer <timo.kreuzer@reactos.org> 6 */ 7 8 /* INCLUDES *******************************************************************/ 9 10 #include <ntoskrnl.h> 11 #define NDEBUG 12 #include <debug.h> 13 14 /* PRIVATE FUNCTIONS ***********************************************************/ 15 16 /** 17 * @brief 18 * Captures a list of object types. 19 * 20 * @param[in] ObjectTypeList 21 * An existing list of object types. 22 * 23 * @param[in] ObjectTypeListLength 24 * The length size of the list. 25 * 26 * @param[in] PreviousMode 27 * Processor access level mode. 28 * 29 * @param[out] CapturedObjectTypeList 30 * The captured list of object types. 31 * 32 * @return 33 * Returns STATUS_SUCCESS if the list of object types has been captured 34 * successfully. STATUS_INVALID_PARAMETER is returned if the caller hasn't 35 * supplied a buffer list of object types. STATUS_INSUFFICIENT_RESOURCES 36 * is returned if pool memory allocation for the captured list has failed. 37 */ 38 NTSTATUS 39 SeCaptureObjectTypeList( 40 _In_reads_opt_(ObjectTypeListLength) POBJECT_TYPE_LIST ObjectTypeList, 41 _In_ ULONG ObjectTypeListLength, 42 _In_ KPROCESSOR_MODE PreviousMode, 43 _Out_ POBJECT_TYPE_LIST *CapturedObjectTypeList) 44 { 45 SIZE_T Size; 46 47 if (PreviousMode == KernelMode) 48 { 49 return STATUS_NOT_IMPLEMENTED; 50 } 51 52 if (ObjectTypeListLength == 0) 53 { 54 *CapturedObjectTypeList = NULL; 55 return STATUS_SUCCESS; 56 } 57 58 if (ObjectTypeList == NULL) 59 { 60 return STATUS_INVALID_PARAMETER; 61 } 62 63 /* Calculate the list size and check for integer overflow */ 64 Size = ObjectTypeListLength * sizeof(OBJECT_TYPE_LIST); 65 if (Size == 0) 66 { 67 return STATUS_INVALID_PARAMETER; 68 } 69 70 /* Allocate a new list */ 71 *CapturedObjectTypeList = ExAllocatePoolWithTag(PagedPool, Size, TAG_SEPA); 72 if (*CapturedObjectTypeList == NULL) 73 { 74 return STATUS_INSUFFICIENT_RESOURCES; 75 } 76 77 _SEH2_TRY 78 { 79 ProbeForRead(ObjectTypeList, Size, sizeof(ULONG)); 80 RtlCopyMemory(*CapturedObjectTypeList, ObjectTypeList, Size); 81 } 82 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) 83 { 84 ExFreePoolWithTag(*CapturedObjectTypeList, TAG_SEPA); 85 *CapturedObjectTypeList = NULL; 86 _SEH2_YIELD(return _SEH2_GetExceptionCode()); 87 } 88 _SEH2_END; 89 90 return STATUS_SUCCESS; 91 } 92 93 /** 94 * @brief 95 * Releases a buffer list of object types. 96 * 97 * @param[in] CapturedObjectTypeList 98 * A list of object types to free. 99 * 100 * @param[in] PreviousMode 101 * Processor access level mode. 102 * 103 * @return 104 * Nothing. 105 */ 106 VOID 107 SeReleaseObjectTypeList( 108 _In_ _Post_invalid_ POBJECT_TYPE_LIST CapturedObjectTypeList, 109 _In_ KPROCESSOR_MODE PreviousMode) 110 { 111 if ((PreviousMode != KernelMode) && (CapturedObjectTypeList != NULL)) 112 ExFreePoolWithTag(CapturedObjectTypeList, TAG_SEPA); 113 } 114 115 /* EOF */ 116