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 LIBKERN_ALWAYS_DESTROY 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 = NULL; 194 load_security_extensions_function = NULL; 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 uint64_t slideOffset = (uint64_t) myOffsets->offsetsArray[j]; 484 uintptr_t * slideAddr = (uintptr_t *) ((uint64_t)prelinkData + slideOffset); 485 int slideAddrSegIndex = -1; 486 int addrToSlideSegIndex = -1; 487 488 slideAddrSegIndex = __whereIsAddr((vm_offset_t)slideAddr, &plk_segSizes[0], &plk_segAddrs[0], PLK_SEGMENTS ); 489 if (slideAddrSegIndex >= 0) { 490 addrToSlideSegIndex = __whereIsAddr(ml_static_slide((vm_offset_t)(*slideAddr)), &plk_segSizes[0], &plk_segAddrs[0], PLK_SEGMENTS ); 491 if (addrToSlideSegIndex < 0) { 492 badSlideTarget++; 493 continue; 494 } 495 } else { 496 badSlideAddr++; 497 continue; 498 } 499 500 slidKextAddrCount++; 501 *slideAddr = ml_static_slide(*slideAddr); 502 } // for ... 503 504 /* All kexts are now slid, set VM protections for them */ 505 OSKext::setAllVMAttributes(); 506 } 507 508 /* Store the number of prelinked kexts in the registry so we can tell 509 * when the system has been started from a prelinked kernel. 510 */ 511 registryRoot = IORegistryEntry::getRegistryRoot(); 512 assert(registryRoot); 513 514 prelinkCountObj = OSNumber::withNumber( 515 (unsigned long long)infoDictArray->getCount(), 516 8 * sizeof(uint32_t)); 517 assert(prelinkCountObj); 518 if (prelinkCountObj) { 519 registryRoot->setProperty(kOSPrelinkKextCountKey, prelinkCountObj); 520 } 521 522 OSKextLog(/* kext */ NULL, 523 kOSKextLogProgressLevel | 524 kOSKextLogGeneralFlag | kOSKextLogKextBookkeepingFlag | 525 kOSKextLogDirectoryScanFlag | kOSKextLogArchiveFlag, 526 "%u prelinked kexts", 527 infoDictArray->getCount()); 528 529 #if CONFIG_KEXT_BASEMENT 530 /* On CONFIG_KEXT_BASEMENT systems, kexts are copied to their own 531 * special VM region during OSKext init time, so we can free the whole 532 * segment now. 533 */ 534 ml_static_mfree((vm_offset_t) prelinkData, prelinkLength); 535 #endif /* __x86_64__ */ 536 537 /* Free the prelink info segment, we're done with it. 538 */ 539 prelinkInfoSegment = getsegbyname(kPrelinkInfoSegment); 540 if (prelinkInfoSegment) { 541 ml_static_mfree((vm_offset_t)prelinkInfoSegment->vmaddr, 542 (vm_size_t)prelinkInfoSegment->vmsize); 543 } 544 545 finish: 546 OSSafeReleaseNULL(errorString); 547 OSSafeReleaseNULL(parsedXML); 548 OSSafeReleaseNULL(theKernel); 549 OSSafeReleaseNULL(prelinkCountObj); 550 return; 551 } 552 553 static int 554 __whereIsAddr(vm_offset_t theAddr, unsigned long * segSizes, vm_offset_t *segAddrs, int segCount) 555 { 556 int i; 557 558 for (i = 0; i < segCount; i++) { 559 vm_offset_t myAddr = *(segAddrs + i); 560 unsigned long mySize = *(segSizes + i); 561 562 if (theAddr >= myAddr && theAddr < (myAddr + mySize)) { 563 return i; 564 } 565 } 566 567 return -1; 568 } 569 570 571 /********************************************************************* 572 *********************************************************************/ 573 #define BOOTER_KEXT_PREFIX "Driver-" 574 575 typedef struct _DeviceTreeBuffer { 576 uint32_t paddr; 577 uint32_t length; 578 } _DeviceTreeBuffer; 579 580 void 581 KLDBootstrap::readBooterExtensions(void) 582 { 583 IORegistryEntry * booterMemoryMap = NULL;// must release 584 OSDictionary * propertyDict = NULL;// must release 585 OSCollectionIterator * keyIterator = NULL;// must release 586 OSString * deviceTreeName = NULL;// do not release 587 588 const _DeviceTreeBuffer * deviceTreeBuffer = NULL;// do not free 589 char * booterDataPtr = NULL;// do not free 590 OSData * booterData = NULL;// must release 591 592 OSKext * aKext = NULL;// must release 593 594 OSKextLog(/* kext */ NULL, 595 kOSKextLogProgressLevel | 596 kOSKextLogDirectoryScanFlag | kOSKextLogKextBookkeepingFlag, 597 "Reading startup extensions from booter memory."); 598 599 booterMemoryMap = IORegistryEntry::fromPath( "/chosen/memory-map", gIODTPlane); 600 601 if (!booterMemoryMap) { 602 OSKextLog(/* kext */ NULL, 603 kOSKextLogErrorLevel | 604 kOSKextLogGeneralFlag | kOSKextLogDirectoryScanFlag, 605 "Can't read booter memory map."); 606 goto finish; 607 } 608 609 propertyDict = booterMemoryMap->dictionaryWithProperties(); 610 if (!propertyDict) { 611 OSKextLog(/* kext */ NULL, 612 kOSKextLogErrorLevel | 613 kOSKextLogDirectoryScanFlag, 614 "Can't get property dictionary from memory map."); 615 goto finish; 616 } 617 618 keyIterator = OSCollectionIterator::withCollection(propertyDict); 619 if (!keyIterator) { 620 OSKextLog(/* kext */ NULL, 621 kOSKextLogErrorLevel | 622 kOSKextLogGeneralFlag, 623 "Can't allocate iterator for driver images."); 624 goto finish; 625 } 626 627 /* Create dictionary of excluded kexts 628 */ 629 #ifndef CONFIG_EMBEDDED 630 OSKext::createExcludeListFromBooterData(propertyDict, keyIterator); 631 #endif 632 keyIterator->reset(); 633 634 while ((deviceTreeName = 635 OSDynamicCast(OSString, keyIterator->getNextObject()))) { 636 const char * devTreeNameCString = deviceTreeName->getCStringNoCopy(); 637 OSData * deviceTreeEntry = OSDynamicCast(OSData, 638 propertyDict->getObject(deviceTreeName)); 639 640 /* Clear out the booterData from the prior iteration. 641 */ 642 OSSafeReleaseNULL(booterData); 643 644 /* If there is no entry for the name, we can't do much with it. */ 645 if (!deviceTreeEntry) { 646 continue; 647 } 648 649 /* Make sure it is a kext */ 650 if (strncmp(devTreeNameCString, 651 BOOTER_KEXT_PREFIX, 652 CONST_STRLEN(BOOTER_KEXT_PREFIX))) { 653 continue; 654 } 655 656 deviceTreeBuffer = (const _DeviceTreeBuffer *) 657 deviceTreeEntry->getBytesNoCopy(0, sizeof(deviceTreeBuffer)); 658 if (!deviceTreeBuffer) { 659 /* We can't get to the data, so we can't do anything, 660 * not even free it from physical memory (if it's there). 661 */ 662 OSKextLog(/* kext */ NULL, 663 kOSKextLogErrorLevel | 664 kOSKextLogDirectoryScanFlag, 665 "Device tree entry %s has NULL pointer.", 666 devTreeNameCString); 667 goto finish; // xxx - continue, panic? 668 } 669 670 booterDataPtr = (char *)ml_static_ptovirt(deviceTreeBuffer->paddr); 671 if (!booterDataPtr) { 672 OSKextLog(/* kext */ NULL, 673 kOSKextLogErrorLevel | 674 kOSKextLogDirectoryScanFlag, 675 "Can't get virtual address for device tree entry %s.", 676 devTreeNameCString); 677 goto finish; 678 } 679 680 /* Wrap the booter data buffer in an OSData and set a dealloc function 681 * so it will take care of the physical memory when freed. Kexts will 682 * retain the booterData for as long as they need it. Remove the entry 683 * from the booter memory map after this is done. 684 */ 685 booterData = OSData::withBytesNoCopy(booterDataPtr, 686 deviceTreeBuffer->length); 687 if (!booterData) { 688 OSKextLog(/* kext */ NULL, 689 kOSKextLogErrorLevel | 690 kOSKextLogGeneralFlag, 691 "Error - Can't allocate OSData wrapper for device tree entry %s.", 692 devTreeNameCString); 693 goto finish; 694 } 695 booterData->setDeallocFunction(osdata_phys_free); 696 697 /* Create the kext for the entry, then release it, because the 698 * kext system keeps them around until explicitly removed. 699 * Any creation/registration failures are already logged for us. 700 */ 701 OSKext * newKext = OSKext::withBooterData(deviceTreeName, booterData); 702 OSSafeReleaseNULL(newKext); 703 704 booterMemoryMap->removeProperty(deviceTreeName); 705 } /* while ( (deviceTreeName = OSDynamicCast(OSString, ...) ) ) */ 706 707 finish: 708 709 OSSafeReleaseNULL(booterMemoryMap); 710 OSSafeReleaseNULL(propertyDict); 711 OSSafeReleaseNULL(keyIterator); 712 OSSafeReleaseNULL(booterData); 713 OSSafeReleaseNULL(aKext); 714 return; 715 } 716 717 /********************************************************************* 718 *********************************************************************/ 719 #define COM_APPLE "com.apple." 720 721 void 722 KLDBootstrap::loadSecurityExtensions(void) 723 { 724 OSDictionary * extensionsDict = NULL;// must release 725 OSCollectionIterator * keyIterator = NULL;// must release 726 OSString * bundleID = NULL;// don't release 727 OSKext * theKext = NULL;// don't release 728 729 OSKextLog(/* kext */ NULL, 730 kOSKextLogStepLevel | 731 kOSKextLogLoadFlag, 732 "Loading security extensions."); 733 734 extensionsDict = OSKext::copyKexts(); 735 if (!extensionsDict) { 736 return; 737 } 738 739 keyIterator = OSCollectionIterator::withCollection(extensionsDict); 740 if (!keyIterator) { 741 OSKextLog(/* kext */ NULL, 742 kOSKextLogErrorLevel | 743 kOSKextLogGeneralFlag, 744 "Failed to allocate iterator for security extensions."); 745 goto finish; 746 } 747 748 while ((bundleID = OSDynamicCast(OSString, keyIterator->getNextObject()))) { 749 const char * bundle_id = bundleID->getCStringNoCopy(); 750 751 /* Skip extensions whose bundle IDs don't start with "com.apple.". 752 */ 753 if (!bundle_id || 754 (strncmp(bundle_id, COM_APPLE, CONST_STRLEN(COM_APPLE)) != 0)) { 755 continue; 756 } 757 758 theKext = OSDynamicCast(OSKext, extensionsDict->getObject(bundleID)); 759 if (!theKext) { 760 continue; 761 } 762 763 if (kOSBooleanTrue == theKext->getPropertyForHostArch(kAppleSecurityExtensionKey)) { 764 OSKextLog(/* kext */ NULL, 765 kOSKextLogStepLevel | 766 kOSKextLogLoadFlag, 767 "Loading security extension %s.", bundleID->getCStringNoCopy()); 768 OSKext::loadKextWithIdentifier(bundleID->getCStringNoCopy(), 769 /* allowDefer */ false); 770 } 771 } 772 773 finish: 774 OSSafeReleaseNULL(keyIterator); 775 OSSafeReleaseNULL(extensionsDict); 776 777 return; 778 } 779 780 /********************************************************************* 781 * We used to require that all listed kernel components load, but 782 * nowadays we can get them from userland so we only try to load the 783 * ones we have. If an error occurs later, such is life. 784 * 785 * Note that we look the kexts up first, so we can avoid spurious 786 * (in this context, anyhow) log messages about kexts not being found. 787 * 788 * xxx - do we even need to do this any more? Check if the kernel 789 * xxx - compoonents just load in the regular paths 790 *********************************************************************/ 791 OSReturn 792 KLDBootstrap::loadKernelComponentKexts(void) 793 { 794 OSReturn result = kOSReturnSuccess;// optimistic 795 OSKext * theKext = NULL; // must release 796 const char ** kextIDPtr = NULL; // do not release 797 798 for (kextIDPtr = &sKernelComponentNames[0]; *kextIDPtr; kextIDPtr++) { 799 OSSafeReleaseNULL(theKext); 800 theKext = OSKext::lookupKextWithIdentifier(*kextIDPtr); 801 802 if (theKext) { 803 if (kOSReturnSuccess != OSKext::loadKextWithIdentifier( 804 *kextIDPtr, /* allowDefer */ false)) { 805 // xxx - check KextBookkeeping, might be redundant 806 OSKextLog(/* kext */ NULL, 807 kOSKextLogErrorLevel | 808 kOSKextLogDirectoryScanFlag | kOSKextLogKextBookkeepingFlag, 809 "Failed to initialize kernel component %s.", *kextIDPtr); 810 result = kOSReturnError; 811 } 812 } 813 } 814 815 OSSafeReleaseNULL(theKext); 816 return result; 817 } 818 819 /********************************************************************* 820 * Ensure that Kernel External Components are loaded early in boot, 821 * before other kext personalities get sent to the IOCatalogue. These 822 * kexts are treated specially because they may provide the implementation 823 * for kernel-vended KPI, so they must register themselves before 824 * general purpose IOKit probing begins. 825 *********************************************************************/ 826 827 #define COM_APPLE_KEC "com.apple.kec." 828 829 void 830 KLDBootstrap::loadKernelExternalComponents(void) 831 { 832 OSDictionary * extensionsDict = NULL;// must release 833 OSCollectionIterator * keyIterator = NULL;// must release 834 OSString * bundleID = NULL;// don't release 835 OSKext * theKext = NULL;// don't release 836 OSBoolean * isKernelExternalComponent = NULL;// don't release 837 838 OSKextLog(/* kext */ NULL, 839 kOSKextLogStepLevel | 840 kOSKextLogLoadFlag, 841 "Loading Kernel External Components."); 842 843 extensionsDict = OSKext::copyKexts(); 844 if (!extensionsDict) { 845 return; 846 } 847 848 keyIterator = OSCollectionIterator::withCollection(extensionsDict); 849 if (!keyIterator) { 850 OSKextLog(/* kext */ NULL, 851 kOSKextLogErrorLevel | 852 kOSKextLogGeneralFlag, 853 "Failed to allocate iterator for Kernel External Components."); 854 goto finish; 855 } 856 857 while ((bundleID = OSDynamicCast(OSString, keyIterator->getNextObject()))) { 858 const char * bundle_id = bundleID->getCStringNoCopy(); 859 860 /* Skip extensions whose bundle IDs don't start with "com.apple.kec.". 861 */ 862 if (!bundle_id || 863 (strncmp(bundle_id, COM_APPLE_KEC, CONST_STRLEN(COM_APPLE_KEC)) != 0)) { 864 continue; 865 } 866 867 theKext = OSDynamicCast(OSKext, extensionsDict->getObject(bundleID)); 868 if (!theKext) { 869 continue; 870 } 871 872 isKernelExternalComponent = OSDynamicCast(OSBoolean, 873 theKext->getPropertyForHostArch(kAppleKernelExternalComponentKey)); 874 if (isKernelExternalComponent && isKernelExternalComponent->isTrue()) { 875 OSKextLog(/* kext */ NULL, 876 kOSKextLogStepLevel | 877 kOSKextLogLoadFlag, 878 "Loading kernel external component %s.", bundleID->getCStringNoCopy()); 879 OSKext::loadKextWithIdentifier(bundleID->getCStringNoCopy(), 880 /* allowDefer */ false); 881 } 882 } 883 884 finish: 885 OSSafeReleaseNULL(keyIterator); 886 OSSafeReleaseNULL(extensionsDict); 887 888 return; 889 } 890 891 /********************************************************************* 892 *********************************************************************/ 893 void 894 KLDBootstrap::readBuiltinPersonalities(void) 895 { 896 OSObject * parsedXML = NULL;// must release 897 OSArray * builtinExtensions = NULL;// do not release 898 OSArray * allPersonalities = NULL;// must release 899 OSString * errorString = NULL;// must release 900 kernel_section_t * infosect = NULL;// do not free 901 OSCollectionIterator * personalitiesIterator = NULL;// must release 902 unsigned int count, i; 903 904 OSKextLog(/* kext */ NULL, 905 kOSKextLogStepLevel | 906 kOSKextLogLoadFlag, 907 "Reading built-in kernel personalities for I/O Kit drivers."); 908 909 /* Look in the __BUILTIN __info segment for an array of Info.plist 910 * entries. For each one, extract the personalities dictionary, add 911 * it to our array, then push them all (without matching) to 912 * the IOCatalogue. This can be used to augment the personalities 913 * in gIOKernelConfigTables, especially when linking entire kexts into 914 * the mach_kernel image. 915 */ 916 infosect = getsectbyname("__BUILTIN", "__info"); 917 if (!infosect) { 918 // this isn't fatal 919 goto finish; 920 } 921 922 parsedXML = OSUnserializeXML((const char *) (uintptr_t)infosect->addr, 923 &errorString); 924 if (parsedXML) { 925 builtinExtensions = OSDynamicCast(OSArray, parsedXML); 926 } 927 if (!builtinExtensions) { 928 const char * errorCString = "(unknown error)"; 929 930 if (errorString && errorString->getCStringNoCopy()) { 931 errorCString = errorString->getCStringNoCopy(); 932 } else if (parsedXML) { 933 errorCString = "not an array"; 934 } 935 OSKextLog(/* kext */ NULL, 936 kOSKextLogErrorLevel | 937 kOSKextLogLoadFlag, 938 "Error unserializing built-in personalities: %s.", errorCString); 939 goto finish; 940 } 941 942 // estimate 3 personalities per Info.plist/kext 943 count = builtinExtensions->getCount(); 944 allPersonalities = OSArray::withCapacity(count * 3); 945 946 for (i = 0; i < count; i++) { 947 OSDictionary * infoDict = NULL;// do not release 948 OSString * moduleName = NULL;// do not release 949 OSDictionary * personalities;// do not release 950 OSString * personalityName;// do not release 951 952 OSSafeReleaseNULL(personalitiesIterator); 953 954 infoDict = OSDynamicCast(OSDictionary, 955 builtinExtensions->getObject(i)); 956 if (!infoDict) { 957 continue; 958 } 959 960 moduleName = OSDynamicCast(OSString, 961 infoDict->getObject(kCFBundleIdentifierKey)); 962 if (!moduleName) { 963 continue; 964 } 965 966 OSKextLog(/* kext */ NULL, 967 kOSKextLogStepLevel | 968 kOSKextLogLoadFlag, 969 "Adding personalities for built-in driver %s:", 970 moduleName->getCStringNoCopy()); 971 972 personalities = OSDynamicCast(OSDictionary, 973 infoDict->getObject("IOKitPersonalities")); 974 if (!personalities) { 975 continue; 976 } 977 978 personalitiesIterator = OSCollectionIterator::withCollection(personalities); 979 if (!personalitiesIterator) { 980 continue; // xxx - well really, what can we do? should we panic? 981 } 982 983 while ((personalityName = OSDynamicCast(OSString, 984 personalitiesIterator->getNextObject()))) { 985 OSDictionary * personality = OSDynamicCast(OSDictionary, 986 personalities->getObject(personalityName)); 987 988 OSKextLog(/* kext */ NULL, 989 kOSKextLogDetailLevel | 990 kOSKextLogLoadFlag, 991 "Adding built-in driver personality %s.", 992 personalityName->getCStringNoCopy()); 993 994 if (personality && !personality->getObject(kCFBundleIdentifierKey)) { 995 personality->setObject(kCFBundleIdentifierKey, moduleName); 996 } 997 allPersonalities->setObject(personality); 998 } 999 } 1000 1001 gIOCatalogue->addDrivers(allPersonalities, false); 1002 1003 finish: 1004 OSSafeReleaseNULL(parsedXML); 1005 OSSafeReleaseNULL(allPersonalities); 1006 OSSafeReleaseNULL(errorString); 1007 OSSafeReleaseNULL(personalitiesIterator); 1008 return; 1009 } 1010 1011 #if PRAGMA_MARK 1012 #pragma mark Bootstrap Functions 1013 #endif 1014 /********************************************************************* 1015 * Bootstrap Functions 1016 *********************************************************************/ 1017 static void 1018 bootstrapRecordStartupExtensions(void) 1019 { 1020 sBootstrapObject.readStartupExtensions(); 1021 return; 1022 } 1023 1024 static void 1025 bootstrapLoadSecurityExtensions(void) 1026 { 1027 sBootstrapObject.loadSecurityExtensions(); 1028 return; 1029 } 1030 1031