2 * Copyright (c) 2008-2016 Apple Inc. All rights reserved.
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
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.
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
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.
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
29 #ifndef _LIBKERN_OSKEXT_H
30 #define _LIBKERN_OSKEXT_H
33 #include <kern/thread_call.h>
34 #include <libkern/OSKextLibPrivate.h>
35 #include <libkern/kernel_mach_header.h>
36 #include <libkern/kxld.h>
37 #include <mach/kmod.h>
39 #ifdef XNU_KERNEL_PRIVATE
40 #include <kern/thread_call.h>
41 #endif /* XNU_KERNEL_PRIVATE */
44 #include <libkern/OSKextLib.h>
45 #include <libkern/OSKextLibPrivate.h>
46 #include <libkern/c++/OSObject.h>
47 #include <libkern/c++/OSContainers.h>
48 #include <IOKit/IOLocks.h>
50 /*********************************************************************
51 * C functions used for callbacks.
52 *********************************************************************/
53 #ifdef XNU_KERNEL_PRIVATE
55 void osdata_kmem_free(void * ptr
, unsigned int length
);
56 void osdata_phys_free(void * ptr
, unsigned int length
);
57 void osdata_vm_deallocate(void * ptr
, unsigned int length
);
58 void osdata_kext_free(void * ptr
, unsigned int length
);
59 void kxld_log_callback(
60 KXLDLogSubsystem subsystem
,
66 #endif /* XNU_KERNEL_PRIVATE */
68 /*********************************************************************
69 * C Function Prototypes for Friend Declarations.
70 *********************************************************************/
76 OSKextLogSpec msgLogSpec
,
77 const char * format
, ...)
78 __attribute__((format(printf
, 3, 4)));
82 OSKextLogSpec msgLogSpec
,
86 #ifdef XNU_KERNEL_PRIVATE
87 void OSKextRemoveKextBootstrap(void);
89 kern_return_t
OSRuntimeInitializeCPP(
91 kern_return_t
OSRuntimeFinalizeCPP(
93 void OSRuntimeUnloadCPPForSegment(
94 kernel_segment_command_t
* segment
);
96 kern_return_t
is_io_catalog_send_data(
97 mach_port_t masterPort
,
100 mach_msg_type_number_t inDataCount
,
101 kern_return_t
* result
);
103 void kmod_dump_log(vm_offset_t
*, unsigned int, boolean_t
);
104 void *OSKextKextForAddress(const void *addr
);
106 #endif /* XNU_KERNEL_PRIVATE */
109 /********************************************************************/
115 struct list_head
*prev
;
116 struct list_head
*next
;
119 struct OSKextGrabPgoStruct
{
125 struct list_head list_head
;
129 #define container_of(ptr, type, member) ((type*)(((uintptr_t)ptr) - offsetof(type, member)))
131 /********************************************************************/
133 #if XNU_KERNEL_PRIVATE
135 struct OSKextAccount
{
136 vm_allocation_site_t site
;
141 struct OSKextActiveAccount
{
143 uintptr_t address_end
;
144 OSKextAccount
* account
;
146 typedef struct OSKextActiveAccount OSKextActiveAccount
;
148 #endif /* XNU_KERNEL_PRIVATE */
153 /********************************************************************/
154 class OSKext
: public OSObject
156 OSDeclareDefaultStructors(OSKext
)
159 /**************************************/
160 #pragma mark Friend Declarations
161 /**************************************/
163 friend class IOCatalogue
;
164 friend class KLDBootstrap
;
165 friend class OSMetaClass
;
167 friend int OSKextGrabPgoData(uuid_t uuid
,
174 #ifdef XNU_KERNEL_PRIVATE
175 friend void OSKextVLog(
177 OSKextLogSpec msgLogSpec
,
181 friend void OSKextRemoveKextBootstrap(void);
182 friend OSReturn
OSKextUnloadKextWithLoadTag(uint32_t);
184 friend kern_return_t
kext_request(
185 host_priv_t hostPriv
,
186 /* in only */ uint32_t clientLogSpec
,
187 /* in only */ vm_offset_t requestIn
,
188 /* in only */ mach_msg_type_number_t requestLengthIn
,
189 /* out only */ vm_offset_t
* responseOut
,
190 /* out only */ mach_msg_type_number_t
* responseLengthOut
,
191 /* out only */ vm_offset_t
* logDataOut
,
192 /* out only */ mach_msg_type_number_t
* logDataLengthOut
,
193 /* out only */ kern_return_t
* op_result
);
195 friend kxld_addr_t
kern_allocate(
197 KXLDAllocateFlags
* flags
,
200 friend void kxld_log_shim(
201 KXLDLogSubsystem subsystem
,
207 friend void _OSKextConsiderUnloads(
208 __unused thread_call_param_t p0
,
209 __unused thread_call_param_t p1
);
211 friend kern_return_t
OSRuntimeInitializeCPP(
213 friend kern_return_t
OSRuntimeFinalizeCPP(
215 friend void OSRuntimeUnloadCPPForSegment(
216 kernel_segment_command_t
* segment
);
218 friend kern_return_t
is_io_catalog_send_data(
219 mach_port_t masterPort
,
222 mach_msg_type_number_t inDataCount
,
223 kern_return_t
* result
);
225 friend void kmod_panic_dump(vm_offset_t
*, unsigned int);
226 friend void kmod_dump_log(vm_offset_t
*, unsigned int, boolean_t
);
227 friend void kext_dump_panic_lists(int (*printf_func
)(const char * fmt
, ...));
228 friend void *OSKextKextForAddress(const void *addr
);
230 #endif /* XNU_KERNEL_PRIVATE */
234 /*************************
236 *************************/
237 OSDictionary
* infoDict
;
239 const OSSymbol
* bundleID
;
240 OSString
* path
; // not necessarily correct :-/
241 OSString
* executableRelPath
;// relative to bundle
243 OSKextVersion version
; // parsed
244 OSKextVersion compatibleVersion
;// parsed
246 /* These fields are required for tracking loaded kexts and
247 * will always have values for a loaded kext.
249 OSKextLoadTag loadTag
; // 'id' from old kmod_info;
250 // kOSKextInvalidLoadTag invalid
251 kmod_info_t
* kmod_info
; // address into linkedExec./alloced for interface
253 OSArray
* dependencies
; // kernel resource does not have any;
254 // links directly to kernel
256 /* Only real kexts have these; interface kexts do not.
258 OSData
* linkedExecutable
;
259 OSSet
* metaClasses
; // for C++/OSMetaClass kexts
261 /* Only interface kexts have these; non-interface kexts can get at them
262 * in the linked Executable.
264 OSData
* interfaceUUID
;
267 unsigned int loggingEnabled
:1;
269 unsigned int hasAllDependencies
:1;
270 unsigned int hasBleedthrough
:1;
272 unsigned int interface
:1;
273 unsigned int kernelComponent
:1;
274 unsigned int prelinked
:1;
275 unsigned int builtin
:1;
276 unsigned int loaded
:1;
277 unsigned int dtraceInitialized
:1;
278 unsigned int starting
:1;
279 unsigned int started
:1;
280 unsigned int stopping
:1;
281 unsigned int unloading
:1;
283 unsigned int autounloadEnabled
:1;
284 unsigned int delayAutounload
:1; // for development
286 unsigned int CPPInitialized
:1;
287 unsigned int jettisonLinkeditSeg
:1;
290 struct list_head pendingPgoHead
;
291 uuid_t instance_uuid
;
292 OSKextAccount
* account
;
293 uint32_t builtinKmodIdx
;
296 /**************************************/
297 #pragma mark Private Functions
298 /**************************************/
301 #ifdef XNU_KERNEL_PRIVATE
302 /* Startup/shutdown phases.
305 static void initialize(void);
306 static OSDictionary
* copyKexts(void);
307 static OSReturn
removeKextBootstrap(void);
308 static void willShutdown(void);// called by IOPMrootDomain on shutdown
309 static void reportOSMetaClassInstances(
310 const char * kextIdentifier
,
311 OSKextLogSpec msgLogSpec
);
313 #endif /* XNU_KERNEL_PRIVATE */
316 /* Called by power management at sleep/shutdown.
318 static bool setLoadEnabled(bool flag
);
319 static bool setUnloadEnabled(bool flag
);
320 static bool setAutounloadsEnabled(bool flag
);
321 static bool setKernelRequestsEnabled(bool flag
);
323 // all getters subject to race condition, caller beware
324 static bool getLoadEnabled(void);
325 static bool getUnloadEnabled(void);
326 static bool getAutounloadEnabled(void);
327 static bool getKernelRequestsEnabled(void);
329 /* Instance life cycle.
331 static OSKext
* withBooterData(
332 OSString
* deviceTreeName
,
333 OSData
* booterData
);
334 virtual bool initWithBooterData(
335 OSString
* deviceTreeName
,
336 OSData
* booterData
);
338 static OSKext
* withPrelinkedInfoDict(
339 OSDictionary
* infoDict
,
340 bool doCoalesedSlides
);
341 virtual bool initWithPrelinkedInfoDict(
342 OSDictionary
* infoDict
,
343 bool doCoalesedSlides
);
345 static void setAllVMAttributes(void);
347 static OSKext
* withMkext2Info(
348 OSDictionary
* anInfoDict
,
350 virtual bool initWithMkext2Info(
351 OSDictionary
* anInfoDict
,
354 virtual bool setInfoDictionaryAndPath(
355 OSDictionary
* aDictionary
,
357 virtual bool setExecutable(
358 OSData
* anExecutable
,
359 OSData
* externalData
= NULL
,
360 bool externalDataIsMkext
= false);
361 virtual bool registerIdentifier(void);
363 virtual void free(void) APPLE_KEXT_OVERRIDE
;
365 static OSReturn
removeKext(
367 bool terminateServicesAndRemovePersonalitiesFlag
= false);
369 virtual bool isInExcludeList(void);
373 static OSReturn
readMkextArchive(
375 uint32_t * checksumPtr
= NULL
);
376 static OSReturn
readMkext2Archive(
378 OSDictionary
** mkextPlistOut
,
379 uint32_t * checksumPtr
= NULL
);
380 virtual OSData
* createMkext2FileEntry(
382 OSNumber
* offsetNum
,
383 const char * entryName
);
384 virtual OSData
* extractMkext2FileData(
387 uint32_t compressedSize
,
392 virtual bool resolveDependencies(
393 OSArray
* loopStack
= NULL
); // priv/prot
394 virtual bool addBleedthroughDependencies(OSArray
* anArray
);
395 virtual bool flushDependencies(bool forceFlag
= false); // priv/prot
396 virtual uint32_t getNumDependencies(void);
397 virtual OSArray
* getDependencies(void);
399 /* User-space requests (load/generic).
401 static OSReturn
loadFromMkext(
402 OSKextLogSpec clientLogSpec
,
404 uint32_t mkextBufferLength
,
406 uint32_t * logInfoLengthOut
);
407 static OSReturn
handleRequest(
408 host_priv_t hostPriv
,
409 OSKextLogSpec clientLogSpec
,
410 char * requestBuffer
,
411 uint32_t requestLength
,
413 uint32_t * responseLengthOut
,
415 uint32_t * logInfoLengthOut
);
416 static OSReturn
serializeLogInfo(
417 OSArray
* logInfoArray
,
419 uint32_t * logInfoLengthOut
);
423 virtual OSReturn
load(
424 OSKextExcludeLevel startOpt
= kOSKextExcludeNone
,
425 OSKextExcludeLevel startMatchingOpt
= kOSKextExcludeAll
,
426 OSArray
* personalityNames
= NULL
);// priv/prot
427 virtual OSReturn
unload(void);
428 virtual OSReturn
queueKextNotification(
429 const char * notificationName
,
430 OSString
* kextIdentifier
);
432 static void recordIdentifierRequest(
433 OSString
* kextIdentifier
);
435 virtual OSReturn
slidePrelinkedExecutable(bool doCoalesedSlides
);
436 virtual OSReturn
loadExecutable(void);
437 virtual void jettisonLinkeditSegment(void);
438 virtual void jettisonDATASegmentPadding(void);
439 static void considerDestroyingLinkContext(void);
440 virtual OSData
* getExecutable(void);
441 virtual void setLinkedExecutable(OSData
* anExecutable
);
444 friend void OSKextRegisterKextsWithDTrace(void);
445 static void registerKextsWithDTrace(void);
446 virtual void registerWithDTrace(void);
447 virtual void unregisterWithDTrace(void);
448 #endif /* CONFIG_DTRACE */
450 virtual OSReturn
start(bool startDependenciesFlag
= true);
451 virtual OSReturn
stop(void);
452 virtual OSReturn
setVMAttributes(bool protect
, bool wire
);
453 virtual boolean_t
segmentShouldBeWired(kernel_segment_command_t
*seg
);
454 virtual OSReturn
validateKextMapping(bool startFlag
);
455 virtual boolean_t
verifySegmentMapping(kernel_segment_command_t
*seg
);
457 static OSArray
* copyAllKextPersonalities(
458 bool filterSafeBootFlag
= false);
460 static void setPrelinkedPersonalities(OSArray
* personalitiesArray
);
462 static void sendAllKextPersonalitiesToCatalog(
463 bool startMatching
= false);
464 virtual OSReturn
sendPersonalitiesToCatalog(
465 bool startMatching
= false,
466 OSArray
* personalityNames
= NULL
);
468 static bool canUnloadKextWithIdentifier(
469 OSString
* kextIdentifier
,
470 bool checkClassesFlag
= true);
472 static OSReturn
autounloadKext(OSKext
* aKext
);
474 /* Sync with user space.
476 static OSReturn
pingKextd(void);
478 /* Getting info about loaded kexts (kextstat).
480 static OSDictionary
* copyLoadedKextInfo(
481 OSArray
* kextIdentifiers
= NULL
,
482 OSArray
* keys
= NULL
);
483 static OSDictionary
* copyLoadedKextInfoByUUID(
484 OSArray
* kextIdentifiers
= NULL
,
485 OSArray
* keys
= NULL
);
486 static OSData
* copyKextUUIDForAddress(OSNumber
*address
= NULL
);
487 virtual OSDictionary
* copyInfo(OSArray
* keys
= NULL
);
489 /* Logging to user space.
491 static OSKextLogSpec
setUserSpaceLogFilter(
492 OSKextLogSpec userLogSpec
,
493 bool captureFlag
= false);
494 static OSArray
* clearUserSpaceLogFilter(void);
495 static OSKextLogSpec
getUserSpaceLogFilter(void);
497 /* OSMetaClasses defined by kext.
499 virtual OSReturn
addClass(
500 OSMetaClass
* aClass
,
501 uint32_t numClasses
);
502 virtual OSReturn
removeClass(
503 OSMetaClass
* aClass
);
504 virtual bool hasOSMetaClassInstances(void);
505 virtual OSSet
* getMetaClasses(void);
507 virtual void reportOSMetaClassInstances(
508 OSKextLogSpec msgLogSpec
);
510 /* Resource requests and other callback stuff.
512 static OSReturn
dispatchResource(OSDictionary
* requestDict
);
514 static OSReturn
dequeueCallbackForRequestTag(
515 OSKextRequestTag requestTag
,
516 OSDictionary
** callbackRecordOut
);
517 static OSReturn
dequeueCallbackForRequestTag(
518 OSNumber
* requestTagNum
,
519 OSDictionary
** callbackRecordOut
);
520 static void invokeRequestCallback(
521 OSDictionary
* callbackRecord
,
522 OSReturn requestResult
);
523 virtual void invokeOrCancelRequestCallbacks(
524 OSReturn callbackResult
,
525 bool invokeFlag
= true);
526 virtual uint32_t countRequestCallbacks(void);
532 kPrintKextsLock
= 0x01,
533 kPrintKextsUnslide
= 0x02,
534 kPrintKextsTerse
= 0x04
536 static void printKextsInBacktrace(
539 int (* printf_func
)(const char *fmt
, ...),
542 static OSKextLoadedKextSummary
*summaryForAddress(const uintptr_t addr
);
543 static void *kextForAddress(const void *addr
);
544 static boolean_t
summaryIsInBacktrace(
545 OSKextLoadedKextSummary
* summary
,
548 static void printSummary(
549 OSKextLoadedKextSummary
* summary
,
550 int (* printf_func
)(const char *fmt
, ...),
553 static int saveLoadedKextPanicListTyped(
559 static void saveLoadedKextPanicList(void);
560 void savePanicString(bool isLoading
);
561 static void printKextPanicLists(int (*printf_func
)(const char *fmt
, ...));
563 /* Kext summary support.
565 static void updateLoadedKextSummaries(void);
566 void updateLoadedKextSummary(OSKextLoadedKextSummary
*summary
);
567 void updateActiveAccount(OSKextActiveAccount
*accountp
);
569 #ifdef XNU_KERNEL_PRIVATE
571 #endif /* XNU_KERNEL_PRIVATE */
573 /* C++ Initialization.
575 virtual void setCPPInitialized(bool initialized
= true);
578 /**************************************/
579 #pragma mark Public Functions
580 /**************************************/
583 // caller must release
584 static OSKext
* lookupKextWithIdentifier(const char * kextIdentifier
);
585 static OSKext
* lookupKextWithIdentifier(OSString
* kextIdentifier
);
586 static OSKext
* lookupKextWithLoadTag(OSKextLoadTag aTag
);
587 static OSKext
* lookupKextWithAddress(vm_address_t address
);
588 static OSKext
* lookupKextWithUUID(uuid_t uuid
);
590 kernel_section_t
*lookupSection(const char *segname
, const char*secname
);
592 static bool isKextWithIdentifierLoaded(const char * kextIdentifier
);
594 static OSReturn
loadKextWithIdentifier(
595 const char * kextIdentifier
,
596 Boolean allowDeferFlag
= true,
597 Boolean delayAutounloadFlag
= false,
598 OSKextExcludeLevel startOpt
= kOSKextExcludeNone
,
599 OSKextExcludeLevel startMatchingOpt
= kOSKextExcludeAll
,
600 OSArray
* personalityNames
= NULL
);
601 static OSReturn
loadKextWithIdentifier(
602 OSString
* kextIdentifier
,
603 Boolean allowDeferFlag
= true,
604 Boolean delayAutounloadFlag
= false,
605 OSKextExcludeLevel startOpt
= kOSKextExcludeNone
,
606 OSKextExcludeLevel startMatchingOpt
= kOSKextExcludeAll
,
607 OSArray
* personalityNames
= NULL
);
608 static OSReturn
removeKextWithIdentifier(
609 const char * kextIdentifier
,
610 bool terminateServicesAndRemovePersonalitiesFlag
= false);
611 static OSReturn
removeKextWithLoadTag(
612 OSKextLoadTag loadTag
,
613 bool terminateServicesAndRemovePersonalitiesFlag
= false);
615 static OSReturn
requestResource(
616 const char * kextIdentifier
,
617 const char * resourceName
,
618 OSKextRequestResourceCallback callback
,
620 OSKextRequestTag
* requestTagOut
);
621 static OSReturn
cancelRequest(
622 OSKextRequestTag requestTag
,
625 static void considerUnloads(Boolean rescheduleOnlyFlag
= false);
626 static void flushNonloadedKexts(Boolean flushPrelinkedKexts
);
627 static void setKextdActive(Boolean active
= true);
628 static void setDeferredLoadSucceeded(Boolean succeeded
= true);
629 static void considerRebuildOfPrelinkedKernel(void);
630 static void createExcludeListFromBooterData(
631 OSDictionary
* theDictionary
,
632 OSCollectionIterator
* theIterator
);
633 static void createExcludeListFromPrelinkInfo(OSArray
* theInfoArray
);
634 static boolean_t
updateExcludeList(OSDictionary
* infoDict
);
636 static bool isWaitingKextd(void);
638 virtual bool setAutounloadEnabled(bool flag
);
640 virtual const OSSymbol
* getIdentifier(void);
641 virtual const char * getIdentifierCString(void);
642 virtual OSKextVersion
getVersion(void);
643 virtual OSKextVersion
getCompatibleVersion(void);
644 virtual bool isLibrary(void);
645 virtual bool isCompatibleWithVersion(OSKextVersion aVersion
);
646 virtual OSObject
* getPropertyForHostArch(const char * key
);
648 virtual OSKextLoadTag
getLoadTag(void);
649 virtual void getSizeInfo(uint32_t *loadSize
, uint32_t *wiredSize
);
650 virtual OSData
* copyUUID(void);
651 OSData
* copyTextUUID(void);
652 OSData
* copyMachoUUID(const kernel_mach_header_t
* header
);
653 virtual OSArray
* copyPersonalitiesArray(void);
655 /* This removes personalities naming the kext (by CFBundleIdentifier),
656 * not all personalities defined by the kext (IOPersonalityPublisher or CFBundleIdentifier).
658 virtual void removePersonalitiesFromCatalog(void);
660 /* Converts common string-valued properties to OSSymbols for lower memory consumption.
662 static void uniquePersonalityProperties(OSDictionary
* personalityDict
);
664 virtual bool declaresExecutable(void); // might be missing
665 virtual bool isInterface(void);
666 virtual bool isKernel(void);
667 virtual bool isKernelComponent(void);
668 virtual bool isExecutable(void);
669 virtual bool isLoadableInSafeBoot(void);
670 virtual bool isPrelinked(void);
671 virtual bool isLoaded(void);
672 virtual bool isStarted(void);
673 virtual bool isCPPInitialized(void);
677 #endif /* !_LIBKERN_OSKEXT_H */