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