xref: /xnu-11215/libsa/bootstrap.cpp (revision 76e12aa3)
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