1 /* 2 * Copyright (c) 2008-2019 Apple Inc. All rights reserved. 3 * 4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ 5 * 6 * This file contains Original Code and/or Modifications of Original Code 7 * as defined in and that are subject to the Apple Public Source License 8 * Version 2.0 (the 'License'). You may not use this file except in 9 * compliance with the License. The rights granted to you under the License 10 * may not be used to create, or enable the creation or redistribution of, 11 * unlawful or unlicensed copies of an Apple operating system, or to 12 * circumvent, violate, or enable the circumvention or violation of, any 13 * terms of an Apple operating system software license agreement. 14 * 15 * Please obtain a copy of the License at 16 * http://www.opensource.apple.com/apsl/ and read it before using this file. 17 * 18 * The Original Code and all software distributed under the License are 19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 23 * Please see the License for the specific language governing rights and 24 * limitations under the License. 25 * 26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ 27 */ 28 29 #ifndef _LIBKERN_OSKEXT_H 30 #define _LIBKERN_OSKEXT_H 31 32 extern "C" { 33 #include <kern/thread_call.h> 34 #include <libkern/OSKextLibPrivate.h> 35 #include <libkern/kernel_mach_header.h> 36 #include <libkern/kxld.h> 37 #include <mach/kmod.h> 38 39 #ifdef XNU_KERNEL_PRIVATE 40 #include <kern/thread_call.h> 41 #endif /* XNU_KERNEL_PRIVATE */ 42 } 43 44 45 #include <libkern/OSKextLib.h> 46 #include <libkern/OSKextLibPrivate.h> 47 #include <libkern/c++/OSObject.h> 48 #include <libkern/c++/OSContainers.h> 49 50 #include <libkern/c++/OSPtr.h> 51 #include <IOKit/IOLocks.h> 52 53 /********************************************************************* 54 * C functions used for callbacks. 55 *********************************************************************/ 56 #ifdef XNU_KERNEL_PRIVATE 57 extern "C" { 58 void osdata_kmem_free(void * ptr, unsigned int length); 59 void osdata_phys_free(void * ptr, unsigned int length); 60 void osdata_vm_deallocate(void * ptr, unsigned int length); 61 void osdata_kext_free(void * ptr, unsigned int length); 62 void kxld_log_callback( 63 KXLDLogSubsystem subsystem, 64 KXLDLogLevel level, 65 const char * format, 66 va_list argList, 67 void * user_data); 68 }; 69 #endif /* XNU_KERNEL_PRIVATE */ 70 71 /********************************************************************* 72 * C Function Prototypes for Friend Declarations. 73 *********************************************************************/ 74 class OSKext; 75 class OSDextStatistics; 76 77 extern "C" { 78 void OSKextLog( 79 OSKext * aKext, 80 OSKextLogSpec msgLogSpec, 81 const char * format, ...) __printflike(3, 4); 82 83 void OSKextVLog( 84 OSKext * aKext, 85 OSKextLogSpec msgLogSpec, 86 const char * format, 87 va_list srcArgList) __printflike(3, 0);; 88 89 #ifdef XNU_KERNEL_PRIVATE 90 void OSKextRemoveKextBootstrap(void); 91 92 kern_return_t OSRuntimeInitializeCPP( 93 OSKext * kext); 94 kern_return_t OSRuntimeFinalizeCPP( 95 OSKext * kext); 96 void OSRuntimeUnloadCPPForSegment( 97 kernel_segment_command_t * segment); 98 void 99 OSRuntimeSignStructors( 100 kernel_mach_header_t * header); 101 void 102 OSRuntimeSignStructorsInFileset( 103 kernel_mach_header_t * fileset_header); 104 105 kern_return_t is_io_catalog_send_data( 106 mach_port_t masterPort, 107 uint32_t flag, 108 io_buf_ptr_t inData, 109 mach_msg_type_number_t inDataCount, 110 kern_return_t * result); 111 112 void kmod_dump_log(vm_offset_t*, unsigned int, boolean_t); 113 void *OSKextKextForAddress(const void *addr); 114 115 kern_return_t OSKextGetLoadedKextSummaryForAddress( 116 const void * addr, 117 OSKextLoadedKextSummary * summary); 118 119 #endif /* XNU_KERNEL_PRIVATE */ 120 }; 121 122 /********************************************************************/ 123 #if PRAGMA_MARK 124 #pragma mark - 125 #endif 126 127 struct list_head { 128 struct list_head *prev; 129 struct list_head *next; 130 }; 131 132 struct OSKextGrabPgoStruct { 133 bool metadata; 134 uint64_t *pSize; 135 char *pBuffer; 136 uint64_t bufferSize; 137 int err; 138 struct list_head list_head; 139 }; 140 141 #ifndef container_of 142 #define container_of(ptr, type, member) ((type*)(((uintptr_t)ptr) - offsetof(type, member))) 143 #endif 144 /********************************************************************/ 145 146 #if XNU_KERNEL_PRIVATE 147 148 struct OSKextAccount { 149 vm_allocation_site_t site; 150 151 #if DEVELOPMENT || DEBUG 152 struct os_refgrp task_refgrp; 153 /* 154 * '5' for the "task_" prefix. task_refgrp_name can be entirely dropped 155 * once we can directly flag the refgrp to be logged. 156 */ 157 char task_refgrp_name[5 + KMOD_MAX_NAME]; 158 #endif /* DEVELOPMENT || DEBUG */ 159 uint32_t loadTag; 160 OSKext * kext; 161 }; 162 163 struct OSKextActiveAccount { 164 uintptr_t address; 165 uintptr_t address_end; 166 OSKextAccount * account; 167 }; 168 typedef struct OSKextActiveAccount OSKextActiveAccount; 169 170 class OSKextSavedMutableSegment : public OSObject { 171 OSDeclareDefaultStructors(OSKextSavedMutableSegment); 172 public: 173 static OSPtr<OSKextSavedMutableSegment> withSegment(kernel_segment_command_t *seg); 174 OSReturn restoreContents(kernel_segment_command_t *seg); 175 vm_offset_t getVMAddr() const; 176 vm_size_t getVMSize() const; 177 virtual void free(void) APPLE_KEXT_OVERRIDE; 178 private: 179 bool initWithSegment(kernel_segment_command_t *seg); 180 kernel_segment_command_t *savedSegment; 181 vm_offset_t vmaddr; 182 vm_size_t vmsize; 183 void * data; 184 }; 185 186 typedef enum { 187 kOSDextCrashPolicyNone, 188 kOSDextCrashPolicyReboot, 189 } OSDextCrashPolicy; 190 191 enum { 192 kMaxDextCrashesInOneDayDefault = 3, 193 }; 194 195 class OSDextStatistics : public OSObject { 196 OSDeclareDefaultStructors(OSDextStatistics); 197 public: 198 static OSPtr<OSDextStatistics> create(); 199 virtual bool init() APPLE_KEXT_OVERRIDE; 200 virtual void free() APPLE_KEXT_OVERRIDE; 201 202 OSDextCrashPolicy recordCrash(); 203 size_t getCrashCount(); 204 205 private: 206 OSPtr<OSArray> crashes; 207 IOLock * lock; 208 }; 209 210 __enum_closed_decl(OSKextInitResult, uint8_t, { 211 kOSKextInitFailure = 0, 212 kOSKextInitialized, 213 kOSKextAlreadyExist, 214 }); 215 216 #endif /* XNU_KERNEL_PRIVATE */ 217 218 /* 219 * @class OSKext 220 */ 221 /********************************************************************/ 222 class OSKext : public OSObject 223 { 224 OSDeclareDefaultStructors(OSKext); 225 226 #if PRAGMA_MARK 227 /**************************************/ 228 #pragma mark Friend Declarations 229 /**************************************/ 230 #endif 231 friend class IOCatalogue; 232 friend class KLDBootstrap; 233 friend class OSMetaClass; 234 235 friend int OSKextGrabPgoData(uuid_t uuid, 236 uint64_t *pSize, 237 char *pBuffer, 238 uint64_t bufferSize, 239 int wait_for_unload, 240 int metadata); 241 242 #ifdef XNU_KERNEL_PRIVATE 243 friend void OSKextVLog( 244 OSKext * aKext, 245 OSKextLogSpec msgLogSpec, 246 const char * format, 247 va_list srcArgList) __printflike(3, 0); 248 249 friend void OSKextRemoveKextBootstrap(void); 250 friend OSReturn OSKextUnloadKextWithLoadTag(uint32_t); 251 252 friend kern_return_t kext_request( 253 host_priv_t hostPriv, 254 /* in only */ uint32_t clientLogSpec, 255 /* in only */ vm_offset_t requestIn, 256 /* in only */ mach_msg_type_number_t requestLengthIn, 257 /* out only */ vm_offset_t * responseOut, 258 /* out only */ mach_msg_type_number_t * responseLengthOut, 259 /* out only */ vm_offset_t * logDataOut, 260 /* out only */ mach_msg_type_number_t * logDataLengthOut, 261 /* out only */ kern_return_t * op_result); 262 263 friend kxld_addr_t kern_allocate( 264 u_long size, 265 KXLDAllocateFlags * flags, 266 void * user_data); 267 268 friend void kxld_log_shim( 269 KXLDLogSubsystem subsystem, 270 KXLDLogLevel level, 271 const char * format, 272 va_list argList, 273 void * user_data); 274 275 friend void _OSKextConsiderUnloads( 276 __unused thread_call_param_t p0, 277 __unused thread_call_param_t p1); 278 279 friend kern_return_t OSRuntimeInitializeCPP( 280 OSKext * kext); 281 friend kern_return_t OSRuntimeFinalizeCPP( 282 OSKext * kext); 283 friend void OSRuntimeUnloadCPPForSegment( 284 kernel_segment_command_t * segment); 285 286 friend kern_return_t is_io_catalog_send_data( 287 mach_port_t masterPort, 288 uint32_t flag, 289 io_buf_ptr_t inData, 290 mach_msg_type_number_t inDataCount, 291 kern_return_t * result); 292 293 friend void kmod_panic_dump(vm_offset_t*, unsigned int); 294 friend void kmod_dump_log(vm_offset_t*, unsigned int, boolean_t); 295 friend void kext_dump_panic_lists(int (*printf_func)(const char * fmt, ...)); 296 friend void *OSKextKextForAddress(const void *addr); 297 298 friend kern_return_t OSKextGetLoadedKextSummaryForAddress( 299 const void * addr, 300 OSKextLoadedKextSummary * summary); 301 302 #endif /* XNU_KERNEL_PRIVATE */ 303 304 private: 305 306 /************************* 307 * Instance variables 308 *************************/ 309 OSPtr<OSDictionary> infoDict; 310 311 OSPtr<const OSSymbol> bundleID; 312 OSPtr<OSString> path; // not necessarily correct :-/ 313 OSPtr<OSString> executableRelPath;// relative to bundle 314 OSPtr<OSString> userExecutableRelPath;// relative to bundle 315 316 OSKextVersion version; // parsed 317 OSKextVersion compatibleVersion;// parsed 318 319 /* These fields are required for tracking loaded kexts and 320 * will always have values for a loaded kext. 321 */ 322 OSKextLoadTag loadTag; // 'id' from old kmod_info; 323 // kOSKextInvalidLoadTag invalid 324 kmod_info_t * kmod_info; // address into linkedExec./alloced for interface 325 326 OSPtr<OSArray> dependencies; // kernel resource does not have any; 327 // links directly to kernel 328 329 /* Only real kexts have these; interface kexts do not. 330 */ 331 OSPtr<OSData> linkedExecutable; 332 OSPtr<OSSet> metaClasses; // for C++/OSMetaClass kexts 333 334 /* Only interface kexts have these; non-interface kexts can get at them 335 * in the linked Executable. 336 */ 337 OSPtr<OSData> interfaceUUID; 338 OSPtr<OSData> driverKitUUID; 339 340 struct { 341 unsigned int loggingEnabled:1; 342 343 unsigned int hasAllDependencies:1; 344 unsigned int hasBleedthrough:1; 345 346 unsigned int interface:1; 347 unsigned int kernelComponent:1; 348 unsigned int prelinked:1; 349 unsigned int builtin:1; 350 unsigned int loaded:1; 351 unsigned int dtraceInitialized:1; 352 unsigned int starting:1; 353 unsigned int started:1; 354 unsigned int stopping:1; 355 unsigned int unloading:1; 356 unsigned int resetSegmentsFromVnode:1; 357 358 unsigned int requireExplicitLoad:1; 359 unsigned int autounloadEnabled:1; 360 unsigned int delayAutounload:1; // for development 361 362 unsigned int CPPInitialized:1; 363 unsigned int jettisonLinkeditSeg:1; 364 unsigned int resetSegmentsFromImmutableCopy:1; 365 unsigned int unloadUnsupported:1; 366 unsigned int dextToReplace:1; 367 368 /* The Mach-O header contains segment addresses which are unslid. */ 369 unsigned int unslidMachO:1; 370 } flags; 371 372 uint32_t matchingRefCount; 373 kc_kind_t kc_type; 374 375 struct list_head pendingPgoHead; 376 uuid_t instance_uuid; 377 OSKextAccount * account; 378 uint32_t builtinKmodIdx; 379 OSPtr<OSArray> savedMutableSegments; 380 OSPtr<OSDextStatistics> dextStatistics; 381 OSPtr<OSData> dextUniqueID; 382 uint32_t dextLaunchedCount; 383 384 #if PRAGMA_MARK 385 /**************************************/ 386 #pragma mark Private Functions 387 /**************************************/ 388 #endif 389 390 #ifdef XNU_KERNEL_PRIVATE 391 /* Startup/shutdown phases. 392 */ 393 public: 394 static void initialize(void); 395 static OSPtr<OSDictionary> copyKexts(void); 396 static OSReturn removeKextBootstrap(void); 397 static void willShutdown(void);// called by IOPMrootDomain on shutdown 398 static void willUserspaceReboot(void); 399 static void resetAfterUserspaceReboot(void); 400 static void reportOSMetaClassInstances( 401 const char * kextIdentifier, 402 OSKextLogSpec msgLogSpec); 403 static void OSKextLogDriverKitInfoLoad(OSKext *kext); 404 static bool iokitDaemonAvailable(void); 405 #endif /* XNU_KERNEL_PRIVATE */ 406 407 private: 408 /* Called by power management at sleep/shutdown. 409 */ 410 static bool setLoadEnabled(bool flag); 411 static bool setUnloadEnabled(bool flag); 412 static bool setAutounloadsEnabled(bool flag); 413 static bool setKernelRequestsEnabled(bool flag); 414 415 // all getters subject to race condition, caller beware 416 static bool getLoadEnabled(void); 417 static bool getUnloadEnabled(void); 418 static bool getAutounloadEnabled(void); 419 static bool getKernelRequestsEnabled(void); 420 421 /* Instance life cycle. 422 */ 423 static OSData *parseDextUniqueID( 424 OSDictionary * anInfoDict, 425 const char *dextIDCS); 426 static void setDextUniqueIDInPersonalities( 427 OSDictionary * anInfoDict, 428 OSData * dextUniqueID); 429 430 static OSPtr<OSKext> withBooterData( 431 OSString * deviceTreeName, 432 OSData * booterData); 433 virtual bool initWithBooterData( 434 OSString * deviceTreeName, 435 OSData * booterData); 436 437 static OSPtr<OSKext> withPrelinkedInfoDict( 438 OSDictionary * infoDict, 439 bool doCoalesedSlides, kc_kind_t type); 440 virtual bool initWithPrelinkedInfoDict( 441 OSDictionary * infoDict, 442 bool doCoalesedSlides, kc_kind_t type); 443 static OSSharedPtr<OSKext> withCodelessInfo( 444 OSDictionary * infoDict, OSKextInitResult *result); 445 446 virtual OSKextInitResult initWithCodelessInfo( 447 OSDictionary * infoDict); 448 449 static void setAllVMAttributes(void); 450 451 virtual bool setInfoDictionaryAndPath( 452 OSDictionary * aDictionary, 453 OSString * aPath); 454 virtual bool setExecutable( 455 OSData * anExecutable, 456 OSData * externalData = NULL, 457 bool externalDataIsMkext = false); 458 virtual OSKextInitResult registerIdentifier(void); 459 460 virtual void free(void) APPLE_KEXT_OVERRIDE; 461 462 static OSReturn removeKext( 463 OSKext * aKext, 464 bool terminateServicesAndRemovePersonalitiesFlag = false); 465 466 virtual bool isInExcludeList(void); 467 virtual bool isLoadable(void); 468 469 static OSKext * allocAndInitFakeKext( 470 kmod_info_t *kmod_info); 471 472 /* Mkexts. 473 */ 474 #if CONFIG_KXLD 475 static OSPtr<OSKext> withMkext2Info( 476 OSDictionary * anInfoDict, 477 OSData * mkextData); 478 virtual bool initWithMkext2Info( 479 OSDictionary * anInfoDict, 480 OSData * mkextData); 481 482 static OSReturn readMkextArchive( 483 OSData * mkextData, 484 uint32_t * checksumPtr = NULL); 485 static OSReturn readMkext2Archive( 486 OSData * mkextData, 487 OSDictionary ** mkextPlistOut, 488 uint32_t * checksumPtr = NULL); 489 490 static OSReturn readMkext2Archive( 491 OSData * mkextData, 492 OSSharedPtr<OSDictionary> &mkextPlistOut, 493 uint32_t * checksumPtr = NULL); 494 495 virtual OSPtr<OSData> createMkext2FileEntry( 496 OSData * mkextData, 497 OSNumber * offsetNum, 498 const char * entryName); 499 virtual OSPtr<OSData> extractMkext2FileData( 500 UInt8 * data, 501 const char * name, 502 uint32_t compressedSize, 503 uint32_t fullSize); 504 #endif // CONFIG_KXLD 505 506 /* Dependencies. 507 */ 508 virtual bool resolveDependencies( 509 OSArray * loopStack = NULL); // priv/prot 510 virtual bool addBleedthroughDependencies(OSArray * anArray); 511 virtual bool flushDependencies(bool forceFlag = false); // priv/prot 512 virtual uint32_t getNumDependencies(void); 513 virtual OSArray * getDependencies(void); 514 515 /* User-space requests (load/generic). 516 */ 517 static OSReturn loadFromMkext( 518 OSKextLogSpec clientLogSpec, 519 char * mkextBuffer, 520 uint32_t mkextBufferLength, 521 char ** logInfoOut, 522 uint32_t * logInfoLengthOut); 523 static OSReturn handleRequest( 524 host_priv_t hostPriv, 525 OSKextLogSpec clientLogSpec, 526 char * requestBuffer, 527 uint32_t requestLength, 528 char ** responseOut, 529 uint32_t * responseLengthOut, 530 char ** logInfoOut, 531 uint32_t * logInfoLengthOut); 532 static OSReturn loadCodelessKext( 533 OSString * kextIdentifier, 534 OSDictionary * requestDict); 535 static OSReturn serializeLogInfo( 536 OSArray * logInfoArray, 537 char ** logInfoOut, 538 uint32_t * logInfoLengthOut); 539 540 /* Loading. 541 */ 542 static bool addKextsFromKextCollection(kernel_mach_header_t *mh, 543 OSDictionary *infoDict, const char *text_seg_name, 544 OSData **kcUUID, kc_kind_t type); 545 546 static bool addKextsFromKextCollection(kernel_mach_header_t *mh, 547 OSDictionary *infoDict, const char *text_seg_name, 548 OSSharedPtr<OSData> &kcUUID, kc_kind_t type); 549 550 static bool registerDeferredKextCollection(kernel_mach_header_t *mh, 551 OSSharedPtr<OSObject> &parsedXML, kc_kind_t type); 552 static OSSharedPtr<OSObject> consumeDeferredKextCollection(kc_kind_t type); 553 554 virtual OSReturn load( 555 OSKextExcludeLevel startOpt = kOSKextExcludeNone, 556 OSKextExcludeLevel startMatchingOpt = kOSKextExcludeAll, 557 OSArray * personalityNames = NULL);// priv/prot 558 virtual OSReturn unload(void); 559 static OSReturn queueKextNotification( 560 const char * notificationName, 561 OSString * kextIdentifier, 562 OSData * dextUniqueIdentifier); 563 564 static void recordIdentifierRequest( 565 OSString * kextIdentifier); 566 567 virtual OSReturn slidePrelinkedExecutable(bool doCoalesedSlides); 568 virtual OSReturn loadExecutable(void); 569 virtual void jettisonLinkeditSegment(void); 570 virtual void jettisonDATASegmentPadding(void); 571 static void considerDestroyingLinkContext(void); 572 virtual OSData * getExecutable(void); 573 virtual void setLinkedExecutable(OSData * anExecutable); 574 575 #if CONFIG_DTRACE 576 friend void OSKextRegisterKextsWithDTrace(void); 577 static void registerKextsWithDTrace(void); 578 virtual void registerWithDTrace(void); 579 virtual void unregisterWithDTrace(void); 580 #endif /* CONFIG_DTRACE */ 581 582 virtual OSReturn start(bool startDependenciesFlag = true); 583 virtual OSReturn stop(void); 584 virtual OSReturn setVMAttributes(bool protect, bool wire); 585 virtual boolean_t segmentShouldBeWired(kernel_segment_command_t *seg); 586 virtual OSReturn validateKextMapping(bool startFlag); 587 virtual boolean_t verifySegmentMapping(kernel_segment_command_t *seg); 588 589 static OSPtr<OSArray> copyAllKextPersonalities( 590 bool filterSafeBootFlag = false); 591 592 static void setPrelinkedPersonalities(OSArray * personalitiesArray); 593 594 static void sendAllKextPersonalitiesToCatalog( 595 bool startMatching = false); 596 virtual OSReturn sendPersonalitiesToCatalog( 597 bool startMatching = false, 598 OSArray * personalityNames = NULL); 599 600 static bool canUnloadKextWithIdentifier( 601 OSString * kextIdentifier, 602 bool checkClassesFlag = true); 603 604 static OSReturn autounloadKext(OSKext * aKext); 605 606 /* Sync with user space. 607 */ 608 static OSReturn pingIOKitDaemon(void); 609 static bool driverkitEnabled(void); 610 611 /* Getting info about loaded kexts (kextstat). 612 */ 613 static OSPtr<OSDictionary> copyLoadedKextInfo( 614 OSArray * kextIdentifiers = NULL, 615 OSArray * keys = NULL); 616 static OSPtr<OSDictionary> copyLoadedKextInfoByUUID( 617 OSArray * kextIdentifiers = NULL, 618 OSArray * keys = NULL); 619 static OSPtr<OSDictionary> copyKextCollectionInfo( 620 OSDictionary *requestDict, 621 OSArray *infoKeys = NULL); 622 static OSPtr<OSData> copyKextUUIDForAddress(OSNumber *address = NULL); 623 static OSPtr<OSArray> copyDextsInfo( 624 OSArray * kextIdentifiers = NULL, 625 OSArray * keys = NULL); 626 virtual OSPtr<OSDictionary> copyInfo(OSArray * keys = NULL); 627 628 /* Logging to user space. 629 */ 630 static OSKextLogSpec setUserSpaceLogFilter( 631 OSKextLogSpec userLogSpec, 632 bool captureFlag = false); 633 static OSPtr<OSArray> clearUserSpaceLogFilter(void); 634 static OSKextLogSpec getUserSpaceLogFilter(void); 635 636 /* OSMetaClasses defined by kext. 637 */ 638 virtual OSReturn addClass( 639 OSMetaClass * aClass, 640 uint32_t numClasses); 641 virtual OSReturn removeClass( 642 OSMetaClass * aClass); 643 virtual bool hasOSMetaClassInstances(void); 644 virtual OSSet * getMetaClasses(void); 645 646 virtual void reportOSMetaClassInstances( 647 OSKextLogSpec msgLogSpec); 648 649 /* Resource requests and other callback stuff. 650 */ 651 static OSReturn loadFileSetKexts(OSDictionary * requestDict); 652 653 static OSReturn loadKCFileSet(const char *filepath, kc_kind_t type); 654 655 #if defined(__x86_64__) || defined(__i386__) 656 static OSReturn mapKCFileSet( 657 void *control, 658 vm_size_t fsize, 659 kernel_mach_header_t **mh, 660 off_t file_offset, 661 uintptr_t *slide, 662 bool pageable, 663 void *map_entry_buffer); 664 static OSReturn protectKCFileSet( 665 kernel_mach_header_t *mh, 666 kc_kind_t type); 667 static OSReturn mapKCTextSegment( 668 void *control, 669 kernel_mach_header_t **mhp, 670 off_t file_offset, 671 uintptr_t *slide, 672 void *map_entry_list); 673 static void freeKCFileSetcontrol(void); 674 OSReturn resetKCFileSetSegments(void); 675 #endif //(__x86_64__) || defined(__i386__) 676 677 static void jettisonFileSetLinkeditSegment(kernel_mach_header_t *mh); 678 static OSReturn validateKCFileSetUUID( 679 OSDictionary *infoDict, 680 kc_kind_t type); 681 682 static OSReturn validateKCUUIDfromPrelinkInfo( 683 uuid_t *loaded_kcuuid, 684 kc_kind_t type, 685 OSDictionary *infoDict, 686 const char *uuid_key); 687 688 static OSReturn dispatchResource(OSDictionary * requestDict); 689 690 static OSReturn setMissingAuxKCBundles(OSDictionary * requestDict); 691 692 static OSReturn setAuxKCBundleAvailable(OSString *kextIdentifier, 693 OSDictionary *requestDict); 694 695 static OSReturn dequeueCallbackForRequestTag( 696 OSKextRequestTag requestTag, 697 LIBKERN_RETURNS_RETAINED OSDictionary ** callbackRecordOut); 698 static OSReturn dequeueCallbackForRequestTag( 699 OSNumber * requestTagNum, 700 LIBKERN_RETURNS_RETAINED OSDictionary ** callbackRecordOut); 701 702 static OSReturn dequeueCallbackForRequestTag( 703 OSKextRequestTag requestTag, 704 OSSharedPtr<OSDictionary> &callbackRecordOut); 705 static OSReturn dequeueCallbackForRequestTag( 706 OSNumber * requestTagNum, 707 OSSharedPtr<OSDictionary> &callbackRecordOut); 708 709 static void invokeRequestCallback( 710 OSDictionary * callbackRecord, 711 OSReturn requestResult); 712 virtual void invokeOrCancelRequestCallbacks( 713 OSReturn callbackResult, 714 bool invokeFlag = true); 715 virtual uint32_t countRequestCallbacks(void); 716 OSReturn resetMutableSegments(void); 717 virtual OSData * getDextUniqueID(void); 718 719 static bool upgradeDext( 720 OSKext * olddext, 721 OSKext * newdext); 722 static bool removeDext(OSKext * dext); 723 static void replaceDextInternal( 724 OSKext * olddext, 725 OSKext * newdext); 726 /* panic() support. 727 */ 728 public: 729 enum { 730 kPrintKextsLock = 0x01, 731 kPrintKextsUnslide = 0x02, 732 kPrintKextsTerse = 0x04 733 }; 734 static void printKextsInBacktrace( 735 vm_offset_t * addr, 736 unsigned int cnt, 737 int (* printf_func)(const char *fmt, ...), 738 uint32_t flags); 739 static void foreachKextInBacktrace( 740 vm_offset_t * addr, 741 uint32_t cnt, 742 uint32_t flags, 743 void (^ handler)(OSKextLoadedKextSummary *summary, uint32_t index)); 744 bool isDriverKit(void); 745 bool isInFileset(void); 746 private: 747 static OSKextLoadedKextSummary *summaryForAddress(const uintptr_t addr); 748 static kern_return_t summaryForAddressExt( 749 const void * addr, 750 OSKextLoadedKextSummary * summary); 751 static void *kextForAddress(const void *addr); 752 static boolean_t summaryIsInBacktrace( 753 OSKextLoadedKextSummary * summary, 754 vm_offset_t * addr, 755 unsigned int cnt); 756 static void printSummary( 757 OSKextLoadedKextSummary * summary, 758 int (* printf_func)(const char *fmt, ...), 759 uint32_t flags); 760 761 static int saveLoadedKextPanicListTyped( 762 const char * prefix, 763 int invertFlag, 764 int libsFlag, 765 char * paniclist, 766 uint32_t list_size); 767 static void saveLoadedKextPanicList(void); 768 void savePanicString(bool isLoading); 769 static void printKextPanicLists(int (*printf_func)(const char *fmt, ...)); 770 771 /* Kext summary support. 772 */ 773 static void updateLoadedKextSummaries(void); 774 void updateLoadedKextSummary(OSKextLoadedKextSummary *summary); 775 void updateActiveAccount(OSKextActiveAccount *accountp); 776 static void removeDaemonExitRequests(void); 777 778 #ifdef XNU_KERNEL_PRIVATE 779 public: 780 #endif /* XNU_KERNEL_PRIVATE */ 781 782 /* C++ Initialization. 783 */ 784 virtual void setCPPInitialized(bool initialized = true); 785 786 #if PRAGMA_MARK 787 /**************************************/ 788 #pragma mark Public Functions 789 /**************************************/ 790 #endif 791 public: 792 // caller must release 793 static OSPtr<OSKext> lookupKextWithIdentifier(const char * kextIdentifier); 794 static OSPtr<OSKext> lookupKextWithIdentifier(OSString * kextIdentifier); 795 static OSPtr<OSKext> lookupKextWithLoadTag(OSKextLoadTag aTag); 796 static OSPtr<OSKext> lookupKextWithAddress(vm_address_t address); 797 static OSPtr<OSKext> lookupKextWithUUID(uuid_t uuid); 798 static OSPtr<OSKext> lookupDextWithIdentifier(OSString * dextIdentifier, OSData *dextUniqueIdentifier); 799 800 kernel_section_t *lookupSection(const char *segname, const char*secname); 801 802 static bool isKextWithIdentifierLoaded(const char * kextIdentifier); 803 804 static OSReturn loadKextWithIdentifier( 805 const char * kextIdentifier, 806 Boolean allowDeferFlag = true, 807 Boolean delayAutounloadFlag = false, 808 OSKextExcludeLevel startOpt = kOSKextExcludeNone, 809 OSKextExcludeLevel startMatchingOpt = kOSKextExcludeAll, 810 OSArray * personalityNames = NULL); 811 812 static OSReturn loadKextWithIdentifier( 813 OSString * kextIdentifier, 814 LIBKERN_RETURNS_RETAINED_ON_ZERO OSObject ** kextRef, 815 Boolean allowDeferFlag = true, 816 Boolean delayAutounloadFlag = false, 817 OSKextExcludeLevel startOpt = kOSKextExcludeNone, 818 OSKextExcludeLevel startMatchingOpt = kOSKextExcludeAll, 819 OSArray * personalityNames = NULL); 820 821 static OSReturn loadKextWithIdentifier( 822 OSString * kextIdentifier, 823 OSSharedPtr<OSObject> &kextRef, 824 Boolean allowDeferFlag = true, 825 Boolean delayAutounloadFlag = false, 826 OSKextExcludeLevel startOpt = kOSKextExcludeNone, 827 OSKextExcludeLevel startMatchingOpt = kOSKextExcludeAll, 828 OSArray * personalityNames = NULL); 829 830 static OSReturn loadKextFromKC(OSKext *theKext, OSDictionary *requestDict); 831 832 static void dropMatchingReferences( 833 OSSet * kexts); 834 835 bool hasDependency(const OSSymbol * depID); 836 837 static OSReturn removeKextWithIdentifier( 838 const char * kextIdentifier, 839 bool terminateServicesAndRemovePersonalitiesFlag = false); 840 static OSReturn removeKextWithLoadTag( 841 OSKextLoadTag loadTag, 842 bool terminateServicesAndRemovePersonalitiesFlag = false); 843 static OSReturn requestDaemonLaunch( 844 OSString * kextIdentifier, 845 OSString * serverName, 846 OSNumber * serverTag, 847 OSBoolean * reslide, 848 class IOUserServerCheckInToken * checkInToken, 849 OSData *serverDUI); 850 static OSReturn notifyDextUpgrade( 851 OSString * kextIdentifier, 852 OSData * dextUniqueIdentifier); 853 static OSReturn requestResource( 854 const char * kextIdentifier, 855 const char * resourceName, 856 OSKextRequestResourceCallback callback, 857 void * context, 858 OSKextRequestTag * requestTagOut); 859 static OSReturn cancelRequest( 860 OSKextRequestTag requestTag, 861 void ** contextOut); 862 863 static void considerUnloads(Boolean rescheduleOnlyFlag = false); 864 static void flushNonloadedKexts(Boolean flushPrelinkedKexts); 865 static void setIOKitDaemonActive(bool active = true); 866 static void setDeferredLoadSucceeded(Boolean succeeded = true); 867 static void considerRebuildOfPrelinkedKernel(void); 868 static void createExcludeListFromBooterData( 869 OSDictionary * theDictionary, 870 OSCollectionIterator * theIterator); 871 static void createExcludeListFromPrelinkInfo(OSArray * theInfoArray); 872 static boolean_t updateExcludeList(OSDictionary * infoDict); 873 874 static bool pendingIOKitDaemonRequests(void); 875 876 virtual bool setAutounloadEnabled(bool flag); 877 878 virtual const OSObject * getBundleExecutable(void); 879 virtual const OSSymbol * getIdentifier(void); 880 virtual const char * getIdentifierCString(void); 881 virtual OSKextVersion getVersion(void); 882 virtual OSKextVersion getCompatibleVersion(void); 883 virtual bool isLibrary(void); 884 virtual bool isCompatibleWithVersion(OSKextVersion aVersion); 885 virtual OSObject * getPropertyForHostArch(const char * key); 886 887 virtual OSKextLoadTag getLoadTag(void); 888 virtual void getSizeInfo(uint32_t *loadSize, uint32_t *wiredSize); 889 virtual OSPtr<OSData> copyUUID(void); 890 OSPtr<OSData> copyTextUUID(void); 891 OSPtr<OSData> copyMachoUUID(const kernel_mach_header_t * header); 892 OSPtr<OSDextStatistics> copyDextStatistics(); 893 virtual OSPtr<OSArray> copyPersonalitiesArray(void); 894 static bool copyUserExecutablePath(const OSSymbol * bundleID, char * pathResult, size_t pathSize); 895 virtual void setDriverKitUUID(LIBKERN_CONSUMED OSData *uuid); 896 static bool incrementDextLaunchCount(OSKext *dext, OSData *dextUniqueIDToMatch); 897 static bool decrementDextLaunchCount(OSString *bundleID); 898 899 /* This removes personalities naming the kext (by CFBundleIdentifier), 900 * not all personalities defined by the kext (IOPersonalityPublisher or CFBundleIdentifier). 901 */ 902 virtual void removePersonalitiesFromCatalog(void); 903 /* 904 * This removes the personalities naming the kext (by CFBundleIdentifier), and atomically adds 905 * the new personalities upgradedPersonalities. 906 */ 907 virtual void updatePersonalitiesInCatalog(OSArray *upgradedPersonalities); 908 909 /* Converts common string-valued properties to OSSymbols for lower memory consumption. 910 */ 911 static void uniquePersonalityProperties(OSDictionary * personalityDict); 912 #ifdef XNU_KERNEL_PRIVATE 913 static void uniquePersonalityProperties(OSDictionary * personalityDict, bool defaultAddKernelBundleIdentifier); 914 #endif 915 916 static bool iokitDaemonActive(void); 917 918 virtual bool declaresExecutable(void); // might be missing 919 virtual bool isInterface(void); 920 virtual bool isKernel(void); 921 virtual bool isKernelComponent(void); 922 virtual bool isExecutable(void); 923 virtual bool isSpecialKernelBinary(void); 924 virtual bool isLoadableInSafeBoot(void); 925 virtual bool isPrelinked(void); 926 virtual bool isLoaded(void); 927 virtual bool isStarted(void); 928 virtual bool isCPPInitialized(void); 929 930 const char * getKCTypeString(void)931 getKCTypeString(void) 932 { 933 switch (kc_type) { 934 case KCKindPrimary: 935 return kKCTypePrimary; 936 case KCKindPageable: 937 return kKCTypeSystem; 938 case KCKindAuxiliary: 939 return kKCTypeAuxiliary; 940 case KCKindNone: 941 return kKCTypeCodeless; 942 default: 943 return "??"; 944 } 945 } 946 }; 947 948 extern "C" void OSKextResetAfterUserspaceReboot(void); 949 950 #endif /* !_LIBKERN_OSKEXT_H */ 951