Author: ion Date: Fri May 11 22:15:13 2007 New Revision: 26701
URL: http://svn.reactos.org/svn/reactos?rev=26701&view=rev Log: - Add missing ACE structures to ntifs.h. - Add missing SeLengthSid to ntifs.h. - Implement CmpHiveRootSecurityDescriptor and use it in CmpInitializeSystemHive and CmInitSystem1 to properly secure system-created hives. - Implement CmpInitializeHardwareConfiguration and call it. Its job is to populate the hardware hive, but FreeLDR already does this, so it doesn't do much at the moment.
Added: trunk/reactos/ntoskrnl/config/cmse.c Modified: trunk/reactos/include/ddk/ntifs.h trunk/reactos/ntoskrnl/cm/cm.h trunk/reactos/ntoskrnl/cm/registry.c trunk/reactos/ntoskrnl/config/cmconfig.c trunk/reactos/ntoskrnl/ntoskrnl.rbuild
Modified: trunk/reactos/include/ddk/ntifs.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/include/ddk/ntifs.h?rev=267... ============================================================================== --- trunk/reactos/include/ddk/ntifs.h (original) +++ trunk/reactos/include/ddk/ntifs.h Fri May 11 22:15:13 2007 @@ -1724,6 +1724,41 @@ USHORT AceSize; } ACE_HEADER, *PACE_HEADER;
+typedef struct _ACCESS_ALLOWED_ACE +{ + ACE_HEADER Header; + ACCESS_MASK Mask; + ULONG SidStart; +} ACCESS_ALLOWED_ACE, *PACCESS_ALLOWED_ACE; + +typedef struct _ACCESS_DENIED_ACE +{ + ACE_HEADER Header; + ACCESS_MASK Mask; + ULONG SidStart; +} ACCESS_DENIED_ACE, *PACCESS_DENIED_ACE; + +typedef struct _SYSTEM_AUDIT_ACE +{ + ACE_HEADER Header; + ACCESS_MASK Mask; + ULONG SidStart; +} SYSTEM_AUDIT_ACE, *PSYSTEM_AUDIT_ACE; + +typedef struct _SYSTEM_ALARM_ACE +{ + ACE_HEADER Header; + ACCESS_MASK Mask; + ULONG SidStart; +} SYSTEM_ALARM_ACE, *PSYSTEM_ALARM_ACE; + +typedef struct _SYSTEM_MANDATORY_LABEL_ACE +{ + ACE_HEADER Header; + ACCESS_MASK Mask; + ULONG SidStart; +} SYSTEM_MANDATORY_LABEL_ACE, *PSYSTEM_MANDATORY_LABEL_ACE; + typedef struct _TUNNEL { FAST_MUTEX Mutex; PRTL_SPLAY_LINKS Cache; @@ -4305,6 +4340,10 @@ );
#endif /* (VER_PRODUCTBUILD >= 2195) */ + + +#define SeLengthSid( Sid ) \ + (8 + (4 * ((SID *)Sid)->SubAuthorityCount))
#define SeDeleteClientSecurity(C) { \ if (SeTokenType((C)->ClientToken) == TokenPrimary) { \
Modified: trunk/reactos/ntoskrnl/cm/cm.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/cm/cm.h?rev=26701&... ============================================================================== --- trunk/reactos/ntoskrnl/cm/cm.h (original) +++ trunk/reactos/ntoskrnl/cm/cm.h Fri May 11 22:15:13 2007 @@ -418,6 +418,66 @@ PHHIVE RegistryHive, ULONG FileType);
+VOID +CmiCheckKey(BOOLEAN Verbose, + HANDLE Key); + +BOOLEAN +INIT_FUNCTION +CmImportSystemHive(PCHAR ChunkBase, + ULONG ChunkSize, + OUT PEREGISTRY_HIVE *RegistryHive); + +BOOLEAN +INIT_FUNCTION +CmImportHardwareHive(PCHAR ChunkBase, + ULONG ChunkSize, + OUT PEREGISTRY_HIVE *RegistryHive); + +NTSTATUS +NTAPI +CmpSetSystemValues(IN PLOADER_PARAMETER_BLOCK LoaderBlock); + +NTSTATUS +NTAPI +CmpCreateControlSet(IN PLOADER_PARAMETER_BLOCK LoaderBlock); + +NTSTATUS +NTAPI +CmpInitializeMachineDependentConfiguration(IN PLOADER_PARAMETER_BLOCK LoaderBlock); + +NTSTATUS +NTAPI +CmpInitializeHive(PEREGISTRY_HIVE *RegistryHive, + ULONG OperationType, + ULONG HiveFlags, + ULONG FileType, + PVOID HiveData OPTIONAL, + HANDLE Primary, + HANDLE Log, + HANDLE External, + PUNICODE_STRING FileName OPTIONAL, + ULONG CheckFlags); + +USHORT +NTAPI +CmpCopyName(IN PHHIVE Hive, + IN PWCHAR Destination, + IN PUNICODE_STRING Source); + +USHORT +NTAPI +CmpNameSize(IN PHHIVE Hive, + IN PUNICODE_STRING Name); + +NTSTATUS +NTAPI +CmpInitializeHardwareConfiguration(IN PLOADER_PARAMETER_BLOCK LoaderBlock); + +PSECURITY_DESCRIPTOR +NTAPI +CmpHiveRootSecurityDescriptor(VOID); + #if 0 static __inline PVOID xHvGetCell(char *file, int line, PHHIVE Hive, HCELL_INDEX Cell) {
Modified: trunk/reactos/ntoskrnl/cm/registry.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/cm/registry.c?rev=... ============================================================================== --- trunk/reactos/ntoskrnl/cm/registry.c (original) +++ trunk/reactos/ntoskrnl/cm/registry.c Fri May 11 22:15:13 2007 @@ -48,60 +48,6 @@
static GENERIC_MAPPING CmiKeyMapping = {KEY_READ, KEY_WRITE, KEY_EXECUTE, KEY_ALL_ACCESS}; - - - -VOID -CmiCheckKey(BOOLEAN Verbose, - HANDLE Key); - -BOOLEAN -INIT_FUNCTION -CmImportSystemHive(PCHAR ChunkBase, - ULONG ChunkSize, - OUT PEREGISTRY_HIVE *RegistryHive); - -BOOLEAN -INIT_FUNCTION -CmImportHardwareHive(PCHAR ChunkBase, - ULONG ChunkSize, - OUT PEREGISTRY_HIVE *RegistryHive); - -NTSTATUS -NTAPI -CmpSetSystemValues(IN PLOADER_PARAMETER_BLOCK LoaderBlock); - -NTSTATUS -NTAPI -CmpCreateControlSet(IN PLOADER_PARAMETER_BLOCK LoaderBlock); - -NTSTATUS -NTAPI -CmpInitializeMachineDependentConfiguration(IN PLOADER_PARAMETER_BLOCK LoaderBlock); - -NTSTATUS -NTAPI -CmpInitializeHive(PEREGISTRY_HIVE *RegistryHive, - ULONG OperationType, - ULONG HiveFlags, - ULONG FileType, - PVOID HiveData OPTIONAL, - HANDLE Primary, - HANDLE Log, - HANDLE External, - PUNICODE_STRING FileName OPTIONAL, - ULONG CheckFlags); - -USHORT -NTAPI -CmpCopyName(IN PHHIVE Hive, - IN PWCHAR Destination, - IN PUNICODE_STRING Source); - -USHORT -NTAPI -CmpNameSize(IN PHHIVE Hive, - IN PUNICODE_STRING Name);
static VOID STDCALL CmiHiveSyncDpcRoutine(PKDPC Dpc, @@ -253,6 +199,7 @@ UNICODE_STRING KeyName; PEREGISTRY_HIVE SystemHive; UNICODE_STRING HiveName = RTL_CONSTANT_STRING(L"SYSTEM"); + PSECURITY_DESCRIPTOR SecurityDescriptor; PAGED_CODE();
/* Setup the ansi string */ @@ -309,9 +256,16 @@ Allocate = TRUE; }
+ /* Create the default security descriptor */ + SecurityDescriptor = CmpHiveRootSecurityDescriptor(); + /* Attach it to the system key */ RtlInitUnicodeString(&KeyName, REG_SYSTEM_KEY_NAME); - Status = CmpLinkHiveToMaster(&KeyName, NULL, SystemHive, Allocate, NULL); + Status = CmpLinkHiveToMaster(&KeyName, + NULL, + SystemHive, + Allocate, + SecurityDescriptor); if (!NT_SUCCESS(Status)) return FALSE;
/* Success! */ @@ -495,6 +449,7 @@ PEREGISTRY_HIVE HardwareHive; PVOID BaseAddress; ULONG Length; + PSECURITY_DESCRIPTOR SecurityDescriptor; PAGED_CODE();
/* Initialize the hive list */ @@ -559,13 +514,16 @@ KEBUGCHECKEX(CONFIG_INITIALIZATION_FAILED, 1, 3, 0, 0); }
+ /* Create the default security descriptor */ + SecurityDescriptor = CmpHiveRootSecurityDescriptor(); + /* Create '\Registry\Machine' key. */ RtlInitUnicodeString(&KeyName, L"\REGISTRY\MACHINE"); InitializeObjectAttributes(&ObjectAttributes, &KeyName, OBJ_CASE_INSENSITIVE, NULL, - NULL); + SecurityDescriptor); Status = NtCreateKey(&KeyHandle, KEY_READ | KEY_WRITE, &ObjectAttributes, @@ -588,7 +546,7 @@ &KeyName, OBJ_CASE_INSENSITIVE, NULL, - NULL); + SecurityDescriptor); Status = NtCreateKey(&KeyHandle, KEY_READ | KEY_WRITE, &ObjectAttributes, @@ -642,11 +600,23 @@
/* Attach it to the machine key */ RtlInitUnicodeString(&KeyName, REG_HARDWARE_KEY_NAME); - Status = CmpLinkHiveToMaster(&KeyName, NULL, HardwareHive, FALSE, NULL); + Status = CmpLinkHiveToMaster(&KeyName, + NULL, + HardwareHive, + FALSE, + SecurityDescriptor); if (!NT_SUCCESS(Status)) { /* Bugcheck */ KEBUGCHECKEX(CONFIG_INITIALIZATION_FAILED, 1, 12, Status, 0); + } + + /* Fill out the Hardware key with the ARC Data from the Loader */ + Status = CmpInitializeHardwareConfiguration(KeLoaderBlock); + if (!NT_SUCCESS(Status)) + { + /* Bugcheck */ + KEBUGCHECKEX(CONFIG_INITIALIZATION_FAILED, 1, 13, Status, 0); }
/* Initialize machine-dependent information into the registry */
Modified: trunk/reactos/ntoskrnl/config/cmconfig.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/config/cmconfig.c?... ============================================================================== --- trunk/reactos/ntoskrnl/config/cmconfig.c (original) +++ trunk/reactos/ntoskrnl/config/cmconfig.c Fri May 11 22:15:13 2007 @@ -194,3 +194,81 @@ return Status; }
+NTSTATUS +NTAPI +CmpInitializeHardwareConfiguration(IN PLOADER_PARAMETER_BLOCK LoaderBlock) +{ + NTSTATUS Status; + OBJECT_ATTRIBUTES ObjectAttributes; + HANDLE KeyHandle; + ULONG Disposition; + UNICODE_STRING KeyName; + + /* Setup the key name */ + RtlInitUnicodeString(&KeyName, + L"\Registry\Machine\Hardware\DeviceMap"); + InitializeObjectAttributes(&ObjectAttributes, + &KeyName, + OBJ_CASE_INSENSITIVE, + NULL, + NULL); + + /* Create the device map key */ + Status = NtCreateKey(&KeyHandle, + KEY_READ | KEY_WRITE, + &ObjectAttributes, + 0, + NULL, + 0, + &Disposition); + if (!NT_SUCCESS(Status)) return Status; + NtClose(KeyHandle); + + /* Nobody should've created this key yet! */ + //ASSERT(Disposition == REG_CREATED_NEW_KEY); + + /* Setup the key name */ + RtlInitUnicodeString(&KeyName, + L"\Registry\Machine\Hardware\Description"); + InitializeObjectAttributes(&ObjectAttributes, + &KeyName, + OBJ_CASE_INSENSITIVE, + NULL, + NULL); + + /* Create the description key */ + Status = NtCreateKey(&KeyHandle, + KEY_READ | KEY_WRITE, + &ObjectAttributes, + 0, + NULL, + 0, + &Disposition); + if (!NT_SUCCESS(Status)) return Status; + + /* Nobody should've created this key yet! */ + //ASSERT(Disposition == REG_CREATED_NEW_KEY); + + /* Allocate the configuration data buffer */ + CmpConfigurationData = ExAllocatePoolWithTag(PagedPool, + CmpConfigurationAreaSize, + TAG_CM); + if (!CmpConfigurationData) return STATUS_INSUFFICIENT_RESOURCES; + + /* Check if we got anything from NTLDR */ + if (LoaderBlock->ConfigurationRoot) + { + ASSERTMSG("NTLDR ARC Hardware Tree Not Supported!\n", FALSE); + } + else + { + /* Nothing else to do */ + Status = STATUS_SUCCESS; + } + + /* Close our handle, free the buffer and return status */ + ExFreePool(CmpConfigurationData); + NtClose(KeyHandle); + return Status; +} +
Added: trunk/reactos/ntoskrnl/config/cmse.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/config/cmse.c?rev=... ============================================================================== --- trunk/reactos/ntoskrnl/config/cmse.c (added) +++ trunk/reactos/ntoskrnl/config/cmse.c Fri May 11 22:15:13 2007 @@ -1,0 +1,138 @@ +/* + * PROJECT: ReactOS Kernel + * LICENSE: GPL - See COPYING in the top level directory + * FILE: ntoskrnl/config/cmse.c + * PURPOSE: Configuration Manager - Security Subsystem Interface + * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org) + */ + +/* INCLUDES ******************************************************************/ + +#include "ntoskrnl.h" +#include "cm.h" +#define NDEBUG +#include "debug.h" + +/* GLOBALS *******************************************************************/ + +/* FUNCTIONS *****************************************************************/ + +PSECURITY_DESCRIPTOR +NTAPI +CmpHiveRootSecurityDescriptor(VOID) +{ + NTSTATUS Status; + PSECURITY_DESCRIPTOR SecurityDescriptor; + PACL Acl, AclCopy; + PSID Sid[3]; + SID_IDENTIFIER_AUTHORITY WorldAuthority = {SECURITY_WORLD_SID_AUTHORITY}; + SID_IDENTIFIER_AUTHORITY NtAuthority = {SECURITY_NT_AUTHORITY}; + ULONG AceLength, AclLength, SidLength; + PACE_HEADER AceHeader; + ULONG i; + PAGED_CODE(); + + /* Phase 1: Allocate SIDs */ + SidLength = RtlLengthRequiredSid(1); + Sid[0] = ExAllocatePoolWithTag(PagedPool, SidLength, TAG_CM); + Sid[1] = ExAllocatePoolWithTag(PagedPool, SidLength, TAG_CM); + Sid[2] = ExAllocatePoolWithTag(PagedPool, SidLength, TAG_CM); + SidLength = RtlLengthRequiredSid(2); + Sid[3] = ExAllocatePoolWithTag(PagedPool, SidLength, TAG_CM); + + /* Make sure all SIDs were allocated */ + if (!(Sid[0]) || !(Sid[1]) || !(Sid[2]) || !(Sid[3])) + { + /* Bugcheck */ + KEBUGCHECKEX(REGISTRY_ERROR, 2, 1, 0, 0); + } + + /* Phase 2: Initialize all SIDs */ + Status = RtlInitializeSid(Sid[0], &WorldAuthority, 1); + Status |= RtlInitializeSid(Sid[1], &NtAuthority, 1); + Status |= RtlInitializeSid(Sid[2], &NtAuthority, 1); + Status |= RtlInitializeSid(Sid[3], &NtAuthority, 2); + if (!NT_SUCCESS(Status)) KEBUGCHECKEX(REGISTRY_ERROR, 2, 2, 0, 0); + + /* Phase 2: Setup SID Sub Authorities */ + *RtlSubAuthoritySid(Sid[0], 0) = SECURITY_WORLD_RID; + *RtlSubAuthoritySid(Sid[1], 0) = SECURITY_RESTRICTED_CODE_RID; + *RtlSubAuthoritySid(Sid[2], 0) = SECURITY_LOCAL_SYSTEM_RID; + *RtlSubAuthoritySid(Sid[3], 0) = SECURITY_BUILTIN_DOMAIN_RID; + *RtlSubAuthoritySid(Sid[3], 1) = DOMAIN_ALIAS_RID_ADMINS; + + /* Make sure all SIDs are valid */ + ASSERT(RtlValidSid(Sid[0])); + ASSERT(RtlValidSid(Sid[1])); + ASSERT(RtlValidSid(Sid[2])); + ASSERT(RtlValidSid(Sid[3])); + + /* Phase 3: Calculate ACL Length */ + AclLength = sizeof(ACL); + for (i = 0; i < 4; i++) + { + /* This is what MSDN says to do */ + AceLength = FIELD_OFFSET(ACCESS_ALLOWED_ACE, SidStart); + AceLength += SeLengthSid(Sid[i]); + AclLength += AceLength; + } + + /* Phase 3: Allocate the ACL */ + Acl = ExAllocatePoolWithTag(PagedPool, AclLength, TAG_CM); + if (!Acl) KEBUGCHECKEX(REGISTRY_ERROR, 2, 3, 0, 0); + + /* Phase 4: Create the ACL */ + Status = RtlCreateAcl(Acl, AclLength, ACL_REVISION); + if (!NT_SUCCESS(Status)) KEBUGCHECKEX(REGISTRY_ERROR, 2, 4, Status, 0); + + /* Phase 5: Build the ACL */ + Status = RtlAddAccessAllowedAce(Acl, ACL_REVISION, KEY_ALL_ACCESS, Sid[0]); + Status |= RtlAddAccessAllowedAce(Acl, ACL_REVISION, KEY_ALL_ACCESS, Sid[1]); + Status |= RtlAddAccessAllowedAce(Acl, ACL_REVISION, KEY_READ, Sid[2]); + Status |= RtlAddAccessAllowedAce(Acl, ACL_REVISION, KEY_READ, Sid[3]); + if (!NT_SUCCESS(Status)) KEBUGCHECKEX(REGISTRY_ERROR, 2, 5, Status, 0); + + /* Phase 5: Make the ACEs inheritable */ + Status = RtlGetAce(Acl, 0,( PVOID*)&AceHeader); + ASSERT(NT_SUCCESS(Status)); + AceHeader->AceFlags |= CONTAINER_INHERIT_ACE; + Status = RtlGetAce(Acl, 1, (PVOID*)&AceHeader); + ASSERT(NT_SUCCESS(Status)); + AceHeader->AceFlags |= CONTAINER_INHERIT_ACE; + Status = RtlGetAce(Acl, 2, (PVOID*)&AceHeader); + ASSERT(NT_SUCCESS(Status)); + AceHeader->AceFlags |= CONTAINER_INHERIT_ACE; + Status = RtlGetAce(Acl, 3, (PVOID*)&AceHeader); + ASSERT(NT_SUCCESS(Status)); + AceHeader->AceFlags |= CONTAINER_INHERIT_ACE; + + /* Phase 6: Allocate the security descriptor and make space for the ACL */ + SecurityDescriptor = ExAllocatePoolWithTag(PagedPool, + sizeof(SECURITY_DESCRIPTOR) + + AclLength, + TAG_CM); + if (!SecurityDescriptor) KEBUGCHECKEX(REGISTRY_ERROR, 2, 6, 0, 0); + + /* Phase 6: Make a copy of the ACL */ + AclCopy = (PACL)((PISECURITY_DESCRIPTOR)SecurityDescriptor + 1); + RtlCopyMemory(AclCopy, Acl, AclLength); + + /* Phase 7: Create the security descriptor */ + Status = RtlCreateSecurityDescriptor(SecurityDescriptor, + SECURITY_DESCRIPTOR_REVISION); + if (!NT_SUCCESS(Status)) KEBUGCHECKEX(REGISTRY_ERROR, 2, 7, Status, 0); + + /* Phase 8: Set the ACL as a DACL */ + Status = RtlSetDaclSecurityDescriptor(SecurityDescriptor, + TRUE, + AclCopy, + FALSE); + if (!NT_SUCCESS(Status)) KEBUGCHECKEX(REGISTRY_ERROR, 2, 8, Status, 0); + + /* Free the SIDs and original ACL */ + for (i = 0; i < 4; i++) ExFreePool(Sid[i]); + ExFreePool(Acl); + + /* Return the security descriptor */ + return SecurityDescriptor; +}
Modified: trunk/reactos/ntoskrnl/ntoskrnl.rbuild URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ntoskrnl.rbuild?re... ============================================================================== --- trunk/reactos/ntoskrnl/ntoskrnl.rbuild (original) +++ trunk/reactos/ntoskrnl/ntoskrnl.rbuild Fri May 11 22:15:13 2007 @@ -98,6 +98,7 @@ <file>cmmapvw.c</file> <file>cmname.c</file> <file>cmparse.c</file> + <file>cmse.c</file> <file>cmsecach.c</file> <file>cmsysini.c</file> <file>cmvalue.c</file>