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