1 /* 2 * Copyright (c) 2000-2012 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 extern "C" { 29 #include <mach/kmod.h> 30 #include <libkern/kernel_mach_header.h> 31 #include <libkern/prelink.h> 32 33 #if CONFIG_EMBEDDED 34 extern uuid_t kernelcache_uuid; 35 #endif 36 } 37 38 #include <libkern/version.h> 39 #include <libkern/c++/OSContainers.h> 40 #include <libkern/OSKextLibPrivate.h> 41 #include <libkern/c++/OSKext.h> 42 #include <IOKit/IOLib.h> 43 #include <IOKit/IOService.h> 44 #include <IOKit/IODeviceTreeSupport.h> 45 #include <IOKit/IOCatalogue.h> 46 47 #if __x86_64__ 48 #define KASLR_KEXT_DEBUG 0 49 #endif 50 51 #if PRAGMA_MARK 52 #pragma mark Bootstrap Declarations 53 #endif 54 /********************************************************************* 55 * Bootstrap Declarations 56 * 57 * The ENTIRE point of the libsa/KLD segment is to isolate bootstrap 58 * code from other parts of the kernel, so function symbols are not 59 * exported; rather pointers to those functions are exported. 60 * 61 * xxx - need to think about locking for handling the 'weak' refs. 62 * xxx - do export a non-KLD function that says you've called a 63 * xxx - bootstrap function that has been removed. 64 * 65 * ALL call-ins to this segment of the kernel must be done through 66 * exported pointers. The symbols themselves are private and not to 67 * be linked against. 68 *********************************************************************/ 69 extern "C" { 70 extern void (*record_startup_extensions_function)(void); 71 extern void (*load_security_extensions_function)(void); 72 }; 73 74 static void bootstrapRecordStartupExtensions(void); 75 static void bootstrapLoadSecurityExtensions(void); 76 77 78 #if NO_KEXTD 79 extern "C" bool IORamDiskBSDRoot(void); 80 #endif 81 82 #if PRAGMA_MARK 83 #pragma mark Macros 84 #endif 85 /********************************************************************* 86 * Macros 87 *********************************************************************/ 88 #define CONST_STRLEN(str) (sizeof(str) - 1) 89 90 #if PRAGMA_MARK 91 #pragma mark Kernel Component Kext Identifiers 92 #endif 93 /********************************************************************* 94 * Kernel Component Kext Identifiers 95 * 96 * We could have each kernel resource kext automatically "load" as 97 * it's created, but it's nicer to have them listed in kextstat in 98 * the order of this list. We'll walk through this after setting up 99 * all the boot kexts and have them load up. 100 *********************************************************************/ 101 static const char * sKernelComponentNames[] = { 102 // The kexts for these IDs must have a version matching 'osrelease'. 103 "com.apple.kernel", 104 "com.apple.kpi.bsd", 105 "com.apple.kpi.dsep", 106 "com.apple.kpi.iokit", 107 "com.apple.kpi.libkern", 108 "com.apple.kpi.mach", 109 "com.apple.kpi.private", 110 "com.apple.kpi.unsupported", 111 "com.apple.iokit.IONVRAMFamily", 112 "com.apple.driver.AppleNMI", 113 "com.apple.iokit.IOSystemManagementFamily", 114 "com.apple.iokit.ApplePlatformFamily", 115 NULL 116 }; 117 118 static int __whereIsAddr(vm_offset_t theAddr, unsigned long * segSizes, vm_offset_t *segAddrs, int segCount ); 119 120 #define PLK_SEGMENTS 12 121 122 static const char * plk_segNames[] = { 123 "__TEXT", 124 "__TEXT_EXEC", 125 "__DATA", 126 "__DATA_CONST", 127 "__LINKEDIT", 128 "__PRELINK_TEXT", 129 "__PLK_TEXT_EXEC", 130 "__PRELINK_DATA", 131 "__PLK_DATA_CONST", 132 "__PLK_LLVM_COV", 133 "__PLK_LINKEDIT", 134 "__PRELINK_INFO", 135 NULL 136 }; 137 138 #if PRAGMA_MARK 139 #pragma mark KLDBootstrap Class 140 #endif 141 /********************************************************************* 142 * KLDBootstrap Class 143 * 144 * We use a C++ class here so that it can be a friend of OSKext and 145 * get at private stuff. We can't hide the class itself, but we can 146 * hide the instance through which we invoke the functions. 147 *********************************************************************/ 148 class KLDBootstrap { 149 friend void bootstrapRecordStartupExtensions(void); 150 friend void bootstrapLoadSecurityExtensions(void); 151 152 private: 153 void readStartupExtensions(void); 154 155 void readPrelinkedExtensions( 156 kernel_section_t * prelinkInfoSect); 157 void readBooterExtensions(void); 158 159 OSReturn loadKernelComponentKexts(void); 160 void loadKernelExternalComponents(void); 161 void readBuiltinPersonalities(void); 162 163 void loadSecurityExtensions(void); 164 165 public: 166 KLDBootstrap(void); 167 ~KLDBootstrap(void); 168 }; 169 170 static KLDBootstrap sBootstrapObject; 171 172 /********************************************************************* 173 * Set the function pointers for the entry points into the bootstrap 174 * segment upon C++ static constructor invocation. 175 *********************************************************************/ 176 KLDBootstrap::KLDBootstrap(void) 177 { 178 if (this != &sBootstrapObject) { 179 panic("Attempt to access bootstrap segment."); 180 } 181 record_startup_extensions_function = &bootstrapRecordStartupExtensions; 182 load_security_extensions_function = &bootstrapLoadSecurityExtensions; 183 } 184 185 /********************************************************************* 186 * Clear the function pointers for the entry points into the bootstrap 187 * segment upon C++ static destructor invocation. 188 *********************************************************************/ 189 KLDBootstrap::~KLDBootstrap(void) 190 { 191 if (this != &sBootstrapObject) { 192 panic("Attempt to access bootstrap segment."); 193 } 194 195 196 record_startup_extensions_function = 0; 197 load_security_extensions_function = 0; 198 } 199 200 /********************************************************************* 201 *********************************************************************/ 202 void 203 KLDBootstrap::readStartupExtensions(void) 204 { 205 kernel_section_t * prelinkInfoSect = NULL; // do not free 206 207 OSKextLog(/* kext */ NULL, 208 kOSKextLogProgressLevel | 209 kOSKextLogGeneralFlag | kOSKextLogDirectoryScanFlag | 210 kOSKextLogKextBookkeepingFlag, 211 "Reading startup extensions."); 212 213 /* If the prelink info segment has a nonzero size, we are prelinked 214 * and won't have any individual kexts or mkexts to read. 215 * Otherwise, we need to read kexts or the mkext from what the booter 216 * has handed us. 217 */ 218 prelinkInfoSect = getsectbyname(kPrelinkInfoSegment, kPrelinkInfoSection); 219 if (prelinkInfoSect->size) { 220 readPrelinkedExtensions(prelinkInfoSect); 221 } else { 222 readBooterExtensions(); 223 } 224 225 loadKernelComponentKexts(); 226 loadKernelExternalComponents(); 227 readBuiltinPersonalities(); 228 OSKext::sendAllKextPersonalitiesToCatalog(); 229 230 return; 231 } 232 233 typedef struct kaslrPackedOffsets { 234 uint32_t count; /* number of offsets */ 235 uint32_t offsetsArray[]; /* offsets to slide */ 236 } kaslrPackedOffsets; 237 238 /********************************************************************* 239 *********************************************************************/ 240 void 241 KLDBootstrap::readPrelinkedExtensions( 242 kernel_section_t * prelinkInfoSect) 243 { 244 OSArray * infoDictArray = NULL; // do not release 245 OSObject * parsedXML = NULL; // must release 246 OSDictionary * prelinkInfoDict = NULL; // do not release 247 OSString * errorString = NULL; // must release 248 OSKext * theKernel = NULL; // must release 249 #if CONFIG_EMBEDDED 250 OSData * kernelcacheUUID = NULL; // do not release 251 #endif 252 253 kernel_segment_command_t * prelinkTextSegment = NULL; // see code 254 kernel_segment_command_t * prelinkInfoSegment = NULL; // see code 255 256 /* We make some copies of data, but if anything fails we're basically 257 * going to fail the boot, so these won't be cleaned up on error. 258 */ 259 void * prelinkData = NULL; // see code 260 vm_size_t prelinkLength = 0; 261 262 263 OSDictionary * infoDict = NULL; // do not release 264 265 IORegistryEntry * registryRoot = NULL; // do not release 266 OSNumber * prelinkCountObj = NULL; // must release 267 268 u_int i = 0; 269 #if NO_KEXTD 270 bool ramDiskBoot; 271 bool developerDevice; 272 bool dontLoad; 273 #endif 274 OSData * kaslrOffsets = NULL; 275 unsigned long plk_segSizes[PLK_SEGMENTS]; 276 vm_offset_t plk_segAddrs[PLK_SEGMENTS]; 277 278 OSKextLog(/* kext */ NULL, 279 kOSKextLogProgressLevel | 280 kOSKextLogDirectoryScanFlag | kOSKextLogArchiveFlag, 281 "Starting from prelinked kernel."); 282 283 prelinkTextSegment = getsegbyname(kPrelinkTextSegment); 284 if (!prelinkTextSegment) { 285 OSKextLog(/* kext */ NULL, 286 kOSKextLogErrorLevel | 287 kOSKextLogDirectoryScanFlag | kOSKextLogArchiveFlag, 288 "Can't find prelinked kexts' text segment."); 289 goto finish; 290 } 291 292 #if KASLR_KEXT_DEBUG 293 unsigned long scratchSize; 294 vm_offset_t scratchAddr; 295 296 IOLog("kaslr: prelinked kernel address info: \n"); 297 298 scratchAddr = (vm_offset_t) getsegdatafromheader(&_mh_execute_header, "__TEXT", &scratchSize); 299 IOLog("kaslr: start 0x%lx end 0x%lx length %lu for __TEXT \n", 300 (unsigned long)scratchAddr, 301 (unsigned long)(scratchAddr + scratchSize), 302 scratchSize); 303 304 scratchAddr = (vm_offset_t) getsegdatafromheader(&_mh_execute_header, "__DATA", &scratchSize); 305 IOLog("kaslr: start 0x%lx end 0x%lx length %lu for __DATA \n", 306 (unsigned long)scratchAddr, 307 (unsigned long)(scratchAddr + scratchSize), 308 scratchSize); 309 310 scratchAddr = (vm_offset_t) getsegdatafromheader(&_mh_execute_header, "__LINKEDIT", &scratchSize); 311 IOLog("kaslr: start 0x%lx end 0x%lx length %lu for __LINKEDIT \n", 312 (unsigned long)scratchAddr, 313 (unsigned long)(scratchAddr + scratchSize), 314 scratchSize); 315 316 scratchAddr = (vm_offset_t) getsegdatafromheader(&_mh_execute_header, "__KLD", &scratchSize); 317 IOLog("kaslr: start 0x%lx end 0x%lx length %lu for __KLD \n", 318 (unsigned long)scratchAddr, 319 (unsigned long)(scratchAddr + scratchSize), 320 scratchSize); 321 322 scratchAddr = (vm_offset_t) getsegdatafromheader(&_mh_execute_header, "__PRELINK_TEXT", &scratchSize); 323 IOLog("kaslr: start 0x%lx end 0x%lx length %lu for __PRELINK_TEXT \n", 324 (unsigned long)scratchAddr, 325 (unsigned long)(scratchAddr + scratchSize), 326 scratchSize); 327 328 scratchAddr = (vm_offset_t) getsegdatafromheader(&_mh_execute_header, "__PRELINK_INFO", &scratchSize); 329 IOLog("kaslr: start 0x%lx end 0x%lx length %lu for __PRELINK_INFO \n", 330 (unsigned long)scratchAddr, 331 (unsigned long)(scratchAddr + scratchSize), 332 scratchSize); 333 #endif 334 335 prelinkData = (void *) prelinkTextSegment->vmaddr; 336 prelinkLength = prelinkTextSegment->vmsize; 337 338 /* build arrays of plk info for later use */ 339 const char ** segNamePtr; 340 341 for (segNamePtr = &plk_segNames[0], i = 0; *segNamePtr && i < PLK_SEGMENTS; segNamePtr++, i++) { 342 plk_segSizes[i] = 0; 343 plk_segAddrs[i] = (vm_offset_t)getsegdatafromheader(&_mh_execute_header, *segNamePtr, &plk_segSizes[i]); 344 } 345 346 347 /* Unserialize the info dictionary from the prelink info section. 348 */ 349 parsedXML = OSUnserializeXML((const char *)prelinkInfoSect->addr, 350 &errorString); 351 if (parsedXML) { 352 prelinkInfoDict = OSDynamicCast(OSDictionary, parsedXML); 353 } 354 if (!prelinkInfoDict) { 355 const char * errorCString = "(unknown error)"; 356 357 if (errorString && errorString->getCStringNoCopy()) { 358 errorCString = errorString->getCStringNoCopy(); 359 } else if (parsedXML) { 360 errorCString = "not a dictionary"; 361 } 362 OSKextLog(/* kext */ NULL, kOSKextLogErrorLevel | kOSKextLogArchiveFlag, 363 "Error unserializing prelink plist: %s.", errorCString); 364 goto finish; 365 } 366 367 #if NO_KEXTD 368 /* Check if we should keep developer kexts around. 369 * TODO: Check DeviceTree instead of a boot-arg <rdar://problem/10604201> 370 */ 371 developerDevice = true; 372 PE_parse_boot_argn("developer", &developerDevice, sizeof(developerDevice)); 373 374 ramDiskBoot = IORamDiskBSDRoot(); 375 #endif /* NO_KEXTD */ 376 377 #if CONFIG_EMBEDDED 378 /* Copy in the kernelcache UUID */ 379 kernelcacheUUID = OSDynamicCast(OSData, 380 prelinkInfoDict->getObject(kPrelinkInfoKCIDKey)); 381 if (!kernelcacheUUID) { 382 bzero(&kernelcache_uuid, sizeof(kernelcache_uuid)); 383 } else if (kernelcacheUUID->getLength() != sizeof(kernelcache_uuid)) { 384 panic("kernelcacheUUID length is %d, expected %lu", kernelcacheUUID->getLength(), 385 sizeof(kernelcache_uuid)); 386 } else { 387 memcpy((void *)&kernelcache_uuid, (void *)kernelcacheUUID->getBytesNoCopy(), kernelcacheUUID->getLength()); 388 } 389 #endif /* CONFIG_EMBEDDED */ 390 391 infoDictArray = OSDynamicCast(OSArray, 392 prelinkInfoDict->getObject(kPrelinkInfoDictionaryKey)); 393 if (!infoDictArray) { 394 OSKextLog(/* kext */ NULL, kOSKextLogErrorLevel | kOSKextLogArchiveFlag, 395 "The prelinked kernel has no kext info dictionaries"); 396 goto finish; 397 } 398 399 /* kaslrOffsets are available use them to slide local relocations */ 400 kaslrOffsets = OSDynamicCast(OSData, 401 prelinkInfoDict->getObject(kPrelinkLinkKASLROffsetsKey)); 402 403 /* Create dictionary of excluded kexts 404 */ 405 #ifndef CONFIG_EMBEDDED 406 OSKext::createExcludeListFromPrelinkInfo(infoDictArray); 407 #endif 408 /* Create OSKext objects for each info dictionary. 409 */ 410 for (i = 0; i < infoDictArray->getCount(); ++i) { 411 infoDict = OSDynamicCast(OSDictionary, infoDictArray->getObject(i)); 412 if (!infoDict) { 413 OSKextLog(/* kext */ NULL, 414 kOSKextLogErrorLevel | 415 kOSKextLogDirectoryScanFlag | kOSKextLogArchiveFlag, 416 "Can't find info dictionary for prelinked kext #%d.", i); 417 continue; 418 } 419 420 #if NO_KEXTD 421 dontLoad = false; 422 423 /* If we're not on a developer device, skip and free developer kexts. 424 */ 425 if (developerDevice == false) { 426 OSBoolean *devOnlyBool = OSDynamicCast(OSBoolean, 427 infoDict->getObject(kOSBundleDeveloperOnlyKey)); 428 if (devOnlyBool == kOSBooleanTrue) { 429 dontLoad = true; 430 } 431 } 432 433 /* Skip and free kexts that are only needed when booted from a ram disk. 434 */ 435 if (ramDiskBoot == false) { 436 OSBoolean *ramDiskOnlyBool = OSDynamicCast(OSBoolean, 437 infoDict->getObject(kOSBundleRamDiskOnlyKey)); 438 if (ramDiskOnlyBool == kOSBooleanTrue) { 439 dontLoad = true; 440 } 441 } 442 443 if (dontLoad == true) { 444 OSString *bundleID = OSDynamicCast(OSString, 445 infoDict->getObject(kCFBundleIdentifierKey)); 446 if (bundleID) { 447 OSKextLog(NULL, kOSKextLogWarningLevel | kOSKextLogGeneralFlag, 448 "Kext %s not loading.", bundleID->getCStringNoCopy()); 449 } 450 451 OSNumber *addressNum = OSDynamicCast(OSNumber, 452 infoDict->getObject(kPrelinkExecutableLoadKey)); 453 OSNumber *lengthNum = OSDynamicCast(OSNumber, 454 infoDict->getObject(kPrelinkExecutableSizeKey)); 455 if (addressNum && lengthNum) { 456 #if __arm__ || __arm64__ 457 vm_offset_t data = (vm_offset_t) ((addressNum->unsigned64BitValue()) + vm_kernel_slide); 458 vm_size_t length = (vm_size_t) (lengthNum->unsigned32BitValue()); 459 ml_static_mfree(data, length); 460 #else 461 #error Pick the right way to free prelinked data on this arch 462 #endif 463 } 464 465 infoDictArray->removeObject(i--); 466 continue; 467 } 468 #endif /* NO_KEXTD */ 469 470 /* Create the kext for the entry, then release it, because the 471 * kext system keeps them around until explicitly removed. 472 * Any creation/registration failures are already logged for us. 473 */ 474 OSKext * newKext = OSKext::withPrelinkedInfoDict(infoDict, (kaslrOffsets ? TRUE : FALSE)); 475 OSSafeReleaseNULL(newKext); 476 } 477 478 /* slide kxld relocations */ 479 if (kaslrOffsets && vm_kernel_slide > 0) { 480 int slidKextAddrCount = 0; 481 int badSlideAddr = 0; 482 int badSlideTarget = 0; 483 484 kaslrPackedOffsets * myOffsets = NULL; 485 myOffsets = (kaslrPackedOffsets *) kaslrOffsets->getBytesNoCopy(); 486 487 for (uint32_t j = 0; j < myOffsets->count; j++) { 488 489 uint64_t slideOffset = (uint64_t) myOffsets->offsetsArray[j]; 490 uintptr_t * slideAddr = (uintptr_t *) ((uint64_t)prelinkData + slideOffset); 491 int slideAddrSegIndex = -1; 492 int addrToSlideSegIndex = -1; 493 494 slideAddrSegIndex = __whereIsAddr( (vm_offset_t)slideAddr, &plk_segSizes[0], &plk_segAddrs[0], PLK_SEGMENTS ); 495 if (slideAddrSegIndex >= 0) { 496 addrToSlideSegIndex = __whereIsAddr( (vm_offset_t)(*slideAddr + vm_kernel_slide), &plk_segSizes[0], &plk_segAddrs[0], PLK_SEGMENTS ); 497 if (addrToSlideSegIndex < 0) { 498 badSlideTarget++; 499 continue; 500 } 501 } 502 else { 503 badSlideAddr++; 504 continue; 505 } 506 507 slidKextAddrCount++; 508 *(slideAddr) += vm_kernel_slide; 509 } // for ... 510 511 /* All kexts are now slid, set VM protections for them */ 512 OSKext::setAllVMAttributes(); 513 } 514 515 /* Store the number of prelinked kexts in the registry so we can tell 516 * when the system has been started from a prelinked kernel. 517 */ 518 registryRoot = IORegistryEntry::getRegistryRoot(); 519 assert(registryRoot); 520 521 prelinkCountObj = OSNumber::withNumber( 522 (unsigned long long)infoDictArray->getCount(), 523 8 * sizeof(uint32_t)); 524 assert(prelinkCountObj); 525 if (prelinkCountObj) { 526 registryRoot->setProperty(kOSPrelinkKextCountKey, prelinkCountObj); 527 } 528 529 OSKextLog(/* kext */ NULL, 530 kOSKextLogProgressLevel | 531 kOSKextLogGeneralFlag | kOSKextLogKextBookkeepingFlag | 532 kOSKextLogDirectoryScanFlag | kOSKextLogArchiveFlag, 533 "%u prelinked kexts", 534 infoDictArray->getCount()); 535 536 #if CONFIG_KEXT_BASEMENT 537 /* On CONFIG_KEXT_BASEMENT systems, kexts are copied to their own 538 * special VM region during OSKext init time, so we can free the whole 539 * segment now. 540 */ 541 ml_static_mfree((vm_offset_t) prelinkData, prelinkLength); 542 #endif /* __x86_64__ */ 543 544 /* Free the prelink info segment, we're done with it. 545 */ 546 prelinkInfoSegment = getsegbyname(kPrelinkInfoSegment); 547 if (prelinkInfoSegment) { 548 ml_static_mfree((vm_offset_t)prelinkInfoSegment->vmaddr, 549 (vm_size_t)prelinkInfoSegment->vmsize); 550 } 551 552 finish: 553 OSSafeReleaseNULL(errorString); 554 OSSafeReleaseNULL(parsedXML); 555 OSSafeReleaseNULL(theKernel); 556 OSSafeReleaseNULL(prelinkCountObj); 557 return; 558 } 559 560 static int __whereIsAddr(vm_offset_t theAddr, unsigned long * segSizes, vm_offset_t *segAddrs, int segCount) 561 { 562 int i; 563 564 for (i = 0; i < segCount; i++) { 565 vm_offset_t myAddr = *(segAddrs + i); 566 unsigned long mySize = *(segSizes + i); 567 568 if (theAddr >= myAddr && theAddr < (myAddr + mySize)) { 569 return i; 570 } 571 } 572 573 return -1; 574 } 575 576 577 /********************************************************************* 578 *********************************************************************/ 579 #define BOOTER_KEXT_PREFIX "Driver-" 580 581 typedef struct _DeviceTreeBuffer { 582 uint32_t paddr; 583 uint32_t length; 584 } _DeviceTreeBuffer; 585 586 void 587 KLDBootstrap::readBooterExtensions(void) 588 { 589 IORegistryEntry * booterMemoryMap = NULL; // must release 590 OSDictionary * propertyDict = NULL; // must release 591 OSCollectionIterator * keyIterator = NULL; // must release 592 OSString * deviceTreeName = NULL; // do not release 593 594 const _DeviceTreeBuffer * deviceTreeBuffer = NULL; // do not free 595 char * booterDataPtr = NULL; // do not free 596 OSData * booterData = NULL; // must release 597 598 OSKext * aKext = NULL; // must release 599 600 OSKextLog(/* kext */ NULL, 601 kOSKextLogProgressLevel | 602 kOSKextLogDirectoryScanFlag | kOSKextLogKextBookkeepingFlag, 603 "Reading startup extensions from booter memory."); 604 605 booterMemoryMap = IORegistryEntry::fromPath( "/chosen/memory-map", gIODTPlane); 606 607 if (!booterMemoryMap) { 608 OSKextLog(/* kext */ NULL, 609 kOSKextLogErrorLevel | 610 kOSKextLogGeneralFlag | kOSKextLogDirectoryScanFlag, 611 "Can't read booter memory map."); 612 goto finish; 613 } 614 615 propertyDict = booterMemoryMap->dictionaryWithProperties(); 616 if (!propertyDict) { 617 OSKextLog(/* kext */ NULL, 618 kOSKextLogErrorLevel | 619 kOSKextLogDirectoryScanFlag, 620 "Can't get property dictionary from memory map."); 621 goto finish; 622 } 623 624 keyIterator = OSCollectionIterator::withCollection(propertyDict); 625 if (!keyIterator) { 626 OSKextLog(/* kext */ NULL, 627 kOSKextLogErrorLevel | 628 kOSKextLogGeneralFlag, 629 "Can't allocate iterator for driver images."); 630 goto finish; 631 } 632 633 /* Create dictionary of excluded kexts 634 */ 635 #ifndef CONFIG_EMBEDDED 636 OSKext::createExcludeListFromBooterData(propertyDict, keyIterator); 637 #endif 638 keyIterator->reset(); 639 640 while ( ( deviceTreeName = 641 OSDynamicCast(OSString, keyIterator->getNextObject() ))) { 642 643 const char * devTreeNameCString = deviceTreeName->getCStringNoCopy(); 644 OSData * deviceTreeEntry = OSDynamicCast(OSData, 645 propertyDict->getObject(deviceTreeName)); 646 647 /* Clear out the booterData from the prior iteration. 648 */ 649 OSSafeReleaseNULL(booterData); 650 651 /* If there is no entry for the name, we can't do much with it. */ 652 if (!deviceTreeEntry) { 653 continue; 654 } 655 656 /* Make sure it is a kext */ 657 if (strncmp(devTreeNameCString, 658 BOOTER_KEXT_PREFIX, 659 CONST_STRLEN(BOOTER_KEXT_PREFIX))) { 660 continue; 661 } 662 663 deviceTreeBuffer = (const _DeviceTreeBuffer *) 664 deviceTreeEntry->getBytesNoCopy(0, sizeof(deviceTreeBuffer)); 665 if (!deviceTreeBuffer) { 666 /* We can't get to the data, so we can't do anything, 667 * not even free it from physical memory (if it's there). 668 */ 669 OSKextLog(/* kext */ NULL, 670 kOSKextLogErrorLevel | 671 kOSKextLogDirectoryScanFlag, 672 "Device tree entry %s has NULL pointer.", 673 devTreeNameCString); 674 goto finish; // xxx - continue, panic? 675 } 676 677 booterDataPtr = (char *)ml_static_ptovirt(deviceTreeBuffer->paddr); 678 if (!booterDataPtr) { 679 OSKextLog(/* kext */ NULL, 680 kOSKextLogErrorLevel | 681 kOSKextLogDirectoryScanFlag, 682 "Can't get virtual address for device tree entry %s.", 683 devTreeNameCString); 684 goto finish; 685 } 686 687 /* Wrap the booter data buffer in an OSData and set a dealloc function 688 * so it will take care of the physical memory when freed. Kexts will 689 * retain the booterData for as long as they need it. Remove the entry 690 * from the booter memory map after this is done. 691 */ 692 booterData = OSData::withBytesNoCopy(booterDataPtr, 693 deviceTreeBuffer->length); 694 if (!booterData) { 695 OSKextLog(/* kext */ NULL, 696 kOSKextLogErrorLevel | 697 kOSKextLogGeneralFlag, 698 "Error - Can't allocate OSData wrapper for device tree entry %s.", 699 devTreeNameCString); 700 goto finish; 701 } 702 booterData->setDeallocFunction(osdata_phys_free); 703 704 /* Create the kext for the entry, then release it, because the 705 * kext system keeps them around until explicitly removed. 706 * Any creation/registration failures are already logged for us. 707 */ 708 OSKext * newKext = OSKext::withBooterData(deviceTreeName, booterData); 709 OSSafeReleaseNULL(newKext); 710 711 booterMemoryMap->removeProperty(deviceTreeName); 712 713 } /* while ( (deviceTreeName = OSDynamicCast(OSString, ...) ) ) */ 714 715 finish: 716 717 OSSafeReleaseNULL(booterMemoryMap); 718 OSSafeReleaseNULL(propertyDict); 719 OSSafeReleaseNULL(keyIterator); 720 OSSafeReleaseNULL(booterData); 721 OSSafeReleaseNULL(aKext); 722 return; 723 } 724 725 /********************************************************************* 726 *********************************************************************/ 727 #define COM_APPLE "com.apple." 728 729 void 730 KLDBootstrap::loadSecurityExtensions(void) 731 { 732 OSDictionary * extensionsDict = NULL; // must release 733 OSCollectionIterator * keyIterator = NULL; // must release 734 OSString * bundleID = NULL; // don't release 735 OSKext * theKext = NULL; // don't release 736 OSBoolean * isSecurityKext = NULL; // don't release 737 738 OSKextLog(/* kext */ NULL, 739 kOSKextLogStepLevel | 740 kOSKextLogLoadFlag, 741 "Loading security extensions."); 742 743 extensionsDict = OSKext::copyKexts(); 744 if (!extensionsDict) { 745 return; 746 } 747 748 keyIterator = OSCollectionIterator::withCollection(extensionsDict); 749 if (!keyIterator) { 750 OSKextLog(/* kext */ NULL, 751 kOSKextLogErrorLevel | 752 kOSKextLogGeneralFlag, 753 "Failed to allocate iterator for security extensions."); 754 goto finish; 755 } 756 757 while ((bundleID = OSDynamicCast(OSString, keyIterator->getNextObject()))) { 758 759 const char * bundle_id = bundleID->getCStringNoCopy(); 760 761 /* Skip extensions whose bundle IDs don't start with "com.apple.". 762 */ 763 if (!bundle_id || 764 (strncmp(bundle_id, COM_APPLE, CONST_STRLEN(COM_APPLE)) != 0)) { 765 766 continue; 767 } 768 769 theKext = OSDynamicCast(OSKext, extensionsDict->getObject(bundleID)); 770 if (!theKext) { 771 continue; 772 } 773 774 isSecurityKext = OSDynamicCast(OSBoolean, 775 theKext->getPropertyForHostArch(kAppleSecurityExtensionKey)); 776 if (isSecurityKext && isSecurityKext->isTrue()) { 777 OSKextLog(/* kext */ NULL, 778 kOSKextLogStepLevel | 779 kOSKextLogLoadFlag, 780 "Loading security extension %s.", bundleID->getCStringNoCopy()); 781 OSKext::loadKextWithIdentifier(bundleID->getCStringNoCopy(), 782 /* allowDefer */ false); 783 } 784 } 785 786 finish: 787 OSSafeReleaseNULL(keyIterator); 788 OSSafeReleaseNULL(extensionsDict); 789 790 return; 791 } 792 793 /********************************************************************* 794 * We used to require that all listed kernel components load, but 795 * nowadays we can get them from userland so we only try to load the 796 * ones we have. If an error occurs later, such is life. 797 * 798 * Note that we look the kexts up first, so we can avoid spurious 799 * (in this context, anyhow) log messages about kexts not being found. 800 * 801 * xxx - do we even need to do this any more? Check if the kernel 802 * xxx - compoonents just load in the regular paths 803 *********************************************************************/ 804 OSReturn 805 KLDBootstrap::loadKernelComponentKexts(void) 806 { 807 OSReturn result = kOSReturnSuccess; // optimistic 808 OSKext * theKext = NULL; // must release 809 const char ** kextIDPtr = NULL; // do not release 810 811 for (kextIDPtr = &sKernelComponentNames[0]; *kextIDPtr; kextIDPtr++) { 812 813 OSSafeReleaseNULL(theKext); 814 theKext = OSKext::lookupKextWithIdentifier(*kextIDPtr); 815 816 if (theKext) { 817 if (kOSReturnSuccess != OSKext::loadKextWithIdentifier( 818 *kextIDPtr, /* allowDefer */ false)) { 819 820 // xxx - check KextBookkeeping, might be redundant 821 OSKextLog(/* kext */ NULL, 822 kOSKextLogErrorLevel | 823 kOSKextLogDirectoryScanFlag | kOSKextLogKextBookkeepingFlag, 824 "Failed to initialize kernel component %s.", *kextIDPtr); 825 result = kOSReturnError; 826 } 827 } 828 } 829 830 OSSafeReleaseNULL(theKext); 831 return result; 832 } 833 834 /********************************************************************* 835 * Ensure that Kernel External Components are loaded early in boot, 836 * before other kext personalities get sent to the IOCatalogue. These 837 * kexts are treated specially because they may provide the implementation 838 * for kernel-vended KPI, so they must register themselves before 839 * general purpose IOKit probing begins. 840 *********************************************************************/ 841 842 #define COM_APPLE_KEC "com.apple.kec." 843 844 void 845 KLDBootstrap::loadKernelExternalComponents(void) 846 { 847 OSDictionary * extensionsDict = NULL; // must release 848 OSCollectionIterator * keyIterator = NULL; // must release 849 OSString * bundleID = NULL; // don't release 850 OSKext * theKext = NULL; // don't release 851 OSBoolean * isKernelExternalComponent = NULL; // don't release 852 853 OSKextLog(/* kext */ NULL, 854 kOSKextLogStepLevel | 855 kOSKextLogLoadFlag, 856 "Loading Kernel External Components."); 857 858 extensionsDict = OSKext::copyKexts(); 859 if (!extensionsDict) { 860 return; 861 } 862 863 keyIterator = OSCollectionIterator::withCollection(extensionsDict); 864 if (!keyIterator) { 865 OSKextLog(/* kext */ NULL, 866 kOSKextLogErrorLevel | 867 kOSKextLogGeneralFlag, 868 "Failed to allocate iterator for Kernel External Components."); 869 goto finish; 870 } 871 872 while ((bundleID = OSDynamicCast(OSString, keyIterator->getNextObject()))) { 873 874 const char * bundle_id = bundleID->getCStringNoCopy(); 875 876 /* Skip extensions whose bundle IDs don't start with "com.apple.kec.". 877 */ 878 if (!bundle_id || 879 (strncmp(bundle_id, COM_APPLE_KEC, CONST_STRLEN(COM_APPLE_KEC)) != 0)) { 880 881 continue; 882 } 883 884 theKext = OSDynamicCast(OSKext, extensionsDict->getObject(bundleID)); 885 if (!theKext) { 886 continue; 887 } 888 889 isKernelExternalComponent = OSDynamicCast(OSBoolean, 890 theKext->getPropertyForHostArch(kAppleKernelExternalComponentKey)); 891 if (isKernelExternalComponent && isKernelExternalComponent->isTrue()) { 892 OSKextLog(/* kext */ NULL, 893 kOSKextLogStepLevel | 894 kOSKextLogLoadFlag, 895 "Loading kernel external component %s.", bundleID->getCStringNoCopy()); 896 OSKext::loadKextWithIdentifier(bundleID->getCStringNoCopy(), 897 /* allowDefer */ false); 898 } 899 } 900 901 finish: 902 OSSafeReleaseNULL(keyIterator); 903 OSSafeReleaseNULL(extensionsDict); 904 905 return; 906 } 907 908 /********************************************************************* 909 *********************************************************************/ 910 void 911 KLDBootstrap::readBuiltinPersonalities(void) 912 { 913 OSObject * parsedXML = NULL; // must release 914 OSArray * builtinExtensions = NULL; // do not release 915 OSArray * allPersonalities = NULL; // must release 916 OSString * errorString = NULL; // must release 917 kernel_section_t * infosect = NULL; // do not free 918 OSCollectionIterator * personalitiesIterator = NULL; // must release 919 unsigned int count, i; 920 921 OSKextLog(/* kext */ NULL, 922 kOSKextLogStepLevel | 923 kOSKextLogLoadFlag, 924 "Reading built-in kernel personalities for I/O Kit drivers."); 925 926 /* Look in the __BUILTIN __info segment for an array of Info.plist 927 * entries. For each one, extract the personalities dictionary, add 928 * it to our array, then push them all (without matching) to 929 * the IOCatalogue. This can be used to augment the personalities 930 * in gIOKernelConfigTables, especially when linking entire kexts into 931 * the mach_kernel image. 932 */ 933 infosect = getsectbyname("__BUILTIN", "__info"); 934 if (!infosect) { 935 // this isn't fatal 936 goto finish; 937 } 938 939 parsedXML = OSUnserializeXML((const char *) (uintptr_t)infosect->addr, 940 &errorString); 941 if (parsedXML) { 942 builtinExtensions = OSDynamicCast(OSArray, parsedXML); 943 } 944 if (!builtinExtensions) { 945 const char * errorCString = "(unknown error)"; 946 947 if (errorString && errorString->getCStringNoCopy()) { 948 errorCString = errorString->getCStringNoCopy(); 949 } else if (parsedXML) { 950 errorCString = "not an array"; 951 } 952 OSKextLog(/* kext */ NULL, 953 kOSKextLogErrorLevel | 954 kOSKextLogLoadFlag, 955 "Error unserializing built-in personalities: %s.", errorCString); 956 goto finish; 957 } 958 959 // estimate 3 personalities per Info.plist/kext 960 count = builtinExtensions->getCount(); 961 allPersonalities = OSArray::withCapacity(count * 3); 962 963 for (i = 0; i < count; i++) { 964 OSDictionary * infoDict = NULL; // do not release 965 OSString * moduleName = NULL; // do not release 966 OSDictionary * personalities; // do not release 967 OSString * personalityName; // do not release 968 969 OSSafeReleaseNULL(personalitiesIterator); 970 971 infoDict = OSDynamicCast(OSDictionary, 972 builtinExtensions->getObject(i)); 973 if (!infoDict) { 974 continue; 975 } 976 977 moduleName = OSDynamicCast(OSString, 978 infoDict->getObject(kCFBundleIdentifierKey)); 979 if (!moduleName) { 980 continue; 981 } 982 983 OSKextLog(/* kext */ NULL, 984 kOSKextLogStepLevel | 985 kOSKextLogLoadFlag, 986 "Adding personalities for built-in driver %s:", 987 moduleName->getCStringNoCopy()); 988 989 personalities = OSDynamicCast(OSDictionary, 990 infoDict->getObject("IOKitPersonalities")); 991 if (!personalities) { 992 continue; 993 } 994 995 personalitiesIterator = OSCollectionIterator::withCollection(personalities); 996 if (!personalitiesIterator) { 997 continue; // xxx - well really, what can we do? should we panic? 998 } 999 1000 while ((personalityName = OSDynamicCast(OSString, 1001 personalitiesIterator->getNextObject()))) { 1002 1003 OSDictionary * personality = OSDynamicCast(OSDictionary, 1004 personalities->getObject(personalityName)); 1005 1006 OSKextLog(/* kext */ NULL, 1007 kOSKextLogDetailLevel | 1008 kOSKextLogLoadFlag, 1009 "Adding built-in driver personality %s.", 1010 personalityName->getCStringNoCopy()); 1011 1012 if (personality && !personality->getObject(kCFBundleIdentifierKey)) { 1013 personality->setObject(kCFBundleIdentifierKey, moduleName); 1014 } 1015 allPersonalities->setObject(personality); 1016 } 1017 } 1018 1019 gIOCatalogue->addDrivers(allPersonalities, false); 1020 1021 finish: 1022 OSSafeReleaseNULL(parsedXML); 1023 OSSafeReleaseNULL(allPersonalities); 1024 OSSafeReleaseNULL(errorString); 1025 OSSafeReleaseNULL(personalitiesIterator); 1026 return; 1027 } 1028 1029 #if PRAGMA_MARK 1030 #pragma mark Bootstrap Functions 1031 #endif 1032 /********************************************************************* 1033 * Bootstrap Functions 1034 *********************************************************************/ 1035 static void bootstrapRecordStartupExtensions(void) 1036 { 1037 sBootstrapObject.readStartupExtensions(); 1038 return; 1039 } 1040 1041 static void bootstrapLoadSecurityExtensions(void) 1042 { 1043 sBootstrapObject.loadSecurityExtensions(); 1044 return; 1045 } 1046 1047