ReactOS 0.4.15-dev-8227-g32d615f
objtype.c File Reference
#include <ntoskrnl.h>
#include <debug.h>
Include dependency graph for objtype.c:

Go to the source code of this file.

Macros

#define NDEBUG
 

Functions

static NTSTATUS SepValidateObjectTypeList (_In_reads_(ObjectTypeListLength) POBJECT_TYPE_LIST ObjectTypeList, _In_ ULONG ObjectTypeListLength)
 Validates a list of object types passed from user mode, ensuring the following conditions are met for a valid list:
 
static BOOLEAN SepIsEqualObjectTypeGuid (_In_ CONST GUID *Guid1, _In_ CONST GUID *Guid2)
 Compares two object type GUIDs for equality.
 
PGUID SepGetObjectTypeGuidFromAce (_In_ PACE Ace, _In_ BOOLEAN IsAceDenied)
 Captures an object type GUID from an object access control entry (ACE).
 
BOOLEAN SepObjectTypeGuidInList (_In_reads_(ObjectTypeListLength) POBJECT_TYPE_LIST_INTERNAL ObjectTypeList, _In_ ULONG ObjectTypeListLength, _In_ PGUID ObjectTypeGuid, _Out_ PULONG ObjectIndex)
 Searches for an object type GUID if it exists on an object type list.
 
NTSTATUS SeCaptureObjectTypeList (_In_reads_opt_(ObjectTypeListLength) POBJECT_TYPE_LIST ObjectTypeList, _In_ ULONG ObjectTypeListLength, _In_ KPROCESSOR_MODE PreviousMode, _Out_ POBJECT_TYPE_LIST_INTERNAL *CapturedObjectTypeList)
 Captures a list of object types and converts it to an internal form for use by the kernel. The list is validated before its data is copied.
 
VOID SeReleaseObjectTypeList (_In_ _Post_invalid_ POBJECT_TYPE_LIST_INTERNAL CapturedObjectTypeList, _In_ KPROCESSOR_MODE PreviousMode)
 Releases a buffer list of object types.
 

Macro Definition Documentation

◆ NDEBUG

#define NDEBUG

Definition at line 12 of file objtype.c.

Function Documentation

◆ SeCaptureObjectTypeList()

NTSTATUS SeCaptureObjectTypeList ( _In_reads_opt_(ObjectTypeListLength) POBJECT_TYPE_LIST  ObjectTypeList,
_In_ ULONG  ObjectTypeListLength,
_In_ KPROCESSOR_MODE  PreviousMode,
_Out_ POBJECT_TYPE_LIST_INTERNAL CapturedObjectTypeList 
)

Captures a list of object types and converts it to an internal form for use by the kernel. The list is validated before its data is copied.

Parameters
[in]ObjectTypeListA pointer to a list of object types passed from UM to be captured.
[in]ObjectTypeListLengthThe length size of the list. This length represents the number of object elements in that list.
[in]PreviousModeProcessor access level mode. This has to be set to UserMode as object type access check is not supported in the kernel.
[out]CapturedObjectTypeListA pointer to a returned captured list of object types.
Returns
Returns STATUS_SUCCESS if the list of object types has been captured successfully. STATUS_INVALID_PARAMETER is returned if the caller hasn't supplied a buffer list of object types or the list is invalid. STATUS_INSUFFICIENT_RESOURCES is returned if pool memory allocation for the captured list has failed.

Definition at line 282 of file objtype.c.

287{
289 ULONG ObjectTypeIndex;
290 SIZE_T Size;
291 PGUID ObjectTypeGuid;
292 POBJECT_TYPE_LIST_INTERNAL InternalTypeList;
293
294 PAGED_CODE();
295
296 /* We do not support that in the kernel */
298 {
300 }
301
302 /* No count elements of objects means no captured list for you */
303 if (ObjectTypeListLength == 0)
304 {
305 *CapturedObjectTypeList = NULL;
306 return STATUS_SUCCESS;
307 }
308
309 /* Check if the caller supplied a list since we have the count of elements */
310 if (ObjectTypeList == NULL)
311 {
312 DPRINT1("The caller did not provide a list of object types!\n");
314 }
315
316 /* Validate that list before we copy contents from it */
317 Status = SepValidateObjectTypeList(ObjectTypeList, ObjectTypeListLength);
318 if (!NT_SUCCESS(Status))
319 {
320 DPRINT1("SepValidateObjectTypeList failed (Status 0x%08lx)\n", Status);
321 return Status;
322 }
323
324 /* Allocate a new list */
325 Size = ObjectTypeListLength * sizeof(OBJECT_TYPE_LIST_INTERNAL);
326 InternalTypeList = ExAllocatePoolWithTag(PagedPool, Size, TAG_SEPA);
327 if (InternalTypeList == NULL)
328 {
329 DPRINT1("Failed to allocate pool memory for the object type list!\n");
331 }
332
334 {
335 /* Loop for every object element, data was already probed */
336 for (ObjectTypeIndex = 0;
337 ObjectTypeIndex < ObjectTypeListLength;
338 ObjectTypeIndex++)
339 {
340 /* Copy the object type GUID */
341 ObjectTypeGuid = ObjectTypeList[ObjectTypeIndex].ObjectType;
342 InternalTypeList[ObjectTypeIndex].ObjectTypeGuid = *ObjectTypeGuid;
343
344 /* Copy the object hierarchy level */
345 InternalTypeList[ObjectTypeIndex].Level = ObjectTypeList[ObjectTypeIndex].Level;
346
347 /* Initialize the access check rights */
348 InternalTypeList[ObjectTypeIndex].ObjectAccessRights.RemainingAccessRights = 0;
349 InternalTypeList[ObjectTypeIndex].ObjectAccessRights.GrantedAccessRights = 0;
350 InternalTypeList[ObjectTypeIndex].ObjectAccessRights.DeniedAccessRights = 0;
351 }
352
353 /* Give the captured list to caller */
354 *CapturedObjectTypeList = InternalTypeList;
355 }
357 {
358 ExFreePoolWithTag(InternalTypeList, TAG_SEPA);
359 InternalTypeList = NULL;
361 }
362 _SEH2_END;
363
364 return STATUS_SUCCESS;
365}
#define PAGED_CODE()
LONG NTSTATUS
Definition: precomp.h:26
#define DPRINT1
Definition: precomp.h:8
#define NULL
Definition: types.h:112
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define PagedPool
Definition: env_spec_w32.h:308
#define _SEH2_END
Definition: filesup.c:22
#define _SEH2_TRY
Definition: filesup.c:19
Status
Definition: gdiplustypes.h:25
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1109
#define KernelMode
Definition: asm.h:34
struct _OBJECT_TYPE_LIST_INTERNAL OBJECT_TYPE_LIST_INTERNAL
#define STATUS_NOT_IMPLEMENTED
Definition: ntstatus.h:239
static NTSTATUS SepValidateObjectTypeList(_In_reads_(ObjectTypeListLength) POBJECT_TYPE_LIST ObjectTypeList, _In_ ULONG ObjectTypeListLength)
Validates a list of object types passed from user mode, ensuring the following conditions are met for...
Definition: objtype.c:46
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:165
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:66
#define _SEH2_YIELD(__stmt)
Definition: pseh2_64.h:168
#define STATUS_SUCCESS
Definition: shellext.h:65
#define TAG_SEPA
Definition: tag.h:156
ULONG_PTR SIZE_T
Definition: typedefs.h:80
uint32_t ULONG
Definition: typedefs.h:59
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ DEVPROPTYPE _In_ ULONG Size
Definition: wdfdevice.h:4533
_In_ KPROCESSOR_MODE PreviousMode
Definition: sefuncs.h:103

Referenced by SepAccessCheck(), and SepAccessCheckAndAuditAlarm().

◆ SepGetObjectTypeGuidFromAce()

PGUID SepGetObjectTypeGuidFromAce ( _In_ PACE  Ace,
_In_ BOOLEAN  IsAceDenied 
)

Captures an object type GUID from an object access control entry (ACE).

Parameters
[in]AceA pointer to an access control entry, of which the object type GUID is to be captured from.
[in]IsAceDeniedIf set to TRUE, the function will capture the GUID from a denied object ACE, otherwise from the allowed object ACE.
Returns
Returns a pointer to an object type GUID, otherwise NULL is returned if the target ACE does not have an object type GUID.

Definition at line 180 of file objtype.c.

183{
184 PGUID ObjectTypeGuid = NULL;
185
186 PAGED_CODE();
187
188 /* This Ace must not be NULL */
189 ASSERT(Ace);
190
191 /* Grab the GUID based on the object type ACE header */
192 ObjectTypeGuid = IsAceDenied ? (PGUID)&((PACCESS_DENIED_OBJECT_ACE)Ace)->ObjectType :
193 (PGUID)&((PACCESS_ALLOWED_OBJECT_ACE)Ace)->ObjectType;
194 return ObjectTypeGuid;
195}
GUID * PGUID
Definition: bdasup.h:12
@ Ace
Definition: card.h:12
#define ASSERT(a)
Definition: mode.c:44
ObjectType
Definition: metafile.c:81
struct _ACCESS_ALLOWED_OBJECT_ACE * PACCESS_ALLOWED_OBJECT_ACE

Referenced by SepAnalyzeAcesFromDacl().

◆ SepIsEqualObjectTypeGuid()

static BOOLEAN SepIsEqualObjectTypeGuid ( _In_ CONST GUID Guid1,
_In_ CONST GUID Guid2 
)
static

Compares two object type GUIDs for equality.

Parameters
[in]Guid1A pointer to the first object type GUID.
[in]Guid2A pointer to the second object type GUID.
Returns
Returns TRUE if both GUIDs are equal, FALSE otherwise.

Definition at line 151 of file objtype.c.

154{
155 return RtlCompareMemory(Guid1, Guid2, sizeof(GUID)) == sizeof(GUID);
156}
#define RtlCompareMemory(s1, s2, l)
Definition: env_spec_w32.h:465

Referenced by SepObjectTypeGuidInList().

◆ SepObjectTypeGuidInList()

BOOLEAN SepObjectTypeGuidInList ( _In_reads_(ObjectTypeListLength) POBJECT_TYPE_LIST_INTERNAL  ObjectTypeList,
_In_ ULONG  ObjectTypeListLength,
_In_ PGUID  ObjectTypeGuid,
_Out_ PULONG  ObjectIndex 
)

Searches for an object type GUID if it exists on an object type list.

Parameters
[in]ObjectTypeListA pointer to an object type list.
[in]ObjectTypeListLengthThe length of the list, representing the number of object elements in that list.
[in]ObjectTypeGuidA pointer to an object type GUID to search in the list of interest.
[out]ObjectIndexIf the function found the target GUID, the function returns a pointer to the object index location to this parameter.
Returns
Returns TRUE if the object type GUID of interest exists in the target list, FALSE otherwise.

Definition at line 223 of file objtype.c.

228{
229 ULONG ObjectTypeIndex;
230 GUID ObjectTypeGuidToSearch;
231
232 PAGED_CODE();
233
234 /* Loop over the object elements */
235 for (ObjectTypeIndex = 0;
236 ObjectTypeIndex < ObjectTypeListLength;
237 ObjectTypeIndex++)
238 {
239 /* Is this the object we are searching for? */
240 ObjectTypeGuidToSearch = ObjectTypeList[ObjectTypeIndex].ObjectTypeGuid;
241 if (SepIsEqualObjectTypeGuid(ObjectTypeGuid, &ObjectTypeGuidToSearch))
242 {
243 /* Return the indext of that object to caller */
244 *ObjectIndex = ObjectTypeIndex;
245 return TRUE;
246 }
247 }
248
249 return FALSE;
250}
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
static BOOLEAN SepIsEqualObjectTypeGuid(_In_ CONST GUID *Guid1, _In_ CONST GUID *Guid2)
Compares two object type GUIDs for equality.
Definition: objtype.c:151

Referenced by SepAllowAccessObjectTypeList(), SepAllowAccessObjectTypeResultList(), SepDenyAccessObjectTypeList(), and SepDenyAccessObjectTypeResultList().

◆ SepValidateObjectTypeList()

static NTSTATUS SepValidateObjectTypeList ( _In_reads_(ObjectTypeListLength) POBJECT_TYPE_LIST  ObjectTypeList,
_In_ ULONG  ObjectTypeListLength 
)
static

Validates a list of object types passed from user mode, ensuring the following conditions are met for a valid list:

  • The list must not be too big and it can be read
  • Each object must have a valid level
  • The level hierarchy between objects has to be consistent (e.g. a root cannot have a level 2 subordinate object)
  • The list must have only one root and it must be in the first position
  • Each object type GUID can be read and captured
Parameters
[in]ObjectTypeListA pointer to an object type list of which the elements are being validated.
[in]ObjectTypeListLengthThe length of the list, representing the number of object elements in that list.
Returns
Returns STATUS_SUCCESS if the list has been validated and it contains valid objects. STATUS_INVALID_PARAMETER is returned if the list is not valid. Otherwise a NTSTATUS code is returned.

Definition at line 46 of file objtype.c.

49{
50 PGUID ObjectTypeGuid;
51 ULONG ObjectTypeIndex;
52 USHORT Level, PrevLevel;
54
55 /* Ensure we do not hit an integer overflow */
56 Size = ObjectTypeListLength * sizeof(OBJECT_TYPE_LIST);
57 if (Size == 0)
58 {
59 DPRINT1("The object type list is too big, integer overflow alert!\n");
61 }
62
64 {
65 /* Ensure we can actually read from that list */
66 ProbeForRead(ObjectTypeList, Size, sizeof(ULONG));
67
68 /* Begin looping for each object from the list */
69 for (ObjectTypeIndex = 0;
70 ObjectTypeIndex < ObjectTypeListLength;
71 ObjectTypeIndex++)
72 {
73 /* Get the level of this object and check for validity */
74 Level = ObjectTypeList[ObjectTypeIndex].Level;
76 {
77 DPRINT1("Invalid object level found (level %u, at index %lu)\n", Level, ObjectTypeIndex);
79 }
80
81 /* Are we past the first position in the list? */
82 if (ObjectTypeIndex != 0)
83 {
84 /* Ensure that we do not have two object roots */
86 {
87 DPRINT1("This list has two roots (at index %lu)\n", ObjectTypeIndex);
89 }
90
91 /*
92 * Ensure the current level is consistent with the prior level.
93 * That means, if the previous object is the root (denoted by the
94 * level as ACCESS_OBJECT_GUID aka 0) the current object must
95 * be a child of the parent which is the root (also called a
96 * property set). Whereas a property is a sibling of the
97 * child, the property set.
98 */
99 if (Level > PrevLevel + 1)
100 {
101 DPRINT1("The object levels are not consistent (current level %u, previous level %u, at index %lu)\n",
102 Level, PrevLevel, ObjectTypeIndex);
104 }
105 }
106 else
107 {
108 /* This is the first position so the object must be the root */
110 {
111 DPRINT1("The object is not the root at first index!\n");
113 }
114 }
115
116 /* Get the object type and check that we can read from it */
117 ObjectTypeGuid = ObjectTypeList[ObjectTypeIndex].ObjectType;
118 ProbeForRead(ObjectTypeGuid, sizeof(GUID), sizeof(ULONG));
119
120 /*
121 * Cache the level, we need it to ensure the levels between
122 * the previous and the next object are consistent with each other.
123 */
124 PrevLevel = Level;
125 }
126 }
128 {
130 }
131 _SEH2_END;
132
133 return STATUS_SUCCESS;
134}
VOID NTAPI ProbeForRead(IN CONST VOID *Address, IN SIZE_T Length, IN ULONG Alignment)
Definition: exintrin.c:102
unsigned short USHORT
Definition: pedump.c:61
_IRQL_requires_same_ typedef _In_ ULONG _In_ UCHAR Level
Definition: wmitypes.h:56
#define ACCESS_MAX_LEVEL
Definition: setypes.h:865
struct _OBJECT_TYPE_LIST OBJECT_TYPE_LIST
#define ACCESS_OBJECT_GUID
Definition: setypes.h:862

Referenced by SeCaptureObjectTypeList().

◆ SeReleaseObjectTypeList()

VOID SeReleaseObjectTypeList ( _In_ _Post_invalid_ POBJECT_TYPE_LIST_INTERNAL  CapturedObjectTypeList,
_In_ KPROCESSOR_MODE  PreviousMode 
)

Releases a buffer list of object types.

Parameters
[in]CapturedObjectTypeListA list of object types to free.
[in]PreviousModeProcessor access level mode.

Definition at line 378 of file objtype.c.

381{
382 PAGED_CODE();
383
384 if ((PreviousMode != KernelMode) && (CapturedObjectTypeList != NULL))
385 {
386 ExFreePoolWithTag(CapturedObjectTypeList, TAG_SEPA);
387 }
388}

Referenced by SepAccessCheck(), and SepAccessCheckAndAuditAlarm().