]> git.saurik.com Git - apple/xnu.git/blobdiff - osfmk/arm64/arm_vm_init.c
xnu-7195.101.1.tar.gz
[apple/xnu.git] / osfmk / arm64 / arm_vm_init.c
index 10c0a455eb55ada3fd983b298975e379acf1beb7..728ee8c27bf31f60189373796dc9c9f16508114c 100644 (file)
@@ -258,7 +258,9 @@ SECURITY_READ_ONLY_LATE(vm_offset_t)          segLINKB;
 SECURITY_READ_ONLY_LATE(static unsigned long) segSizeLINK;
 
 SECURITY_READ_ONLY_LATE(static vm_offset_t)   segKLDB;
-SECURITY_READ_ONLY_LATE(static unsigned long) segSizeKLD;
+SECURITY_READ_ONLY_LATE(unsigned long)        segSizeKLD;
+SECURITY_READ_ONLY_LATE(static vm_offset_t)   segKLDDATAB;
+SECURITY_READ_ONLY_LATE(static unsigned long) segSizeKLDDATA;
 SECURITY_READ_ONLY_LATE(vm_offset_t)          segLASTB;
 SECURITY_READ_ONLY_LATE(unsigned long)        segSizeLAST;
 SECURITY_READ_ONLY_LATE(vm_offset_t)          segLASTDATACONSTB;
@@ -1338,6 +1340,7 @@ noAuxKC:
        arm_vm_page_granular_RNX((vm_offset_t)&excepstack_high_guard, PAGE_MAX_SIZE, 0);
 
        arm_vm_page_granular_ROX(segKLDB, segSizeKLD, ARM64_GRANULE_ALLOW_BLOCK | ARM64_GRANULE_ALLOW_HINT);
+       arm_vm_page_granular_RNX(segKLDDATAB, segSizeKLDDATA, ARM64_GRANULE_ALLOW_BLOCK | ARM64_GRANULE_ALLOW_HINT);
        arm_vm_page_granular_RWNX(segLINKB, segSizeLINK, ARM64_GRANULE_ALLOW_BLOCK | ARM64_GRANULE_ALLOW_HINT);
        arm_vm_page_granular_RWNX(segPLKLINKEDITB, segSizePLKLINKEDIT, ARM64_GRANULE_ALLOW_BLOCK | ARM64_GRANULE_ALLOW_HINT); // Coalesced kext LINKEDIT segment
        arm_vm_page_granular_ROX(segLASTB, segSizeLAST, ARM64_GRANULE_ALLOW_BLOCK); // __LAST may be empty, but we cannot assume this
@@ -1433,8 +1436,12 @@ arm_vm_physmap_init(boot_args *args)
        // Slid region between gPhysBase and beginning of protected text
        arm_vm_physmap_slide(temp_ptov_table, gVirtBase, segLOWEST - gVirtBase, AP_RWNA, 0);
 
-       // kext bootstrap segment
+       // kext bootstrap segments
+#if !defined(KERNEL_INTEGRITY_KTRR) && !defined(KERNEL_INTEGRITY_CTRR)
+       /* __KLD,__text is covered by the rorgn */
        arm_vm_physmap_slide(temp_ptov_table, segKLDB, segSizeKLD, AP_RONA, 0);
+#endif
+       arm_vm_physmap_slide(temp_ptov_table, segKLDDATAB, segSizeKLDDATA, AP_RONA, 0);
 
        // Early-boot data
        arm_vm_physmap_slide(temp_ptov_table, segBOOTDATAB, segSizeBOOTDATA, AP_RONA, 0);
@@ -1551,10 +1558,17 @@ arm_vm_prot_finalize(boot_args * args __unused)
 #endif /* __ARM_KERNEL_PROTECT__ */
 
 #if XNU_MONITOR
+#if !defined(KERNEL_INTEGRITY_KTRR) && !defined(KERNEL_INTEGRITY_CTRR)
+       /* __KLD,__text is covered by the rorgn */
        for (vm_offset_t va = segKLDB; va < (segKLDB + segSizeKLD); va += ARM_PGBYTES) {
                pt_entry_t *pte = arm_kva_to_pte(va);
                *pte = ARM_PTE_EMPTY;
        }
+#endif
+       for (vm_offset_t va = segKLDDATAB; va < (segKLDDATAB + segSizeKLDDATA); va += ARM_PGBYTES) {
+               pt_entry_t *pte = arm_kva_to_pte(va);
+               *pte = ARM_PTE_EMPTY;
+       }
        /* Clear the original stack mappings; these pages should be mapped through ptov_table. */
        for (vm_offset_t va = segBOOTDATAB; va < (segBOOTDATAB + segSizeBOOTDATA); va += ARM_PGBYTES) {
                pt_entry_t *pte = arm_kva_to_pte(va);
@@ -1589,6 +1603,11 @@ arm_vm_prot_finalize(boot_args * args __unused)
                arm_vm_page_granular_RNX(segLASTDATACONSTB, segSizeLASTDATACONST, ARM64_GRANULE_ALLOW_BLOCK);
        }
 
+       /*
+        * __KLD,__text should no longer be executable.
+        */
+       arm_vm_page_granular_RNX(segKLDB, segSizeKLD, ARM64_GRANULE_ALLOW_BLOCK);
+
        /*
         * Must wait until all other region permissions are set before locking down DATA_CONST
         * as the kernel static page tables live in DATA_CONST on KTRR enabled systems
@@ -1860,6 +1879,7 @@ arm_vm_init(uint64_t memory_size, boot_args * args)
        segBOOTDATAB     = (vm_offset_t) getsegdatafromheader(&_mh_execute_header, "__BOOTDATA", &segSizeBOOTDATA);
        segLINKB         = (vm_offset_t) getsegdatafromheader(&_mh_execute_header, "__LINKEDIT", &segSizeLINK);
        segKLDB          = (vm_offset_t) getsegdatafromheader(&_mh_execute_header, "__KLD", &segSizeKLD);
+       segKLDDATAB      = (vm_offset_t) getsegdatafromheader(&_mh_execute_header, "__KLDDATA", &segSizeKLDDATA);
        segPRELINKDATAB  = (vm_offset_t) getsegdatafromheader(&_mh_execute_header, "__PRELINK_DATA", &segSizePRELINKDATA);
        segPRELINKINFOB  = (vm_offset_t) getsegdatafromheader(&_mh_execute_header, "__PRELINK_INFO", &segSizePRELINKINFO);
        segPLKLLVMCOVB   = (vm_offset_t) getsegdatafromheader(&_mh_execute_header, "__PLK_LLVM_COV", &segSizePLKLLVMCOV);
@@ -1877,7 +1897,10 @@ arm_vm_init(uint64_t memory_size, boot_args * args)
                // fileset has kext PLK_TEXT_EXEC under kernel collection TEXT_EXEC following kernel's LAST
                segKCTEXTEXECB = (vm_offset_t) getsegdatafromheader(kc_mh,             "__TEXT_EXEC", &segSizeKCTEXTEXEC);
                assert(segPLKTEXTEXECB && !segSizePLKTEXTEXEC);                        // kernel PLK_TEXT_EXEC must be empty
-               assert(segLASTB && segSizeLAST);                                       // kernel LAST must not be empty
+
+               assert(segLASTB);                                                      // kernel LAST can be empty, but it must have
+                                                                                      // a valid address for computations below.
+
                assert(segKCTEXTEXECB <= segLASTB);                                    // KC TEXT_EXEC must contain kernel LAST
                assert(segKCTEXTEXECB + segSizeKCTEXTEXEC >= segLASTB + segSizeLAST);
                segPLKTEXTEXECB = segLASTB + segSizeLAST;