]> git.saurik.com Git - apple/xnu.git/blob - libkern/libkern/c++/OSKext.h
4d4cea4ec4923a86455fc9996b3c1cdb0a62392f
[apple/xnu.git] / libkern / libkern / c++ / OSKext.h
1 /*
2 * Copyright (c) 2008-2016 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
29 #ifndef _LIBKERN_OSKEXT_H
30 #define _LIBKERN_OSKEXT_H
31
32 extern "C" {
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>
38
39 #ifdef XNU_KERNEL_PRIVATE
40 #include <kern/thread_call.h>
41 #endif /* XNU_KERNEL_PRIVATE */
42 }
43
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>
49
50 /*********************************************************************
51 * C functions used for callbacks.
52 *********************************************************************/
53 #ifdef XNU_KERNEL_PRIVATE
54 extern "C" {
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,
61 KXLDLogLevel level,
62 const char * format,
63 va_list argList,
64 void * user_data);
65 };
66 #endif /* XNU_KERNEL_PRIVATE */
67
68 /*********************************************************************
69 * C Function Prototypes for Friend Declarations.
70 *********************************************************************/
71 class OSKext;
72
73 extern "C" {
74
75 void OSKextLog(
76 OSKext * aKext,
77 OSKextLogSpec msgLogSpec,
78 const char * format, ...)
79 __attribute__((format(printf, 3, 4)));
80
81 void OSKextVLog(
82 OSKext * aKext,
83 OSKextLogSpec msgLogSpec,
84 const char * format,
85 va_list srcArgList);
86
87 #ifdef XNU_KERNEL_PRIVATE
88 void OSKextRemoveKextBootstrap(void);
89 void IOSystemShutdownNotification(void);
90
91 kern_return_t OSRuntimeInitializeCPP(
92 kmod_info_t * kmodInfo,
93 void * data);
94 kern_return_t OSRuntimeFinalizeCPP(
95 kmod_info_t * kmodInfo,
96 void * data);
97
98 kern_return_t is_io_catalog_send_data(
99 mach_port_t masterPort,
100 uint32_t flag,
101 io_buf_ptr_t inData,
102 mach_msg_type_number_t inDataCount,
103 kern_return_t * result);
104
105 void kmod_dump_log(vm_offset_t*, unsigned int, boolean_t);
106 void *OSKextKextForAddress(const void *addr);
107
108 #endif /* XNU_KERNEL_PRIVATE */
109 };
110
111 /********************************************************************/
112 #if PRAGMA_MARK
113 #pragma mark -
114 #endif
115
116 struct list_head {
117 struct list_head *prev;
118 struct list_head *next;
119 };
120
121 struct OSKextGrabPgoStruct {
122 bool metadata;
123 uint64_t *pSize;
124 char *pBuffer;
125 uint64_t bufferSize;
126 int err;
127 struct list_head list_head;
128 };
129
130 #ifndef container_of
131 #define container_of(ptr,type,member) ((type*)(((uintptr_t)ptr) - offsetof(type, member)))
132 #endif
133 /********************************************************************/
134
135 #if XNU_KERNEL_PRIVATE
136
137 struct OSKextAccount
138 {
139 vm_allocation_site_t site;
140 uint32_t loadTag;
141 OSKext * kext;
142 };
143
144 struct OSKextActiveAccount
145 {
146 uintptr_t address;
147 uintptr_t address_end;
148 OSKextAccount * account;
149 };
150 typedef struct OSKextActiveAccount OSKextActiveAccount;
151
152 #endif /* XNU_KERNEL_PRIVATE */
153
154 /*
155 * @class OSKext
156 */
157 /********************************************************************/
158 class OSKext : public OSObject
159 {
160 OSDeclareDefaultStructors(OSKext)
161
162 #if PRAGMA_MARK
163 /**************************************/
164 #pragma mark Friend Declarations
165 /**************************************/
166 #endif
167 friend class IOCatalogue;
168 friend class KLDBootstrap;
169 friend class OSMetaClass;
170
171 friend int OSKextGrabPgoData(uuid_t uuid,
172 uint64_t *pSize,
173 char *pBuffer,
174 uint64_t bufferSize,
175 int wait_for_unload,
176 int metadata);
177
178 #ifdef XNU_KERNEL_PRIVATE
179 friend void OSKextVLog(
180 OSKext * aKext,
181 OSKextLogSpec msgLogSpec,
182 const char * format,
183 va_list srcArgList);
184
185 friend void OSKextRemoveKextBootstrap(void);
186 friend void IOSystemShutdownNotification(void);
187 friend OSReturn OSKextUnloadKextWithLoadTag(uint32_t);
188
189 friend kern_return_t kext_request(
190 host_priv_t hostPriv,
191 /* in only */ uint32_t clientLogSpec,
192 /* in only */ vm_offset_t requestIn,
193 /* in only */ mach_msg_type_number_t requestLengthIn,
194 /* out only */ vm_offset_t * responseOut,
195 /* out only */ mach_msg_type_number_t * responseLengthOut,
196 /* out only */ vm_offset_t * logDataOut,
197 /* out only */ mach_msg_type_number_t * logDataLengthOut,
198 /* out only */ kern_return_t * op_result);
199
200 friend kxld_addr_t kern_allocate(
201 u_long size,
202 KXLDAllocateFlags * flags,
203 void * user_data);
204
205 friend void kxld_log_shim(
206 KXLDLogSubsystem subsystem,
207 KXLDLogLevel level,
208 const char * format,
209 va_list argList,
210 void * user_data);
211
212 friend void _OSKextConsiderUnloads(
213 __unused thread_call_param_t p0,
214 __unused thread_call_param_t p1);
215
216 friend kern_return_t OSRuntimeInitializeCPP(
217 kmod_info_t * kmodInfo,
218 void * data);
219 friend kern_return_t OSRuntimeFinalizeCPP(
220 kmod_info_t * kmodInfo,
221 void * data);
222
223 friend kern_return_t is_io_catalog_send_data(
224 mach_port_t masterPort,
225 uint32_t flag,
226 io_buf_ptr_t inData,
227 mach_msg_type_number_t inDataCount,
228 kern_return_t * result);
229
230 friend void kmod_panic_dump(vm_offset_t*, unsigned int);
231 friend void kmod_dump_log(vm_offset_t*, unsigned int, boolean_t);
232 friend void kext_dump_panic_lists(int (*printf_func)(const char * fmt, ...));
233 friend void *OSKextKextForAddress(const void *addr);
234
235 #endif /* XNU_KERNEL_PRIVATE */
236
237 private:
238
239 /*************************
240 * Instance variables
241 *************************/
242 OSDictionary * infoDict;
243
244 const OSSymbol * bundleID;
245 OSString * path; // not necessarily correct :-/
246 OSString * executableRelPath; // relative to bundle
247
248 OSKextVersion version; // parsed
249 OSKextVersion compatibleVersion; // parsed
250
251 /* These fields are required for tracking loaded kexts and
252 * will always have values for a loaded kext.
253 */
254 OSKextLoadTag loadTag; // 'id' from old kmod_info;
255 // kOSKextInvalidLoadTag invalid
256 kmod_info_t * kmod_info; // address into linkedExec./alloced for interface
257
258 OSArray * dependencies; // kernel resource does not have any;
259 // links directly to kernel
260
261 /* Only real kexts have these; interface kexts do not.
262 */
263 OSData * linkedExecutable;
264 OSSet * metaClasses; // for C++/OSMetaClass kexts
265
266 /* Only interface kexts have these; non-interface kexts can get at them
267 * in the linked Executable.
268 */
269 OSData * interfaceUUID;
270
271 struct {
272 unsigned int loggingEnabled:1;
273
274 unsigned int hasAllDependencies:1;
275 unsigned int hasBleedthrough:1;
276
277 unsigned int interface:1;
278 unsigned int kernelComponent:1;
279 unsigned int prelinked:1;
280 unsigned int loaded:1;
281 unsigned int dtraceInitialized:1;
282 unsigned int starting:1;
283 unsigned int started:1;
284 unsigned int stopping:1;
285 unsigned int unloading:1;
286
287 unsigned int autounloadEnabled:1;
288 unsigned int delayAutounload:1; // for development
289
290 unsigned int CPPInitialized:1;
291 unsigned int jettisonLinkeditSeg:1;
292 } flags;
293
294 struct list_head pendingPgoHead;
295 uuid_t instance_uuid;
296 OSKextAccount * account;
297
298 #if PRAGMA_MARK
299 /**************************************/
300 #pragma mark Private Functions
301 /**************************************/
302 #endif
303
304 #ifdef XNU_KERNEL_PRIVATE
305 /* Startup/shutdown phases.
306 */
307 public:
308 static void initialize(void);
309 static OSDictionary * copyKexts(void);
310 static OSReturn removeKextBootstrap(void);
311 static void willShutdown(void); // called by IOPMrootDomain on shutdown
312 #endif /* XNU_KERNEL_PRIVATE */
313
314 private:
315 /* Called by power management at sleep/shutdown.
316 */
317 static bool setLoadEnabled(bool flag);
318 static bool setUnloadEnabled(bool flag);
319 static bool setAutounloadsEnabled(bool flag);
320 static bool setKernelRequestsEnabled(bool flag);
321
322 // all getters subject to race condition, caller beware
323 static bool getLoadEnabled(void);
324 static bool getUnloadEnabled(void);
325 static bool getAutounloadEnabled(void);
326 static bool getKernelRequestsEnabled(void);
327
328 /* Instance life cycle.
329 */
330 static OSKext * withBooterData(
331 OSString * deviceTreeName,
332 OSData * booterData);
333 virtual bool initWithBooterData(
334 OSString * deviceTreeName,
335 OSData * booterData);
336
337 static OSKext * withPrelinkedInfoDict(
338 OSDictionary * infoDict,
339 bool doCoalesedSlides);
340 virtual bool initWithPrelinkedInfoDict(
341 OSDictionary * infoDict,
342 bool doCoalesedSlides);
343
344 static void setAllVMAttributes(void);
345
346 static OSKext * withMkext2Info(
347 OSDictionary * anInfoDict,
348 OSData * mkextData);
349 virtual bool initWithMkext2Info(
350 OSDictionary * anInfoDict,
351 OSData * mkextData);
352
353 virtual bool setInfoDictionaryAndPath(
354 OSDictionary * aDictionary,
355 OSString * aPath);
356 virtual bool setExecutable(
357 OSData * anExecutable,
358 OSData * externalData = NULL,
359 bool externalDataIsMkext = false);
360 virtual bool registerIdentifier(void);
361
362 virtual void free(void) APPLE_KEXT_OVERRIDE;
363
364 static OSReturn removeKext(
365 OSKext * aKext,
366 bool terminateServicesAndRemovePersonalitiesFlag = false);
367
368 virtual bool isInExcludeList(void);
369
370 /* Mkexts.
371 */
372 static OSReturn readMkextArchive(
373 OSData * mkextData,
374 uint32_t * checksumPtr = NULL);
375 static OSReturn readMkext2Archive(
376 OSData * mkextData,
377 OSDictionary ** mkextPlistOut,
378 uint32_t * checksumPtr = NULL);
379 virtual OSData * createMkext2FileEntry(
380 OSData * mkextData,
381 OSNumber * offsetNum,
382 const char * entryName);
383 virtual OSData * extractMkext2FileData(
384 UInt8 * data,
385 const char * name,
386 uint32_t compressedSize,
387 uint32_t fullSize);
388
389 /* Dependencies.
390 */
391 virtual bool resolveDependencies(
392 OSArray * loopStack = NULL); // priv/prot
393 virtual bool addBleedthroughDependencies(OSArray * anArray);
394 virtual bool flushDependencies(bool forceFlag = false); // priv/prot
395 virtual uint32_t getNumDependencies(void);
396 virtual OSArray * getDependencies(void);
397
398 /* User-space requests (load/generic).
399 */
400 static OSReturn loadFromMkext(
401 OSKextLogSpec clientLogSpec,
402 char * mkextBuffer,
403 uint32_t mkextBufferLength,
404 char ** logInfoOut,
405 uint32_t * logInfoLengthOut);
406 static OSReturn handleRequest(
407 host_priv_t hostPriv,
408 OSKextLogSpec clientLogSpec,
409 char * requestBuffer,
410 uint32_t requestLength,
411 char ** responseOut,
412 uint32_t * responseLengthOut,
413 char ** logInfoOut,
414 uint32_t * logInfoLengthOut);
415 static OSReturn serializeLogInfo(
416 OSArray * logInfoArray,
417 char ** logInfoOut,
418 uint32_t * logInfoLengthOut);
419
420 /* Loading.
421 */
422 virtual OSReturn load(
423 OSKextExcludeLevel startOpt = kOSKextExcludeNone,
424 OSKextExcludeLevel startMatchingOpt = kOSKextExcludeAll,
425 OSArray * personalityNames = NULL); // priv/prot
426 virtual OSReturn unload(void);
427 virtual OSReturn queueKextNotification(
428 const char * notificationName,
429 OSString * kextIdentifier);
430
431 static void recordIdentifierRequest(
432 OSString * kextIdentifier);
433
434 virtual OSReturn slidePrelinkedExecutable(bool doCoalesedSlides);
435 virtual OSReturn loadExecutable(void);
436 virtual void jettisonLinkeditSegment(void);
437 virtual void jettisonDATASegmentPadding(void);
438 static void considerDestroyingLinkContext(void);
439 virtual OSData * getExecutable(void);
440 virtual void setLinkedExecutable(OSData * anExecutable);
441
442 #if CONFIG_DTRACE
443 friend void OSKextRegisterKextsWithDTrace(void);
444 static void registerKextsWithDTrace(void);
445 virtual void registerWithDTrace(void);
446 virtual void unregisterWithDTrace(void);
447 #endif /* CONFIG_DTRACE */
448
449 virtual OSReturn start(bool startDependenciesFlag = true);
450 virtual OSReturn stop(void);
451 virtual OSReturn setVMAttributes(bool protect, bool wire);
452 virtual boolean_t segmentShouldBeWired(kernel_segment_command_t *seg);
453 virtual OSReturn validateKextMapping(bool startFlag);
454 virtual boolean_t verifySegmentMapping(kernel_segment_command_t *seg);
455
456 static OSArray * copyAllKextPersonalities(
457 bool filterSafeBootFlag = false);
458
459 static void setPrelinkedPersonalities(OSArray * personalitiesArray);
460
461 static void sendAllKextPersonalitiesToCatalog(
462 bool startMatching = false);
463 virtual OSReturn sendPersonalitiesToCatalog(
464 bool startMatching = false,
465 OSArray * personalityNames = NULL);
466
467 static bool canUnloadKextWithIdentifier(
468 OSString * kextIdentifier,
469 bool checkClassesFlag = true);
470
471 static OSReturn autounloadKext(OSKext * aKext);
472
473 /* Sync with user space.
474 */
475 static OSReturn pingKextd(void);
476
477 /* Getting info about loaded kexts (kextstat).
478 */
479 static OSDictionary * copyLoadedKextInfo(
480 OSArray * kextIdentifiers = NULL,
481 OSArray * keys = NULL);
482 static OSDictionary * copyLoadedKextInfoByUUID(
483 OSArray * kextIdentifiers = NULL,
484 OSArray * keys = NULL);
485 static OSData * copyKextUUIDForAddress(OSNumber *address = NULL);
486 virtual OSDictionary * copyInfo(OSArray * keys = NULL);
487
488 /* Logging to user space.
489 */
490 static OSKextLogSpec setUserSpaceLogFilter(
491 OSKextLogSpec userLogSpec,
492 bool captureFlag = false);
493 static OSArray * clearUserSpaceLogFilter(void);
494 static OSKextLogSpec getUserSpaceLogFilter(void);
495
496 /* OSMetaClasses defined by kext.
497 */
498 virtual OSReturn addClass(
499 OSMetaClass * aClass,
500 uint32_t numClasses);
501 virtual OSReturn removeClass(
502 OSMetaClass * aClass);
503 virtual bool hasOSMetaClassInstances(void);
504 virtual OSSet * getMetaClasses(void);
505 static void reportOSMetaClassInstances(
506 const char * kextIdentifier,
507 OSKextLogSpec msgLogSpec);
508 virtual void reportOSMetaClassInstances(
509 OSKextLogSpec msgLogSpec);
510
511 /* Resource requests and other callback stuff.
512 */
513 static OSReturn dispatchResource(OSDictionary * requestDict);
514
515 static OSReturn dequeueCallbackForRequestTag(
516 OSKextRequestTag requestTag,
517 OSDictionary ** callbackRecordOut);
518 static OSReturn dequeueCallbackForRequestTag(
519 OSNumber * requestTagNum,
520 OSDictionary ** callbackRecordOut);
521 static void invokeRequestCallback(
522 OSDictionary * callbackRecord,
523 OSReturn requestResult);
524 virtual void invokeOrCancelRequestCallbacks(
525 OSReturn callbackResult,
526 bool invokeFlag = true);
527 virtual uint32_t countRequestCallbacks(void);
528
529 /* panic() support.
530 */
531 static void printKextsInBacktrace(
532 vm_offset_t * addr,
533 unsigned int cnt,
534 int (* printf_func)(const char *fmt, ...),
535 bool lockFlag,
536 bool doUnslide);
537 static OSKextLoadedKextSummary *summaryForAddress(const uintptr_t addr);
538 static void *kextForAddress(const void *addr);
539 static boolean_t summaryIsInBacktrace(
540 OSKextLoadedKextSummary * summary,
541 vm_offset_t * addr,
542 unsigned int cnt);
543 static void printSummary(
544 OSKextLoadedKextSummary * summary,
545 int (* printf_func)(const char *fmt, ...),
546 bool doUnslide);
547
548 static int saveLoadedKextPanicListTyped(
549 const char * prefix,
550 int invertFlag,
551 int libsFlag,
552 char * paniclist,
553 uint32_t list_size);
554 static void saveLoadedKextPanicList(void);
555 void savePanicString(bool isLoading);
556 static void printKextPanicLists(int (*printf_func)(const char *fmt, ...));
557
558 /* Kext summary support.
559 */
560 static void updateLoadedKextSummaries(void);
561 void updateLoadedKextSummary(OSKextLoadedKextSummary *summary);
562 void updateActiveAccount(OSKextActiveAccount *accountp);
563
564 /* C++ Initialization.
565 */
566 virtual void setCPPInitialized(bool initialized=true);
567
568
569
570 #if PRAGMA_MARK
571 /**************************************/
572 #pragma mark Public Functions
573 /**************************************/
574 #endif
575 public:
576 // caller must release
577 static OSKext * lookupKextWithIdentifier(const char * kextIdentifier);
578 static OSKext * lookupKextWithIdentifier(OSString * kextIdentifier);
579 static OSKext * lookupKextWithLoadTag(OSKextLoadTag aTag);
580 static OSKext * lookupKextWithAddress(vm_address_t address);
581 static OSKext * lookupKextWithUUID(uuid_t uuid);
582
583 kernel_section_t *lookupSection(const char *segname, const char*secname);
584
585 static bool isKextWithIdentifierLoaded(const char * kextIdentifier);
586
587 static OSReturn loadKextWithIdentifier(
588 const char * kextIdentifier,
589 Boolean allowDeferFlag = true,
590 Boolean delayAutounloadFlag = false,
591 OSKextExcludeLevel startOpt = kOSKextExcludeNone,
592 OSKextExcludeLevel startMatchingOpt = kOSKextExcludeAll,
593 OSArray * personalityNames = NULL);
594 static OSReturn loadKextWithIdentifier(
595 OSString * kextIdentifier,
596 Boolean allowDeferFlag = true,
597 Boolean delayAutounloadFlag = false,
598 OSKextExcludeLevel startOpt = kOSKextExcludeNone,
599 OSKextExcludeLevel startMatchingOpt = kOSKextExcludeAll,
600 OSArray * personalityNames = NULL);
601 static OSReturn removeKextWithIdentifier(
602 const char * kextIdentifier,
603 bool terminateServicesAndRemovePersonalitiesFlag = false);
604 static OSReturn removeKextWithLoadTag(
605 OSKextLoadTag loadTag,
606 bool terminateServicesAndRemovePersonalitiesFlag = false);
607
608 static OSReturn requestResource(
609 const char * kextIdentifier,
610 const char * resourceName,
611 OSKextRequestResourceCallback callback,
612 void * context,
613 OSKextRequestTag * requestTagOut);
614 static OSReturn cancelRequest(
615 OSKextRequestTag requestTag,
616 void ** contextOut);
617
618 static void considerUnloads(Boolean rescheduleOnlyFlag = false);
619 static void flushNonloadedKexts(Boolean flushPrelinkedKexts);
620 static void setKextdActive(Boolean active = true);
621 static void setDeferredLoadSucceeded(Boolean succeeded = true);
622 static void considerRebuildOfPrelinkedKernel(void);
623 static void createExcludeListFromBooterData(
624 OSDictionary * theDictionary,
625 OSCollectionIterator * theIterator);
626 static void createExcludeListFromPrelinkInfo(OSArray * theInfoArray);
627
628 virtual bool setAutounloadEnabled(bool flag);
629
630 virtual const OSSymbol * getIdentifier(void);
631 virtual const char * getIdentifierCString(void);
632 virtual OSKextVersion getVersion(void);
633 virtual OSKextVersion getCompatibleVersion(void);
634 virtual bool isLibrary(void);
635 virtual bool isCompatibleWithVersion(OSKextVersion aVersion);
636 virtual OSObject * getPropertyForHostArch(const char * key);
637
638 virtual OSKextLoadTag getLoadTag(void);
639 virtual void getSizeInfo(uint32_t *loadSize, uint32_t *wiredSize);
640 virtual OSData * copyUUID(void);
641 virtual OSArray * copyPersonalitiesArray(void);
642
643 /* This removes personalities naming the kext (by CFBundleIdentifier),
644 * not all personalities defined by the kext (IOPersonalityPublisher or CFBundleIdentifier).
645 */
646 virtual void removePersonalitiesFromCatalog(void);
647
648 /* Converts common string-valued properties to OSSymbols for lower memory consumption.
649 */
650 static void uniquePersonalityProperties(OSDictionary * personalityDict);
651
652 virtual bool declaresExecutable(void); // might be missing
653 virtual bool isInterface(void);
654 virtual bool isKernel(void);
655 virtual bool isKernelComponent(void);
656 virtual bool isExecutable(void);
657 virtual bool isLoadableInSafeBoot(void);
658 virtual bool isPrelinked(void);
659 virtual bool isLoaded(void);
660 virtual bool isStarted(void);
661 virtual bool isCPPInitialized(void);
662 };
663
664
665 #endif /* !_LIBKERN_OSKEXT_H */