Author: ion Date: Thu Sep 24 02:40:30 2015 New Revision: 69340
URL: http://svn.reactos.org/svn/reactos?rev=69340&view=rev Log: [NDK]: Add OB_FLAG_KERNEL_EXCLUSIVE and OBJ_KERNEL_EXCLUSIVE flags [NTOSKRNL]: Add a helper function such that user-mode cannot pass certain kernel-only object attributes to ObOpenObjectByPointer. [NTOSKRNL]: Make \Device\PhysicalMemory OBJ_KERNEL_EXCLUSIVE [NTOSKRNL]: Deny access to user-mode when opening a handle to an object with OBJ_KERNEL_EXCLUSIVE [NTOSKRNL]: Fix NtOpenProcess, NtOpenThread, NtOpenThreadTokenEx, NtOpenProcessTokenEx to use the helper function. Should fix Rtl using OBJ_KERNEL_HANDLE in user-mode. Thanks to ThFabba for finding out these bugs, and the hbelusca for adding a missing check to NtOpenProcessTokenEx.
Modified: trunk/reactos/include/ndk/obtypes.h trunk/reactos/ntoskrnl/include/internal/ob_x.h trunk/reactos/ntoskrnl/mm/section.c trunk/reactos/ntoskrnl/ob/obhandle.c trunk/reactos/ntoskrnl/ob/oblife.c trunk/reactos/ntoskrnl/ob/obname.c trunk/reactos/ntoskrnl/ps/process.c trunk/reactos/ntoskrnl/ps/security.c trunk/reactos/ntoskrnl/ps/thread.c trunk/reactos/ntoskrnl/se/token.c
Modified: trunk/reactos/include/ndk/obtypes.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/include/ndk/obtypes.h?rev=6... ============================================================================== --- trunk/reactos/include/ndk/obtypes.h [iso-8859-1] (original) +++ trunk/reactos/include/ndk/obtypes.h [iso-8859-1] Thu Sep 24 02:40:30 2015 @@ -86,6 +86,12 @@ #else
// +// Undocumented Attribute for Kernel-Only Access +// +#define OBJ_KERNEL_EXCLUSIVE 0x00010000L +#define OBJ_VALID_KERNEL_ATTRIBUTES (OBJ_VALID_ATTRIBUTES | \ + OBJ_KERNEL_EXCLUSIVE) +// // Object Flags // #define OB_FLAG_CREATE_INFO 0x01 @@ -96,6 +102,11 @@ #define OB_FLAG_SECURITY 0x20 #define OB_FLAG_SINGLE_PROCESS 0x40 #define OB_FLAG_DEFER_DELETE 0x80 + +// +// Object Flags encoded in "QueryReferences" field +// +#define OB_FLAG_KERNEL_EXCLUSIVE 0x40000000
#define OBJECT_TO_OBJECT_HEADER(o) \ CONTAINING_RECORD((o), OBJECT_HEADER, Body)
Modified: trunk/reactos/ntoskrnl/include/internal/ob_x.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/include/internal/o... ============================================================================== --- trunk/reactos/ntoskrnl/include/internal/ob_x.h [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/include/internal/ob_x.h [iso-8859-1] Thu Sep 24 02:40:30 2015 @@ -16,6 +16,24 @@ #define OBP_LOCK_STATE_INITIALIZED 0xFFFF1234
#define OBP_NAME_LOOKASIDE_MAX_SIZE 248 + +FORCEINLINE +ULONG +ObpValidateAttributes(IN ULONG Attributes, + IN KPROCESSOR_MODE PreviousMode) +{ + if (PreviousMode == KernelMode) + { + /* For kernel, allow any valid attributes */ + return Attributes & OBJ_VALID_KERNEL_ATTRIBUTES; + } + else + { + /* For user, mask out kernel-only attributes */ + return (Attributes & OBJ_VALID_ATTRIBUTES) & + ~(OBJ_KERNEL_HANDLE); + } +}
FORCEINLINE ULONG
Modified: trunk/reactos/ntoskrnl/mm/section.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/section.c?rev=6... ============================================================================== --- trunk/reactos/ntoskrnl/mm/section.c [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/mm/section.c [iso-8859-1] Thu Sep 24 02:40:30 2015 @@ -2756,7 +2756,7 @@ SectionSize.QuadPart = 0xFFFFFFFF; InitializeObjectAttributes(&Obj, &Name, - OBJ_PERMANENT, + OBJ_PERMANENT | OBJ_KERNEL_EXCLUSIVE, NULL, NULL); Status = MmCreateSection((PVOID)&PhysSection,
Modified: trunk/reactos/ntoskrnl/ob/obhandle.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ob/obhandle.c?rev=... ============================================================================== --- trunk/reactos/ntoskrnl/ob/obhandle.c [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/ob/obhandle.c [iso-8859-1] Thu Sep 24 02:40:30 2015 @@ -807,6 +807,7 @@ KIRQL CalloutIrql; KPROCESSOR_MODE ProbeMode; ULONG Total; + POBJECT_HEADER_NAME_INFO NameInfo; PAGED_CODE();
/* Get the object header and type */ @@ -868,6 +869,16 @@ (OBJECT_HEADER_TO_EXCLUSIVE_PROCESS(ObjectHeader))) { /* Caller didn't want exclusive access, but the object is exclusive */ + Status = STATUS_ACCESS_DENIED; + goto Quickie; + } + + /* Check for exclusive kernel object */ + NameInfo = OBJECT_HEADER_TO_NAME_INFO(ObjectHeader); + if ((NameInfo) && (NameInfo->QueryReferences & OB_FLAG_KERNEL_EXCLUSIVE) && + (ProbeMode != KernelMode)) + { + /* Caller is not kernel, but the object is kernel exclusive */ Status = STATUS_ACCESS_DENIED; goto Quickie; }
Modified: trunk/reactos/ntoskrnl/ob/oblife.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ob/oblife.c?rev=69... ============================================================================== --- trunk/reactos/ntoskrnl/ob/oblife.c [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/ob/oblife.c [iso-8859-1] Thu Sep 24 02:40:30 2015 @@ -731,10 +731,10 @@ /* Check if this is a call with the special protection flag */ if ((PreviousMode == KernelMode) && (ObjectCreateInfo) && - (ObjectCreateInfo->Attributes & 0x10000)) + (ObjectCreateInfo->Attributes & OBJ_KERNEL_EXCLUSIVE)) { /* Set flag which will make the object protected from user-mode */ - NameInfo->QueryReferences |= 0x40000000; + NameInfo->QueryReferences |= OB_FLAG_KERNEL_EXCLUSIVE; }
/* Set the header pointer */
Modified: trunk/reactos/ntoskrnl/ob/obname.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ob/obname.c?rev=69... ============================================================================== --- trunk/reactos/ntoskrnl/ob/obname.c [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/ob/obname.c [iso-8859-1] Thu Sep 24 02:40:30 2015 @@ -261,14 +261,14 @@ ObpDeleteSymbolicLinkName(Object); }
- /* Check if the magic protection flag is set */ + /* Check if the kernel exclusive is set */ ObjectNameInfo = OBJECT_HEADER_TO_NAME_INFO(ObjectHeader); if ((ObjectNameInfo) && - (ObjectNameInfo->QueryReferences & 0x40000000)) + (ObjectNameInfo->QueryReferences & OB_FLAG_KERNEL_EXCLUSIVE)) { /* Remove protection flag */ InterlockedExchangeAdd((PLONG)&ObjectNameInfo->QueryReferences, - -0x40000000); + -OB_FLAG_KERNEL_EXCLUSIVE); }
/* Get the directory */
Modified: trunk/reactos/ntoskrnl/ps/process.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ps/process.c?rev=6... ============================================================================== --- trunk/reactos/ntoskrnl/ps/process.c [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/ps/process.c [iso-8859-1] Thu Sep 24 02:40:30 2015 @@ -1483,7 +1483,9 @@ sizeof(OBJECT_ATTRIBUTES), sizeof(ULONG)); HasObjectName = (ObjectAttributes->ObjectName != NULL); - Attributes = ObjectAttributes->Attributes; + + /* Validate user attributes */ + Attributes = ObpValidateAttributes(ObjectAttributes->Attributes, PreviousMode); } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { @@ -1496,7 +1498,9 @@ { /* Otherwise just get the data directly */ HasObjectName = (ObjectAttributes->ObjectName != NULL); - Attributes = ObjectAttributes->Attributes; + + /* Still have to sanitize attributes */ + Attributes = ObpValidateAttributes(ObjectAttributes->Attributes, PreviousMode); }
/* Can't pass both, fail */
Modified: trunk/reactos/ntoskrnl/ps/security.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ps/security.c?rev=... ============================================================================== --- trunk/reactos/ntoskrnl/ps/security.c [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/ps/security.c [iso-8859-1] Thu Sep 24 02:40:30 2015 @@ -370,6 +370,9 @@ } _SEH2_END; } + + /* Validate object attributes */ + HandleAttributes = ObpValidateAttributes(HandleAttributes, PreviousMode);
/* Open the process token */ Status = PsOpenTokenOfProcess(ProcessHandle, &Token);
Modified: trunk/reactos/ntoskrnl/ps/thread.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ps/thread.c?rev=69... ============================================================================== --- trunk/reactos/ntoskrnl/ps/thread.c [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/ps/thread.c [iso-8859-1] Thu Sep 24 02:40:30 2015 @@ -1054,7 +1054,9 @@ sizeof(OBJECT_ATTRIBUTES), sizeof(ULONG)); HasObjectName = (ObjectAttributes->ObjectName != NULL); - Attributes = ObjectAttributes->Attributes; + + /* Validate user attributes */ + Attributes = ObpValidateAttributes(ObjectAttributes->Attributes, PreviousMode); } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { @@ -1067,7 +1069,9 @@ { /* Otherwise just get the data directly */ HasObjectName = (ObjectAttributes->ObjectName != NULL); - Attributes = ObjectAttributes->Attributes; + + /* Still have to sanitize attributes */ + Attributes = ObpValidateAttributes(ObjectAttributes->Attributes, PreviousMode); }
/* Can't pass both, fail */
Modified: trunk/reactos/ntoskrnl/se/token.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/se/token.c?rev=693... ============================================================================== --- trunk/reactos/ntoskrnl/se/token.c [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/se/token.c [iso-8859-1] Thu Sep 24 02:40:30 2015 @@ -2952,10 +2952,12 @@ _SEH2_END; }
+ /* Validate object attributes */ + HandleAttributes = ObpValidateAttributes(HandleAttributes, PreviousMode); + /* * At first open the thread token for information access and verify - * that the token associated with thread is valid. - */ + * that the token associated with thread is valid. */
Status = ObReferenceObjectByHandle(ThreadHandle, THREAD_QUERY_INFORMATION, PsThreadType, PreviousMode, (PVOID*)&Thread,