xref: /reactos/ntoskrnl/se/objtype.c (revision 09dde2cf)
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