Loading...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 | /* * Copyright (c) 2025 Apple Inc. All rights reserved. * * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in * compliance with the License. The rights granted to you under the License * may not be used to create, or enable the creation or redistribution of, * unlawful or unlicensed copies of an Apple operating system, or to * circumvent, violate, or enable the circumvention or violation of, any * terms of an Apple operating system software license agreement. * * Please obtain a copy of the License at * http://www.opensource.apple.com/apsl/ and read it before using this file. * * The Original Code and all software distributed under the License are * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. * Please see the License for the specific language governing rights and * limitations under the License. * * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ */ #include <vm/vm_entry_lock_internal.h> #include <vm/vm_map_internal.h> #include <vm/vm_map_lock_internal.h> #include <vm/vm_map_store_internal.h> #include <vm/vm_test_utils_internal.h> #include <sys/code_signing.h> vm_map_t vm_test_alloc_map(void) { pmap_t pmap = pmap_create_options(NULL, 0, PMAP_CREATE_64BIT); return vm_map_create_options(pmap, 0, 0xfffffffffffff, 0); } vm_map_t vm_test_alloc_4k_map(void) { pmap_t pmap = pmap_create_options(NULL, 0, PMAP_CREATE_64BIT); return vm_map_create_with_page_shift(pmap, 0, 0xfffffffffffff, FOURK_PAGE_SHIFT, 0); } vm_map_entry_t vm_test_add_map_entry(vm_map_t map, vm_map_offset_t start, vm_map_offset_t end) { vm_map_entry_t entry = vm_map_entry_create_locked(map, start, end); vm_map_entry_t after_where; bool found; vm_map_ilk_lock(map); found = vm_map_lookup_or_next(map, start, &after_where); if (!found) { after_where = VME_PREV(after_where); } assert(end > start); if (!entry_is_map_end(map, after_where)) { assert(start >= after_where->vme_end); } if (!entry_is_map_end(map, after_where->vme_next)) { assert(end <= after_where->vme_next->vme_start); } entry->use_pmap = true; entry->protection = VM_PROT_DEFAULT; entry->max_protection = VM_PROT_ALL; vm_map_store_insert(map, entry); vm_map_ilk_unlock(map); vm_entry_unlock_exclusive(map, entry); return entry; } void setup_constant_submap(vm_map_address_t constant_submap_entry_start, vm_map_address_t start, vm_map_address_t end, int nentries, vm_map_t * parent_map, vm_map_t * submap) { vm_map_address_t submap_entry_length = PAGE_SIZE; kern_return_t kr; *parent_map = vm_map_create_options(pmap_create_options(NULL, 0, PMAP_CREATE_64BIT), 0, 0xfffffffffffff, 0); pmap_t pmap_nested = pmap_create_options(NULL, 0, PMAP_CREATE_64BIT | PMAP_CREATE_NESTED); #if defined(__arm64__) pmap_set_nested(pmap_nested); #endif #if CODE_SIGNING_MONITOR csm_setup_nested_address_space(pmap_nested, start, end - start); #endif pmap_set_shared_region((*parent_map)->pmap, pmap_nested, start, end - start); *submap = vm_map_create_options(pmap_nested, 0, 0xfffffffffffff, 0); (*submap)->is_nested_map = true; (*submap)->vmmap_sealed = VM_MAP_WILL_BE_SEALED; for (int i = 0; i < nentries; i++) { vm_map_address_t entry_start = constant_submap_entry_start + submap_entry_length * i; vm_object_t obj; obj = vm_object_allocate(submap_entry_length, (*submap)->serial_id); kr = vm_map_enter(*submap, &entry_start, submap_entry_length, 0, VM_MAP_KERNEL_FLAGS_FIXED(), obj, /* non NULL to avoid coalesce */ 0, true, VM_PROT_DEFAULT, VM_PROT_DEFAULT, VM_INHERIT_DEFAULT); assert3u(kr, ==, KERN_SUCCESS); assert(obj->shadowed); /* for entry's needs_copy */ vm_map_reference(*submap); } kr = vm_map_enter(*parent_map, &start, end - start, 0, VM_MAP_KERNEL_FLAGS_FIXED(.vmkf_submap = TRUE, .vmkf_nested_pmap = TRUE), (vm_object_t)(uintptr_t) *submap, constant_submap_entry_start, true, VM_PROT_DEFAULT, VM_PROT_DEFAULT, VM_INHERIT_DEFAULT); assert3u(kr, ==, KERN_SUCCESS); assert3s((*submap)->hdr.nentries, ==, nentries); assert3s((*parent_map)->hdr.nentries, ==, 1); vm_map_seal(*submap, true); } |