1 /* 2 * Copyright (c) 2021 Apple Computer, Inc. All rights reserved. 3 * 4 * @APPLE_LICENSE_HEADER_START@ 5 * 6 * The contents of this file constitute Original Code as defined in and 7 * are subject to the Apple Public Source License Version 1.1 (the 8 * "License"). You may not use this file except in compliance with the 9 * License. Please obtain a copy of the License at 10 * http://www.apple.com/publicsource and read it before using this file. 11 * 12 * This Original Code and all software distributed under the License are 13 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER 14 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 15 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 16 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the 17 * License for the specific language governing rights and limitations 18 * under the License. 19 * 20 * @APPLE_LICENSE_HEADER_END@ 21 */ 22 23 #ifndef _VM_PMAP_CS_H_ 24 #define _VM_PMAP_CS_H_ 25 26 #ifdef KERNEL_PRIVATE 27 /* 28 * All of PMAP_CS definitions are private and should remain accessible only within XNU 29 * and Apple internal kernel extensions. 30 */ 31 32 #include <mach/kern_return.h> 33 #include <mach/vm_param.h> 34 #include <mach/vm_types.h> 35 #include <mach/boolean.h> 36 #include <img4/firmware.h> 37 #include <img4/nonce.h> 38 39 __BEGIN_DECLS 40 41 /** 42 * Check if the PPL based code signing is enabled on the system or not. With a bit of 43 * a refactor on how this function is defined, we could soon move this within the 44 * XNU_KERNEL_PRIVATE directive. 45 */ 46 bool 47 pmap_cs_enabled(void); 48 49 #if XNU_KERNEL_PRIVATE 50 /* 51 * Any declarations for types or functions which don't need to be exported to kernel 52 * extensions should go here. Naturally, this means this section can also include 53 * headers which may not be available to kernel extensions. 54 */ 55 56 #if defined(__arm64__) 57 #include <pexpert/arm64/board_config.h> 58 #endif 59 60 #include <vm/pmap.h> 61 #include <kern/lock_rw.h> 62 #include <libkern/image4/dlxk.h> 63 #include <TrustCache/API.h> 64 65 66 #if PMAP_CS 67 #define PMAP_CS_INCLUDE_CODE_SIGNING 1 68 #endif 69 70 #if CONFIG_SPTM 71 #define PMAP_CS_PPL_MONITOR 0 72 #elif XNU_MONITOR 73 #define PMAP_CS_PPL_MONITOR 1 74 #else 75 #define PMAP_CS_PPL_MONITOR 0 76 #endif 77 78 #if PMAP_CS_PPL_MONITOR 79 80 /* 81 * XNU_MONITOR and PMAP_CS are both defined for the same targets in board_config.h. 82 * As a result, whenever XNU_MONITOR is defined, so is PMAP_CS. In an ideal world, we 83 * can remove the use of PMAP_CS macro and simply use XNU_MONITOR, but that would 84 * require a lot of changes throughout the codebase. 85 * 86 * PMAP_CS_PPL_MONITOR is defined when we have XNU_MONITOR _and_ we explicitly don't 87 * have CONFIG_SPTM. This effectively means that whenever we have PMAP_CS_PPL_MONITOR, 88 * we should also always have PMAP_CS_INCLUDE_CODE_SIGNING. Lets enforce this with a 89 * build check. 90 */ 91 #if !PMAP_CS_INCLUDE_CODE_SIGNING 92 #error "PMAP_CS_INCLUDE_CODE_SIGNING not defined when under PMAP_CS_PPL_MONITOR" 93 #endif 94 95 /* Immutable part of the trust cache runtime */ 96 extern TrustCacheRuntime_t ppl_trust_cache_rt; 97 98 /* Mutable part of the trust cache runtime */ 99 extern TrustCacheMutableRuntime_t ppl_trust_cache_mut_rt; 100 101 /* Lock for the trust cache runtime */ 102 extern lck_rw_t ppl_trust_cache_rt_lock; 103 104 typedef struct _pmap_img4_payload { 105 /* The trust cache data structure which wraps the payload */ 106 TrustCache_t trust_cache; 107 108 /* The actual image4 trust cache payload */ 109 uint8_t img4_payload[0]; 110 } pmap_img4_payload_t; 111 112 /* State for whether developer mode has been set or not */ 113 extern uint8_t ppl_developer_mode_set; 114 115 /* State of developer mode on the system */ 116 extern bool ppl_developer_mode_storage; 117 118 /* 119 * State of lockdown mode on the system. This variable is an exclusive view of 120 * lockdown mode state for the PPL, and we capture this because the kernel's 121 * view of lockdown mode isn't immutable. 122 */ 123 extern bool ppl_lockdown_mode_enabled; 124 extern bool ppl_lockdown_mode_enforce_jit; 125 126 /** 127 * Check the PPL trust cache runtime if a particular trust cache has already been 128 * loaded based on its UUID. The PPL trust cache runtime is kept locked as shared 129 * during the function. 130 */ 131 kern_return_t 132 pmap_check_trust_cache_runtime_for_uuid( 133 const uint8_t check_uuid[kUUIDSize]); 134 135 /** 136 * Load an image4 trust cache of a particular type into the PPL. If validation succeeds, 137 * the payload will remain locked, but the other artifacts will be unlocked. If validation 138 * fails, all artifacts will be unlocked. 139 * 140 * All the lengths passed in will first be rounded up to page-size, so it is expected that 141 * the caller allocates page-aligned data. 142 * 143 * Upon successful validation, the trust cache is added to the runtime maintained by the 144 * PPL. 145 */ 146 kern_return_t 147 pmap_load_trust_cache_with_type( 148 TCType_t type, 149 const vm_address_t pmap_img4_payload, const vm_size_t pmap_img4_payload_len, 150 const vm_address_t img4_manifest, const vm_size_t img4_manifest_len, 151 const vm_address_t img4_aux_manifest, const vm_size_t img4_aux_manifest_len); 152 153 /* 154 * Query a trust cache from within the PPL. This function can only be called when within 155 * the PPL and does not pin the query_token passed in. 156 */ 157 kern_return_t 158 pmap_query_trust_cache_safe( 159 TCQueryType_t query_type, 160 const uint8_t cdhash[kTCEntryHashSize], 161 TrustCacheQueryToken_t *query_token); 162 163 /** 164 * Query a trust cache of a particular type from the PPL. The query_token passed in will 165 * be pinned by the PPL runtime when the PPL is attempting to write to it. This is an API 166 * which can be used for callers external to the PPL. 167 */ 168 kern_return_t 169 pmap_query_trust_cache( 170 TCQueryType_t query_type, 171 const uint8_t cdhash[kTCEntryHashSize], 172 TrustCacheQueryToken_t *query_token); 173 174 /** 175 * Toggle the state of developer mode on the system. This function can only be called with 176 * a true value once in the lifecycle of a boot. 177 * 178 * Until this function is called once to set the state, the PPL will block non-platform 179 * code and JIT on the system. 180 */ 181 void 182 pmap_toggle_developer_mode( 183 bool state); 184 185 #endif /* PMAP_CS_PPL_MONITOR */ 186 187 #if PMAP_CS_INCLUDE_CODE_SIGNING 188 189 #ifndef CORE_ENTITLEMENTS_I_KNOW_WHAT_IM_DOING 190 #define CORE_ENTITLEMENTS_I_KNOW_WHAT_IM_DOING 191 #endif 192 193 #include <CoreEntitlements/CoreEntitlementsPriv.h> 194 #include <kern/cs_blobs.h> 195 #include <libkern/tree.h> 196 #include <libkern/crypto/sha1.h> 197 #include <libkern/crypto/sha2.h> 198 #include <libkern/coretrust/coretrust.h> 199 200 201 /* Validation data for a provisioning profile */ 202 typedef struct _pmap_cs_profile { 203 /* 204 * The PPL uses the physical aperture mapping to write to this structure. But 205 * we need to save a pointer to the original mapping for when we are going to 206 * unregister this profile from the PPL. 207 */ 208 void *original_payload; 209 210 /* A CoreEntitlements context for querying the profile */ 211 der_vm_context_t profile_ctx_storage; 212 const der_vm_context_t *profile_ctx; 213 214 /* 215 * Critical information regarding the profile. If a profile has not been verified, 216 * it cannot be associated with a code signature. Development profiles are only 217 * allowed under certain circumstances. 218 */ 219 bool profile_validated; 220 bool development_profile; 221 222 /* 223 * Reference count for the number of code signatures which are currently using 224 * this provisioning profile for their constraint validation. 225 */ 226 uint32_t reference_count; 227 228 /* 229 * The list of entitlements which are provisioned by this provisioning profile. 230 * If this list allows the debuggee entitlements, then this profile is considered 231 * a development profile. 232 */ 233 struct CEQueryContext entitlements_ctx_storage; 234 struct CEQueryContext *entitlements_ctx; 235 236 /* Red-black tree linkage */ 237 RB_ENTRY(_pmap_cs_profile) link; 238 } pmap_cs_profile_t; 239 240 /* This is how we expect the kernel to hand us provisioning profiles */ 241 typedef struct _pmap_profile_payload { 242 /* Storage for the provisioning profile */ 243 pmap_cs_profile_t profile_obj_storage; 244 245 /* Size of the signed profile blob */ 246 vm_size_t profile_blob_size; 247 248 /* The signed profile blob itself */ 249 uint8_t profile_blob[0]; 250 } pmap_profile_payload_t; 251 252 /* Trust levels are ordered, i.e. higher is more trust */ 253 typedef enum { 254 PMAP_CS_UNTRUSTED = 0, 255 256 /* 257 * Trust level given to code directory entries which have been retired and are 258 * no longer valid to be used for any purpose. These code directores are freed 259 * when their reference count touches 0. 260 */ 261 PMAP_CS_RETIRED, 262 263 /* 264 * This trust level signifies that an application has been verified through the 265 * profile based certificate chain, but the profile in question itself has not 266 * been verified. Code directories with this trust aren't allowed to be run 267 * or mapped. 268 */ 269 PMAP_CS_PROFILE_PREFLIGHT, 270 271 /* 272 * Signatures provided through the compilation service. These signatures are meant 273 * to only apply to loadable libraries, and therefore have the lowest acceptable trust. 274 */ 275 PMAP_CS_COMPILATION_SERVICE, 276 277 /* 278 * Signature for out-of-process JIT. These can only be loaded by an entitled process 279 * and have a special library validation policy for being mapped within other processes. 280 * These represent a safer version of JIT. 281 */ 282 PMAP_CS_OOP_JIT, 283 284 /* 285 * These signatures are those which are trusted because they have been signed by the 286 * device local signing key. 287 */ 288 PMAP_CS_LOCAL_SIGNING, 289 290 /* 291 * These signatures belong to applications which are profile validated, and for those 292 * whose profiles have also been verified. 293 */ 294 PMAP_CS_PROFILE_VALIDATED, 295 296 /* 297 * These signatures are those belonging to the app store. 298 */ 299 PMAP_CS_APP_STORE, 300 301 #if PMAP_CS_INCLUDE_INTERNAL_CODE 302 /* 303 * Engineering roots which are still Apple signed. These don't need to be platform 304 * because they are backed by a CMS signature and therefore would've never been 305 * platform anyways. 306 */ 307 PMAP_CS_ENGINEERING_SIGNED_WITH_CMS, 308 #endif 309 310 /* 311 * These signatures represent platform binaries which have the highest trust level. 312 */ 313 PMAP_CS_IN_MOBILE_ASSET_TRUST_CACHE, 314 PMAP_CS_IN_LOADED_TRUST_CACHE, 315 PMAP_CS_IN_STATIC_TRUST_CACHE, 316 317 #if PMAP_CS_INCLUDE_INTERNAL_CODE 318 /* 319 * Engineering roots installed by engineers for development. These are given the 320 * highest trust level. 321 */ 322 PMAP_CS_ENGINEERING_SIGNED, 323 #endif 324 } pmap_cs_trust_t; 325 326 /* Everything with greater or equal trust is a platform binary */ 327 #define PMAP_CS_LOWEST_PLATFORM_BINARY_TRUST PMAP_CS_IN_MOBILE_ASSET_TRUST_CACHE 328 329 /* Minimum trust level of a code signature to be run/mapped */ 330 #define PMAP_CS_LOWEST_ACCEPTABLE_TRUST PMAP_CS_COMPILATION_SERVICE 331 332 typedef struct pmap_cs_code_directory { 333 union { 334 struct { 335 /* red-black tree linkage */ 336 RB_ENTRY(pmap_cs_code_directory) link; 337 338 /* 339 * Blobs which are small enough are allocated and managed by the PPL. This field 340 * is NULL for large blobs. 341 */ 342 struct pmap_cs_blob *managed_blob; 343 bool managed; 344 345 /* 346 * The superblob of the code signature. The length we store here is the length of the 347 * memory allocated by the kernel itself, which may be greater than the actual length 348 * of the code signature. 349 */ 350 CS_SuperBlob *superblob; 351 vm_size_t superblob_size; 352 bool superblob_validated; 353 354 /* 355 * Code directories can be arbitrarily large, and hashing them can take a long time. We 356 * usually hash code directories in a continuable way, yielding our execution context 357 * after hashing some amount of the bytes. 358 */ 359 union { 360 SHA384_CTX sha384_ctx; 361 SHA256_CTX sha256_ctx; 362 SHA1_CTX sha1_ctx; 363 }; 364 uint32_t cd_length_hashed; 365 366 /* 367 * The best code directory is just an offset away from the superblob. This code directory 368 * is extensively validated for all of its fields. 369 */ 370 const CS_CodeDirectory *cd; 371 bool cd_offset_matched; 372 373 /* 374 * The first code directory is used when validating the CMS blob attached to a code signature 375 * and is often not the best code directory. 376 */ 377 bool first_cd_initialized; 378 bool first_cd_hashed; 379 uint8_t first_cdhash[CS_HASH_MAX_SIZE]; 380 const uint8_t *first_cd; 381 size_t first_cd_length; 382 const uint8_t *cms_blob; 383 size_t cms_blob_length; 384 CoreTrustDigestType ct_digest_type; 385 386 /* 387 * Frequently accessed information from the code directory kept here as a cache. 388 */ 389 const char *identifier; 390 const char *teamid; 391 bool main_binary; 392 393 /* 394 * The DER entitlements blob and CoreEntitlements context for querying this code 395 * signature for entitlements. 396 */ 397 struct CEQueryContext core_entitlements_ctx; 398 struct CEQueryContext *ce_ctx; 399 const CS_GenericBlob *der_entitlements; 400 uint32_t der_entitlements_size; 401 402 /* 403 * This is parhaps the most important field in this structure. It signifies what 404 * level of confidence we have in this code directory and this trust level 405 * defines execution/mapping policies for this code directory. 406 */ 407 pmap_cs_trust_t trust; 408 409 /* 410 * Reference count of how many regions this code directory is associated with through 411 * pmap_cs_associate. 412 */ 413 uint32_t reference_count; 414 415 /* 416 * We maintain this field as it allows us to quickly index into a bucket of supported 417 * hash types, and choose the correct hashing algorithm for this code directory. 418 */ 419 unsigned int hash_type; 420 421 /* Lock on this code directory */ 422 decl_lck_rw_data(, rwlock); 423 424 /* 425 * The PPL may transform the code directory (e.g. for multilevel hashing), 426 * which changes its cdhash. We retain the cdhash of the original, canonical 427 * code directory here. 428 */ 429 uint8_t cdhash[CS_CDHASH_LEN]; 430 431 /* 432 * For performing provisioning profile validation in the PPL, we store the profile as 433 * PPL owned data so it cannot be changed during the validation time period. 434 * 435 * This interface for profile validation is deprecated. 436 */ 437 struct { 438 /* The provisioning profile and its size */ 439 const uint8_t *profile; 440 vm_size_t profile_size; 441 442 /* Size of memory allocated to hold the profile */ 443 vm_size_t allocation_size; 444 } profile_data; 445 446 /* 447 * The provisioning profile object used for validating constrainst for profile validates 448 * signatures. This is the newer interface the PPL uses. 449 */ 450 pmap_cs_profile_t *profile_obj; 451 452 /* 453 * The leaf certificate for CMS blobs as returned to us by CoreTrust. This is used when 454 * verifying a signature against a provisioning profile. 455 */ 456 const uint8_t *cms_leaf; 457 vm_size_t cms_leaf_size; 458 459 /* 460 * A pointer to the entitlements structure maintained by the kernel. We don't really 461 * care about this other than maintaing a link to it in memory which isn't writable 462 * by the kernel. 463 */ 464 const void *kernel_entitlements; 465 466 /* 467 * The UBC layer may request the PPL to unlock the unneeded part of the code signature. 468 * We hold this boolean to track whether we have unlocked those unneeded bits already or 469 * not. 470 */ 471 bool unneeded_code_signature_unlocked; 472 }; 473 474 /* Free list linkage */ 475 struct pmap_cs_code_directory *pmap_cs_code_directory_next; 476 }; 477 } pmap_cs_code_directory_t; 478 479 typedef struct pmap_cs_lookup_results { 480 /* Start of the code region */ 481 vm_map_address_t region_addr; 482 483 /* Size of the code region */ 484 vm_map_size_t region_size; 485 486 /* Code signature backing the code region */ 487 struct pmap_cs_code_directory *region_sig; 488 } pmap_cs_lookup_results_t; 489 490 typedef struct _pmap_cs_ce_acceleration_buffer { 491 /* Magic to identify this structure */ 492 uint16_t magic; 493 494 /* 495 * The acceleration buffer can come from one of two places. First, it can come 496 * from the extra space present within the locked down code signature as not 497 * all of it is used all the time. In this case, we don't need to free the 498 * buffer once we're done using it. Second, it can come from the bucket allocator 499 * within the PPL, in which case we need to deallocate this after we're done with 500 * it. 501 */ 502 union { 503 uint16_t unused0; 504 bool allocated; 505 }; 506 507 /* The length of the acceleration buffer */ 508 uint32_t length; 509 510 /* The embedded buffer bytes */ 511 uint8_t buffer[0]; 512 } __attribute__((packed)) pmap_cs_ce_acceleration_buffer_t; 513 514 /* Ensure we have a known overhead here */ 515 _Static_assert(sizeof(pmap_cs_ce_acceleration_buffer_t) == 8, 516 "sizeof(pmap_cs_ce_acceleration_buffer_t) != 8"); 517 518 #define PMAP_CS_ACCELERATION_BUFFER_MAGIC (0x1337u) 519 520 #define PMAP_CS_ASSOCIATE_JIT ((void *) -1) 521 #define PMAP_CS_ASSOCIATE_COW ((void *) -2) 522 #define PMAP_CS_LOCAL_SIGNING_KEY_SIZE 97 523 524 /* Maximum blob sized managed by the PPL on its own */ 525 extern const size_t pmap_cs_blob_limit; 526 527 /** 528 * Initialize the red-black tree and the locks for managing provisioning profiles within 529 * the PPL. 530 * 531 * This function doesn't trap into the PPL but writes to PPL protected data. Hence, this 532 * function needs to be called before the PPL is locked down, asn otherwise it will cause 533 * a system panic. 534 */ 535 void 536 pmap_initialize_provisioning_profiles(void); 537 538 /** 539 * Register a provisioning profile with the PPL. The payload address and size are both 540 * expected to be page aligned. The PPL will attempt to lockdown the address range before 541 * the profile validation. 542 * 543 * After validation, the profile will be added to an internal red-black tree, allowing 544 * the PPL to safely enumerate all registered profiles. 545 */ 546 kern_return_t 547 pmap_register_provisioning_profile( 548 const vm_address_t payload_addr, 549 const vm_size_t payload_size); 550 551 /** 552 * Unregister a provisioning profile from the PPL. The payload which was registered is 553 * unlocked, and the caller is free to do whatever they want with it. Unregistration is 554 * only successful when there are no reference counts on the profile object. 555 */ 556 kern_return_t 557 pmap_unregister_provisioning_profile( 558 pmap_cs_profile_t *profile_obj); 559 560 /** 561 * Associate a PPL profile object with a PPL code signature object. A code signature 562 * object can only have a single profile associated with it, and a successful association 563 * increments the reference count on the profile object. 564 */ 565 kern_return_t 566 pmap_associate_provisioning_profile( 567 pmap_cs_code_directory_t *cd_entry, 568 pmap_cs_profile_t *profile_obj); 569 570 /** 571 * Disassociate a PPL profile object from a PPL code signature object. Disassociation 572 * through this code path is only successful when the code signature object has been 573 * verified. 574 * 575 * This decrements the reference count on the profile object, potentially allowing it 576 * to be unregistered if the reference count hits zero. 577 */ 578 kern_return_t 579 pmap_disassociate_provisioning_profile( 580 pmap_cs_code_directory_t *cd_entry); 581 582 /** 583 * Store the compilation service CDHash within the PPL storage so that it may not be 584 * modified by an attacker. The CDHash being stored must represent a library and this 585 * is enforced during signature validation when a signature is trusted because it 586 * matched the compilation service CDHash. 587 */ 588 void 589 pmap_set_compilation_service_cdhash(const uint8_t cdhash[CS_CDHASH_LEN]); 590 591 /** 592 * Match a specified CDHash against the stored compilation service CDHash. The CDHash 593 * is protected with a lock, and that lock is held when the matching takes place in 594 * order to ensure we don't compare against a CDHash which is in the process of changing. 595 */ 596 bool 597 pmap_match_compilation_service_cdhash(const uint8_t cdhash[CS_CDHASH_LEN]); 598 599 /** 600 * Store the local signing public key in secured storage within the PPL. The PPL only 601 * allows setting a key once, and subsequent attempts to do this will panic the system. 602 * 603 * This key is used during CoreTrust validation of signatures during code signature 604 * verification. 605 */ 606 void 607 pmap_set_local_signing_public_key( 608 const uint8_t public_key[PMAP_CS_LOCAL_SIGNING_KEY_SIZE]); 609 610 /** 611 * Acquire the local signing public key which was previusly stored within the PPL. If 612 * there is no key stored in the PPL, then this function shall return NULL. 613 */ 614 uint8_t* 615 pmap_get_local_signing_public_key(void); 616 617 /** 618 * All locally signed main binaries need to be authorixed explicitly before they are 619 * allowed to run. As part of this, this API allows an application to register a CDHash 620 * for the main binary it is intending to run. 621 * 622 * Use of this API requires the appropriate entitlement. 623 */ 624 void 625 pmap_unrestrict_local_signing( 626 const uint8_t cdhash[CS_CDHASH_LEN]); 627 628 /** 629 * Register a code signature blob with the PPL. If the blob size is small enough, the 630 * PPL will copy the entire blob into its own allocated memory. On the other hand, if 631 * the blob is large, the PPL will attempt to lockdown the passed in blob, and doing 632 * so will require that the address and size provided are page aligned. 633 * 634 * After validation, the signature will be added to an internal red-black tree, allowing 635 * the PPL to safely enumerate all registered code signatures. 636 */ 637 kern_return_t 638 pmap_cs_register_code_signature_blob( 639 vm_address_t blob_addr, 640 vm_size_t blob_size, 641 vm_offset_t code_directory_offset, 642 pmap_cs_code_directory_t **cd_entry); 643 644 /** 645 * Unregister a code signature blob from the PPL. The signature address is either freed 646 * in case it was owned by the PPL, or it is unlocked in case it was XNU-owned by was PPL 647 * locked. 648 * 649 * If the memory is unlocked, then the kernel is free to do with the memory as it pleases. 650 * Note that this function may not deallocate the cd_entry itself, in case the cd_entry 651 * has any reference counts on it. In that case, the cd_entry is retired, and finally 652 * freed when the final code region which references the cd_entry is freed. 653 */ 654 kern_return_t 655 pmap_cs_unregister_code_signature_blob( 656 pmap_cs_code_directory_t *cd_entry); 657 658 /** 659 * Verify a signature within the PPL. Once a signature has been verified, it gets assigned 660 * a trust level, and based on that trust level, the cd_entry is then allowed to be 661 * associated with address spaces. 662 */ 663 kern_return_t 664 pmap_cs_verify_code_signature_blob( 665 pmap_cs_code_directory_t *cd_entry); 666 667 /** 668 * Once we've verified a code signature, not all blobs from the signature are required 669 * going forward. This function can be used to unlock parts of the code signature which 670 * can then be freed by the kernel to conserve memory. 671 */ 672 kern_return_t 673 pmap_cs_unlock_unneeded_code_signature( 674 pmap_cs_code_directory_t *cd_entry, 675 vm_address_t *unneeded_addr, 676 vm_size_t *unneeded_size); 677 678 /** 679 * Create an association of a cd_entry within a code region in the pmap. If the cd_entry 680 * is a main binary, then it is set as the main region of the pmap, otherwise the cd_entry 681 * is evaluated for a library validation policy against the main binary of the pmap. 682 */ 683 kern_return_t 684 pmap_cs_associate( 685 pmap_t pmap, 686 pmap_cs_code_directory_t *cd_entry, 687 vm_map_address_t vaddr, 688 vm_map_size_t vsize, 689 vm_object_offset_t offset); 690 691 /** 692 * Iterate through the code regions present in the SPLAY tree for checking if the specified 693 * address intersects with any code region or not. 694 */ 695 void 696 pmap_cs_lookup( 697 pmap_t pmap, 698 vm_map_address_t vaddr, 699 pmap_cs_lookup_results_t *results); 700 701 /** 702 * Let the PPL know that the associated pmap needs to be debugged and therefore it needs 703 * to allow invalid code to be mapped in. PPL shall only allow this when the pmap posseses 704 * the appropriate debuggee entitlement. 705 */ 706 kern_return_t 707 pmap_cs_allow_invalid(pmap_t pmap); 708 709 /** 710 * Acquire the trust level which is put onto a pmap based on the code signature associated 711 * with the main region. This function does NOT take a lock on the pmap and does not trap 712 * into the PPL. 713 */ 714 kern_return_t 715 pmap_get_trust_level_kdp( 716 pmap_t pmap, 717 pmap_cs_trust_t *trust_level); 718 719 /** 720 * Acquire the start and end address for the JIT region for the pmap, if any. 721 * This function does NOT take a lock on the pmap and does not trap into the PPL. 722 */ 723 kern_return_t 724 pmap_get_jit_address_range_kdp( 725 pmap_t pmap, 726 uintptr_t *jit_region_start, 727 uintptr_t *jit_region_end); 728 729 /** 730 * Copy over the main binary association from the old address space to the new address 731 * space. This is required since a fork copies over all associations from one address space 732 * to another, and we need to make sure the main binary association is made before any 733 * libraries are mapped in. 734 */ 735 kern_return_t 736 pmap_cs_fork_prepare( 737 pmap_t old_pmap, 738 pmap_t new_pmap); 739 740 /** 741 * Keep a reference to the kernel entitlements data structure within the cd_entry in 742 * order to establish a read-only chain for the kernel to query in order to resolve the 743 * entitlements on an address space. 744 */ 745 kern_return_t 746 pmap_associate_kernel_entitlements( 747 pmap_cs_code_directory_t *cd_entry, 748 const void *kernel_entitlements); 749 750 /** 751 * Resolve the kernel entitlements object attached to the main binary of an address space 752 * and return it back to the kernel. 753 */ 754 kern_return_t 755 pmap_resolve_kernel_entitlements( 756 pmap_t pmap, 757 const void **kernel_entitlements); 758 759 /** 760 * Accelerate the CoreEntitlements context for a particular cd_entry. This operation can 761 * only be performed on reconstituted code signatures, and accelerates the context using 762 * memory which is locked by the PPL. 763 * 764 * If the code signature pages have enough space left within them, then that extra space 765 * is used for allocating the acceleration buffer, otherwise we tap into the allocator 766 * for it. 767 */ 768 kern_return_t 769 pmap_accelerate_entitlements( 770 pmap_cs_code_directory_t *cd_entry); 771 772 #endif /* PMAP_CS_INCLUDE_CODE_SIGNING */ 773 774 /** 775 * The PPl allocates some space for AppleImage4 to store some of its data. It needs to 776 * allocate this space since this region needs to be PPL protected, and the macro which 777 * makes a region PPL protected isn't available to kernel extensions. 778 * 779 * This function can be used to acquire the memory region which is PPL protected. 780 */ 781 void* 782 pmap_image4_pmap_data( 783 size_t *allocated_size); 784 785 /** 786 * Use the AppleImage4 API to set a nonce value based on a particular nonce index. 787 * AppleImage4 ensures that a particular nonce domain value can only be set once 788 * during the boot of the system. 789 */ 790 void 791 pmap_image4_set_nonce( 792 const img4_nonce_domain_index_t ndi, 793 const img4_nonce_t *nonce); 794 795 /** 796 * Use the AppleImage4 API to roll the nonce associated with a particular domain to 797 * make the nonce invalid. 798 */ 799 void 800 pmap_image4_roll_nonce( 801 const img4_nonce_domain_index_t ndi); 802 803 /** 804 * Use the AppleImage4 API to copy the nonce value associated with a particular domain. 805 * 806 * The PPL will attempt to "pin" the nonce_out parameter before writing to it. 807 */ 808 errno_t 809 pmap_image4_copy_nonce( 810 const img4_nonce_domain_index_t ndi, 811 img4_nonce_t *nonce_out); 812 813 /** 814 * Use the AppleImage4 API to perform object execution of a particular known object type. 815 * 816 * These are the supported object types: 817 * - IMG4_RUNTIME_OBJECT_SPEC_INDEX_SUPPLEMENTAL_ROOT 818 */ 819 errno_t 820 pmap_image4_execute_object( 821 img4_runtime_object_spec_index_t obj_spec_index, 822 const img4_buff_t *payload, 823 const img4_buff_t *manifest); 824 825 /** 826 * Use the AppleImage4 API to copy an executed objects contents into provided memroy. 827 * 828 * The PPL will attempt to "pin" the object_out parameter before writing to it. 829 */ 830 errno_t 831 pmap_image4_copy_object( 832 img4_runtime_object_spec_index_t obj_spec_index, 833 vm_address_t object_out, 834 size_t *object_length); 835 836 /** 837 * Entry point for the new AppleImage4 to enter the PPL monitor for it's variety of 838 * tasks. 839 */ 840 errno_t 841 pmap_image4_monitor_trap( 842 image4_cs_trap_t selector, 843 const void *input_data, 844 size_t input_size); 845 846 #endif /* XNU_KERNEL_PRIVATE */ 847 848 __END_DECLS 849 850 #endif /* KERNEL_PRIVATE */ 851 #endif /* _VM_PMAP_CS_H_ */ 852