1/*
2 * Copyright (c) 2008-2019 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
32extern "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
45#include <libkern/OSKextLib.h>
46#include <libkern/OSKextLibPrivate.h>
47#include <libkern/c++/OSObject.h>
48#include <libkern/c++/OSContainers.h>
49
50#include <libkern/c++/OSPtr.h>
51#include <IOKit/IOLocks.h>
52
53/*********************************************************************
54* C functions used for callbacks.
55*********************************************************************/
56#ifdef XNU_KERNEL_PRIVATE
57extern "C" {
58void osdata_kmem_free(void * ptr, unsigned int length);
59void osdata_phys_free(void * ptr, unsigned int length);
60void osdata_vm_deallocate(void * ptr, unsigned int length);
61void osdata_kext_free(void * ptr, unsigned int length);
62void kxld_log_callback(
63 KXLDLogSubsystem subsystem,
64 KXLDLogLevel level,
65 const char * format,
66 va_list argList,
67 void * user_data);
68};
69#endif /* XNU_KERNEL_PRIVATE */
70
71/*********************************************************************
72* C Function Prototypes for Friend Declarations.
73*********************************************************************/
74class OSKext;
75class OSDextStatistics;
76
77extern "C" {
78void OSKextLog(
79 OSKext * aKext,
80 OSKextLogSpec msgLogSpec,
81 const char * format, ...) __printflike(3, 4);
82
83void OSKextVLog(
84 OSKext * aKext,
85 OSKextLogSpec msgLogSpec,
86 const char * format,
87 va_list srcArgList) __printflike(3, 0);;
88
89#ifdef XNU_KERNEL_PRIVATE
90void OSKextRemoveKextBootstrap(void);
91
92kern_return_t OSRuntimeInitializeCPP(
93 OSKext * kext);
94kern_return_t OSRuntimeFinalizeCPP(
95 OSKext * kext);
96void OSRuntimeUnloadCPPForSegment(
97 kernel_segment_command_t * segment);
98void
99OSRuntimeSignStructors(
100 kernel_mach_header_t * header);
101void
102OSRuntimeSignStructorsInFileset(
103 kernel_mach_header_t * fileset_header);
104
105kern_return_t is_io_catalog_send_data(
106 mach_port_t masterPort,
107 uint32_t flag,
108 io_buf_ptr_t inData,
109 mach_msg_type_number_t inDataCount,
110 kern_return_t * result);
111
112void kmod_dump_log(vm_offset_t*, unsigned int, boolean_t);
113void *OSKextKextForAddress(const void *addr);
114
115kern_return_t OSKextGetLoadedKextSummaryForAddress(
116 const void * addr,
117 OSKextLoadedKextSummary * summary);
118
119#endif /* XNU_KERNEL_PRIVATE */
120};
121
122/********************************************************************/
123#if PRAGMA_MARK
124#pragma mark -
125#endif
126
127struct list_head {
128 struct list_head *prev;
129 struct list_head *next;
130};
131
132struct OSKextGrabPgoStruct {
133 bool metadata;
134 uint64_t *pSize;
135 char *pBuffer;
136 uint64_t bufferSize;
137 int err;
138 struct list_head list_head;
139};
140
141#ifndef container_of
142#define container_of(ptr, type, member) ((type*)(((uintptr_t)ptr) - offsetof(type, member)))
143#endif
144/********************************************************************/
145
146#if XNU_KERNEL_PRIVATE
147
148struct OSKextAccount {
149 vm_allocation_site_t site;
150
151#if DEVELOPMENT || DEBUG
152 struct os_refgrp task_refgrp;
153 /*
154 * '5' for the "task_" prefix. task_refgrp_name can be entirely dropped
155 * once we can directly flag the refgrp to be logged.
156 */
157 char task_refgrp_name[5 + KMOD_MAX_NAME];
158#endif /* DEVELOPMENT || DEBUG */
159 uint32_t loadTag;
160 OSKext * kext;
161};
162
163struct OSKextActiveAccount {
164 uintptr_t address;
165 uintptr_t address_end;
166 OSKextAccount * account;
167};
168typedef struct OSKextActiveAccount OSKextActiveAccount;
169
170class OSKextSavedMutableSegment : public OSObject {
171 OSDeclareDefaultStructors(OSKextSavedMutableSegment);
172public:
173 static OSPtr<OSKextSavedMutableSegment> withSegment(kernel_segment_command_t *seg);
174 OSReturn restoreContents(kernel_segment_command_t *seg);
175 vm_offset_t getVMAddr() const;
176 vm_size_t getVMSize() const;
177 virtual void free(void) APPLE_KEXT_OVERRIDE;
178private:
179 bool initWithSegment(kernel_segment_command_t *seg);
180 kernel_segment_command_t *savedSegment;
181 vm_offset_t vmaddr;
182 vm_size_t vmsize;
183 void * data;
184};
185
186typedef enum {
187 kOSDextCrashPolicyNone,
188 kOSDextCrashPolicyReboot,
189} OSDextCrashPolicy;
190
191enum {
192 kMaxDextCrashesInOneDayDefault = 3,
193};
194
195class OSDextStatistics : public OSObject {
196 OSDeclareDefaultStructors(OSDextStatistics);
197public:
198 static OSPtr<OSDextStatistics> create();
199 virtual bool init() APPLE_KEXT_OVERRIDE;
200 virtual void free() APPLE_KEXT_OVERRIDE;
201
202 OSDextCrashPolicy recordCrash();
203 size_t getCrashCount();
204
205private:
206 OSPtr<OSArray> crashes;
207 IOLock * lock;
208};
209
210__enum_closed_decl(OSKextInitResult, uint8_t, {
211 kOSKextInitFailure = 0,
212 kOSKextInitialized,
213 kOSKextAlreadyExist,
214});
215
216#endif /* XNU_KERNEL_PRIVATE */
217
218/*
219 * @class OSKext
220 */
221/********************************************************************/
222class OSKext : public OSObject
223{
224 OSDeclareDefaultStructors(OSKext);
225
226#if PRAGMA_MARK
227/**************************************/
228#pragma mark Friend Declarations
229/**************************************/
230#endif
231 friend class IOCatalogue;
232 friend class KLDBootstrap;
233 friend class OSMetaClass;
234
235 friend int OSKextGrabPgoData(uuid_t uuid,
236 uint64_t *pSize,
237 char *pBuffer,
238 uint64_t bufferSize,
239 int wait_for_unload,
240 int metadata);
241
242#ifdef XNU_KERNEL_PRIVATE
243 friend void OSKextVLog(
244 OSKext * aKext,
245 OSKextLogSpec msgLogSpec,
246 const char * format,
247 va_list srcArgList) __printflike(3, 0);
248
249 friend void OSKextRemoveKextBootstrap(void);
250 friend OSReturn OSKextUnloadKextWithLoadTag(uint32_t);
251
252 friend kern_return_t kext_request(
253 host_priv_t hostPriv,
254 /* in only */ uint32_t clientLogSpec,
255 /* in only */ vm_offset_t requestIn,
256 /* in only */ mach_msg_type_number_t requestLengthIn,
257 /* out only */ vm_offset_t * responseOut,
258 /* out only */ mach_msg_type_number_t * responseLengthOut,
259 /* out only */ vm_offset_t * logDataOut,
260 /* out only */ mach_msg_type_number_t * logDataLengthOut,
261 /* out only */ kern_return_t * op_result);
262
263 friend kxld_addr_t kern_allocate(
264 u_long size,
265 KXLDAllocateFlags * flags,
266 void * user_data);
267
268 friend void kxld_log_shim(
269 KXLDLogSubsystem subsystem,
270 KXLDLogLevel level,
271 const char * format,
272 va_list argList,
273 void * user_data);
274
275 friend void _OSKextConsiderUnloads(
276 __unused thread_call_param_t p0,
277 __unused thread_call_param_t p1);
278
279 friend kern_return_t OSRuntimeInitializeCPP(
280 OSKext * kext);
281 friend kern_return_t OSRuntimeFinalizeCPP(
282 OSKext * kext);
283 friend void OSRuntimeUnloadCPPForSegment(
284 kernel_segment_command_t * segment);
285
286 friend kern_return_t is_io_catalog_send_data(
287 mach_port_t masterPort,
288 uint32_t flag,
289 io_buf_ptr_t inData,
290 mach_msg_type_number_t inDataCount,
291 kern_return_t * result);
292
293 friend void kmod_panic_dump(vm_offset_t*, unsigned int);
294 friend void kmod_dump_log(vm_offset_t*, unsigned int, boolean_t);
295 friend void kext_dump_panic_lists(int (*printf_func)(const char * fmt, ...));
296 friend void *OSKextKextForAddress(const void *addr);
297
298 friend kern_return_t OSKextGetLoadedKextSummaryForAddress(
299 const void * addr,
300 OSKextLoadedKextSummary * summary);
301
302#endif /* XNU_KERNEL_PRIVATE */
303
304private:
305
306/*************************
307* Instance variables
308*************************/
309 OSPtr<OSDictionary> infoDict;
310
311 OSPtr<const OSSymbol> bundleID;
312 OSPtr<OSString> path; // not necessarily correct :-/
313 OSPtr<OSString> executableRelPath;// relative to bundle
314 OSPtr<OSString> userExecutableRelPath;// relative to bundle
315
316 OSKextVersion version; // parsed
317 OSKextVersion compatibleVersion;// parsed
318
319/* These fields are required for tracking loaded kexts and
320 * will always have values for a loaded kext.
321 */
322 OSKextLoadTag loadTag; // 'id' from old kmod_info;
323 // kOSKextInvalidLoadTag invalid
324 kmod_info_t * kmod_info; // address into linkedExec./alloced for interface
325
326 OSPtr<OSArray> dependencies; // kernel resource does not have any;
327 // links directly to kernel
328
329/* Only real kexts have these; interface kexts do not.
330 */
331 OSPtr<OSData> linkedExecutable;
332 OSPtr<OSSet> metaClasses; // for C++/OSMetaClass kexts
333
334/* Only interface kexts have these; non-interface kexts can get at them
335 * in the linked Executable.
336 */
337 OSPtr<OSData> interfaceUUID;
338 OSPtr<OSData> driverKitUUID;
339
340 struct {
341 unsigned int loggingEnabled:1;
342
343 unsigned int hasAllDependencies:1;
344 unsigned int hasBleedthrough:1;
345
346 unsigned int interface:1;
347 unsigned int kernelComponent:1;
348 unsigned int prelinked:1;
349 unsigned int builtin:1;
350 unsigned int loaded:1;
351 unsigned int dtraceInitialized:1;
352 unsigned int starting:1;
353 unsigned int started:1;
354 unsigned int stopping:1;
355 unsigned int unloading:1;
356 unsigned int resetSegmentsFromVnode:1;
357
358 unsigned int requireExplicitLoad:1;
359 unsigned int autounloadEnabled:1;
360 unsigned int delayAutounload:1; // for development
361
362 unsigned int CPPInitialized:1;
363 unsigned int jettisonLinkeditSeg:1;
364 unsigned int resetSegmentsFromImmutableCopy:1;
365 unsigned int unloadUnsupported:1;
366 unsigned int dextToReplace:1;
367
368 /* The Mach-O header contains segment addresses which are unslid. */
369 unsigned int unslidMachO:1;
370 } flags;
371
372 uint32_t matchingRefCount;
373 kc_kind_t kc_type;
374
375 struct list_head pendingPgoHead;
376 uuid_t instance_uuid;
377 OSKextAccount * account;
378 uint32_t builtinKmodIdx;
379 OSPtr<OSArray> savedMutableSegments;
380 OSPtr<OSDextStatistics> dextStatistics;
381 OSPtr<OSData> dextUniqueID;
382 uint32_t dextLaunchedCount;
383
384#if PRAGMA_MARK
385/**************************************/
386#pragma mark Private Functions
387/**************************************/
388#endif
389
390#ifdef XNU_KERNEL_PRIVATE
391/* Startup/shutdown phases.
392 */
393public:
394 static void initialize(void);
395 static OSPtr<OSDictionary> copyKexts(void);
396 static OSReturn removeKextBootstrap(void);
397 static void willShutdown(void);// called by IOPMrootDomain on shutdown
398 static void willUserspaceReboot(void);
399 static void resetAfterUserspaceReboot(void);
400 static void reportOSMetaClassInstances(
401 const char * kextIdentifier,
402 OSKextLogSpec msgLogSpec);
403 static void OSKextLogDriverKitInfoLoad(OSKext *kext);
404 static bool iokitDaemonAvailable(void);
405#endif /* XNU_KERNEL_PRIVATE */
406
407private:
408/* Called by power management at sleep/shutdown.
409 */
410 static bool setLoadEnabled(bool flag);
411 static bool setUnloadEnabled(bool flag);
412 static bool setAutounloadsEnabled(bool flag);
413 static bool setKernelRequestsEnabled(bool flag);
414
415// all getters subject to race condition, caller beware
416 static bool getLoadEnabled(void);
417 static bool getUnloadEnabled(void);
418 static bool getAutounloadEnabled(void);
419 static bool getKernelRequestsEnabled(void);
420
421/* Instance life cycle.
422 */
423 static OSData *parseDextUniqueID(
424 OSDictionary * anInfoDict,
425 const char *dextIDCS);
426 static void setDextUniqueIDInPersonalities(
427 OSDictionary * anInfoDict,
428 OSData * dextUniqueID);
429
430 static OSPtr<OSKext> withBooterData(
431 OSString * deviceTreeName,
432 OSData * booterData);
433 virtual bool initWithBooterData(
434 OSString * deviceTreeName,
435 OSData * booterData);
436
437 static OSPtr<OSKext> withPrelinkedInfoDict(
438 OSDictionary * infoDict,
439 bool doCoalesedSlides, kc_kind_t type);
440 virtual bool initWithPrelinkedInfoDict(
441 OSDictionary * infoDict,
442 bool doCoalesedSlides, kc_kind_t type);
443 static OSSharedPtr<OSKext> withCodelessInfo(
444 OSDictionary * infoDict, OSKextInitResult *result);
445
446 virtual OSKextInitResult initWithCodelessInfo(
447 OSDictionary * infoDict);
448
449 static void setAllVMAttributes(void);
450
451 virtual bool setInfoDictionaryAndPath(
452 OSDictionary * aDictionary,
453 OSString * aPath);
454 virtual bool setExecutable(
455 OSData * anExecutable,
456 OSData * externalData = NULL,
457 bool externalDataIsMkext = false);
458 virtual OSKextInitResult registerIdentifier(void);
459
460 virtual void free(void) APPLE_KEXT_OVERRIDE;
461
462 static OSReturn removeKext(
463 OSKext * aKext,
464 bool terminateServicesAndRemovePersonalitiesFlag = false);
465
466 virtual bool isInExcludeList(void);
467 virtual bool isLoadable(void);
468
469 static OSKext * allocAndInitFakeKext(
470 kmod_info_t *kmod_info);
471
472/* Mkexts.
473 */
474#if CONFIG_KXLD
475 static OSPtr<OSKext> withMkext2Info(
476 OSDictionary * anInfoDict,
477 OSData * mkextData);
478 virtual bool initWithMkext2Info(
479 OSDictionary * anInfoDict,
480 OSData * mkextData);
481
482 static OSReturn readMkextArchive(
483 OSData * mkextData,
484 uint32_t * checksumPtr = NULL);
485 static OSReturn readMkext2Archive(
486 OSData * mkextData,
487 OSDictionary ** mkextPlistOut,
488 uint32_t * checksumPtr = NULL);
489
490 static OSReturn readMkext2Archive(
491 OSData * mkextData,
492 OSSharedPtr<OSDictionary> &mkextPlistOut,
493 uint32_t * checksumPtr = NULL);
494
495 virtual OSPtr<OSData> createMkext2FileEntry(
496 OSData * mkextData,
497 OSNumber * offsetNum,
498 const char * entryName);
499 virtual OSPtr<OSData> extractMkext2FileData(
500 UInt8 * data,
501 const char * name,
502 uint32_t compressedSize,
503 uint32_t fullSize);
504#endif // CONFIG_KXLD
505
506/* Dependencies.
507 */
508 virtual bool resolveDependencies(
509 OSArray * loopStack = NULL); // priv/prot
510 virtual bool addBleedthroughDependencies(OSArray * anArray);
511 virtual bool flushDependencies(bool forceFlag = false); // priv/prot
512 virtual uint32_t getNumDependencies(void);
513 virtual OSArray * getDependencies(void);
514
515/* User-space requests (load/generic).
516 */
517 static OSReturn loadFromMkext(
518 OSKextLogSpec clientLogSpec,
519 char * mkextBuffer,
520 uint32_t mkextBufferLength,
521 char ** logInfoOut,
522 uint32_t * logInfoLengthOut);
523 static OSReturn handleRequest(
524 host_priv_t hostPriv,
525 OSKextLogSpec clientLogSpec,
526 char * requestBuffer,
527 uint32_t requestLength,
528 char ** responseOut,
529 uint32_t * responseLengthOut,
530 char ** logInfoOut,
531 uint32_t * logInfoLengthOut);
532 static OSReturn loadCodelessKext(
533 OSString * kextIdentifier,
534 OSDictionary * requestDict);
535 static OSReturn serializeLogInfo(
536 OSArray * logInfoArray,
537 char ** logInfoOut,
538 uint32_t * logInfoLengthOut);
539
540/* Loading.
541 */
542 static bool addKextsFromKextCollection(kernel_mach_header_t *mh,
543 OSDictionary *infoDict, const char *text_seg_name,
544 OSData **kcUUID, kc_kind_t type);
545
546 static bool addKextsFromKextCollection(kernel_mach_header_t *mh,
547 OSDictionary *infoDict, const char *text_seg_name,
548 OSSharedPtr<OSData> &kcUUID, kc_kind_t type);
549
550 static bool registerDeferredKextCollection(kernel_mach_header_t *mh,
551 OSSharedPtr<OSObject> &parsedXML, kc_kind_t type);
552 static OSSharedPtr<OSObject> consumeDeferredKextCollection(kc_kind_t type);
553
554 virtual OSReturn load(
555 OSKextExcludeLevel startOpt = kOSKextExcludeNone,
556 OSKextExcludeLevel startMatchingOpt = kOSKextExcludeAll,
557 OSArray * personalityNames = NULL);// priv/prot
558 virtual OSReturn unload(void);
559 static OSReturn queueKextNotification(
560 const char * notificationName,
561 OSString * kextIdentifier,
562 OSData * dextUniqueIdentifier);
563
564 static void recordIdentifierRequest(
565 OSString * kextIdentifier);
566
567 virtual OSReturn slidePrelinkedExecutable(bool doCoalesedSlides);
568 virtual OSReturn loadExecutable(void);
569 virtual void jettisonLinkeditSegment(void);
570 virtual void jettisonDATASegmentPadding(void);
571 static void considerDestroyingLinkContext(void);
572 virtual OSData * getExecutable(void);
573 virtual void setLinkedExecutable(OSData * anExecutable);
574
575#if CONFIG_DTRACE
576 friend void OSKextRegisterKextsWithDTrace(void);
577 static void registerKextsWithDTrace(void);
578 virtual void registerWithDTrace(void);
579 virtual void unregisterWithDTrace(void);
580#endif /* CONFIG_DTRACE */
581
582 virtual OSReturn start(bool startDependenciesFlag = true);
583 virtual OSReturn stop(void);
584 virtual OSReturn setVMAttributes(bool protect, bool wire);
585 virtual boolean_t segmentShouldBeWired(kernel_segment_command_t *seg);
586 virtual OSReturn validateKextMapping(bool startFlag);
587 virtual boolean_t verifySegmentMapping(kernel_segment_command_t *seg);
588
589 static OSPtr<OSArray> copyAllKextPersonalities(
590 bool filterSafeBootFlag = false);
591
592 static void setPrelinkedPersonalities(OSArray * personalitiesArray);
593
594 static void sendAllKextPersonalitiesToCatalog(
595 bool startMatching = false);
596 virtual OSReturn sendPersonalitiesToCatalog(
597 bool startMatching = false,
598 OSArray * personalityNames = NULL);
599
600 static bool canUnloadKextWithIdentifier(
601 OSString * kextIdentifier,
602 bool checkClassesFlag = true);
603
604 static OSReturn autounloadKext(OSKext * aKext);
605
606/* Sync with user space.
607 */
608 static OSReturn pingIOKitDaemon(void);
609 static bool driverkitEnabled(void);
610
611/* Getting info about loaded kexts (kextstat).
612 */
613 static OSPtr<OSDictionary> copyLoadedKextInfo(
614 OSArray * kextIdentifiers = NULL,
615 OSArray * keys = NULL);
616 static OSPtr<OSDictionary> copyLoadedKextInfoByUUID(
617 OSArray * kextIdentifiers = NULL,
618 OSArray * keys = NULL);
619 static OSPtr<OSDictionary> copyKextCollectionInfo(
620 OSDictionary *requestDict,
621 OSArray *infoKeys = NULL);
622 static OSPtr<OSData> copyKextUUIDForAddress(OSNumber *address = NULL);
623 static OSPtr<OSArray> copyDextsInfo(
624 OSArray * kextIdentifiers = NULL,
625 OSArray * keys = NULL);
626 virtual OSPtr<OSDictionary> copyInfo(OSArray * keys = NULL);
627
628/* Logging to user space.
629 */
630 static OSKextLogSpec setUserSpaceLogFilter(
631 OSKextLogSpec userLogSpec,
632 bool captureFlag = false);
633 static OSPtr<OSArray> clearUserSpaceLogFilter(void);
634 static OSKextLogSpec getUserSpaceLogFilter(void);
635
636/* OSMetaClasses defined by kext.
637 */
638 virtual OSReturn addClass(
639 OSMetaClass * aClass,
640 uint32_t numClasses);
641 virtual OSReturn removeClass(
642 OSMetaClass * aClass);
643 virtual bool hasOSMetaClassInstances(void);
644 virtual OSSet * getMetaClasses(void);
645
646 virtual void reportOSMetaClassInstances(
647 OSKextLogSpec msgLogSpec);
648
649/* Resource requests and other callback stuff.
650 */
651 static OSReturn loadFileSetKexts(OSDictionary * requestDict);
652
653 static OSReturn loadKCFileSet(const char *filepath, kc_kind_t type);
654
655#if defined(__x86_64__) || defined(__i386__)
656 static OSReturn mapKCFileSet(
657 void *control,
658 vm_size_t fsize,
659 kernel_mach_header_t **mh,
660 off_t file_offset,
661 uintptr_t *slide,
662 bool pageable,
663 void *map_entry_buffer);
664 static OSReturn protectKCFileSet(
665 kernel_mach_header_t *mh,
666 kc_kind_t type);
667 static OSReturn mapKCTextSegment(
668 void *control,
669 kernel_mach_header_t **mhp,
670 off_t file_offset,
671 uintptr_t *slide,
672 void *map_entry_list);
673 static void freeKCFileSetcontrol(void);
674 OSReturn resetKCFileSetSegments(void);
675#endif //(__x86_64__) || defined(__i386__)
676
677 static void jettisonFileSetLinkeditSegment(kernel_mach_header_t *mh);
678 static OSReturn validateKCFileSetUUID(
679 OSDictionary *infoDict,
680 kc_kind_t type);
681
682 static OSReturn validateKCUUIDfromPrelinkInfo(
683 uuid_t *loaded_kcuuid,
684 kc_kind_t type,
685 OSDictionary *infoDict,
686 const char *uuid_key);
687
688 static OSReturn dispatchResource(OSDictionary * requestDict);
689
690 static OSReturn setMissingAuxKCBundles(OSDictionary * requestDict);
691
692 static OSReturn setAuxKCBundleAvailable(OSString *kextIdentifier,
693 OSDictionary *requestDict);
694
695 static OSReturn dequeueCallbackForRequestTag(
696 OSKextRequestTag requestTag,
697 LIBKERN_RETURNS_RETAINED OSDictionary ** callbackRecordOut);
698 static OSReturn dequeueCallbackForRequestTag(
699 OSNumber * requestTagNum,
700 LIBKERN_RETURNS_RETAINED OSDictionary ** callbackRecordOut);
701
702 static OSReturn dequeueCallbackForRequestTag(
703 OSKextRequestTag requestTag,
704 OSSharedPtr<OSDictionary> &callbackRecordOut);
705 static OSReturn dequeueCallbackForRequestTag(
706 OSNumber * requestTagNum,
707 OSSharedPtr<OSDictionary> &callbackRecordOut);
708
709 static void invokeRequestCallback(
710 OSDictionary * callbackRecord,
711 OSReturn requestResult);
712 virtual void invokeOrCancelRequestCallbacks(
713 OSReturn callbackResult,
714 bool invokeFlag = true);
715 virtual uint32_t countRequestCallbacks(void);
716 OSReturn resetMutableSegments(void);
717 virtual OSData * getDextUniqueID(void);
718
719 static bool upgradeDext(
720 OSKext * olddext,
721 OSKext * newdext);
722 static bool removeDext(OSKext * dext);
723 static void replaceDextInternal(
724 OSKext * olddext,
725 OSKext * newdext);
726/* panic() support.
727 */
728public:
729 enum {
730 kPrintKextsLock = 0x01,
731 kPrintKextsUnslide = 0x02,
732 kPrintKextsTerse = 0x04
733 };
734 static void printKextsInBacktrace(
735 vm_offset_t * addr,
736 unsigned int cnt,
737 int (* printf_func)(const char *fmt, ...),
738 uint32_t flags);
739 static void foreachKextInBacktrace(
740 vm_offset_t * addr,
741 uint32_t cnt,
742 uint32_t flags,
743 void (^ handler)(OSKextLoadedKextSummary *summary, uint32_t index));
744 bool isDriverKit(void);
745 bool isInFileset(void);
746private:
747 static OSKextLoadedKextSummary *summaryForAddress(const uintptr_t addr);
748 static kern_return_t summaryForAddressExt(
749 const void * addr,
750 OSKextLoadedKextSummary * summary);
751 static void *kextForAddress(const void *addr);
752 static boolean_t summaryIsInBacktrace(
753 OSKextLoadedKextSummary * summary,
754 vm_offset_t * addr,
755 unsigned int cnt);
756 static void printSummary(
757 OSKextLoadedKextSummary * summary,
758 int (* printf_func)(const char *fmt, ...),
759 uint32_t flags);
760
761 static int saveLoadedKextPanicListTyped(
762 const char * prefix,
763 int invertFlag,
764 int libsFlag,
765 char * paniclist,
766 uint32_t list_size);
767 static void saveLoadedKextPanicList(void);
768 void savePanicString(bool isLoading);
769 static void printKextPanicLists(int (*printf_func)(const char *fmt, ...));
770
771/* Kext summary support.
772 */
773 static void updateLoadedKextSummaries(void);
774 void updateLoadedKextSummary(OSKextLoadedKextSummary *summary);
775 void updateActiveAccount(OSKextActiveAccount *accountp);
776 static void removeDaemonExitRequests(void);
777
778#ifdef XNU_KERNEL_PRIVATE
779public:
780#endif /* XNU_KERNEL_PRIVATE */
781
782/* C++ Initialization.
783 */
784 virtual void setCPPInitialized(bool initialized = true);
785
786#if PRAGMA_MARK
787/**************************************/
788#pragma mark Public Functions
789/**************************************/
790#endif
791public:
792 // caller must release
793 static OSPtr<OSKext> lookupKextWithIdentifier(const char * kextIdentifier);
794 static OSPtr<OSKext> lookupKextWithIdentifier(OSString * kextIdentifier);
795 static OSPtr<OSKext> lookupKextWithLoadTag(OSKextLoadTag aTag);
796 static OSPtr<OSKext> lookupKextWithAddress(vm_address_t address);
797 static OSPtr<OSKext> lookupKextWithUUID(uuid_t uuid);
798 static OSPtr<OSKext> lookupDextWithIdentifier(OSString * dextIdentifier, OSData *dextUniqueIdentifier);
799
800 kernel_section_t *lookupSection(const char *segname, const char*secname);
801
802 static bool isKextWithIdentifierLoaded(const char * kextIdentifier);
803
804 static OSReturn loadKextWithIdentifier(
805 const char * kextIdentifier,
806 Boolean allowDeferFlag = true,
807 Boolean delayAutounloadFlag = false,
808 OSKextExcludeLevel startOpt = kOSKextExcludeNone,
809 OSKextExcludeLevel startMatchingOpt = kOSKextExcludeAll,
810 OSArray * personalityNames = NULL);
811
812 static OSReturn loadKextWithIdentifier(
813 OSString * kextIdentifier,
814 LIBKERN_RETURNS_RETAINED_ON_ZERO OSObject ** kextRef,
815 Boolean allowDeferFlag = true,
816 Boolean delayAutounloadFlag = false,
817 OSKextExcludeLevel startOpt = kOSKextExcludeNone,
818 OSKextExcludeLevel startMatchingOpt = kOSKextExcludeAll,
819 OSArray * personalityNames = NULL);
820
821 static OSReturn loadKextWithIdentifier(
822 OSString * kextIdentifier,
823 OSSharedPtr<OSObject> &kextRef,
824 Boolean allowDeferFlag = true,
825 Boolean delayAutounloadFlag = false,
826 OSKextExcludeLevel startOpt = kOSKextExcludeNone,
827 OSKextExcludeLevel startMatchingOpt = kOSKextExcludeAll,
828 OSArray * personalityNames = NULL);
829
830 static OSReturn loadKextFromKC(OSKext *theKext, OSDictionary *requestDict);
831
832 static void dropMatchingReferences(
833 OSSet * kexts);
834
835 bool hasDependency(const OSSymbol * depID);
836
837 static OSReturn removeKextWithIdentifier(
838 const char * kextIdentifier,
839 bool terminateServicesAndRemovePersonalitiesFlag = false);
840 static OSReturn removeKextWithLoadTag(
841 OSKextLoadTag loadTag,
842 bool terminateServicesAndRemovePersonalitiesFlag = false);
843 static OSReturn requestDaemonLaunch(
844 OSString * kextIdentifier,
845 OSString * serverName,
846 OSNumber * serverTag,
847 OSBoolean * reslide,
848 class IOUserServerCheckInToken * checkInToken,
849 OSData *serverDUI);
850 static OSReturn notifyDextUpgrade(
851 OSString * kextIdentifier,
852 OSData * dextUniqueIdentifier);
853 static OSReturn requestResource(
854 const char * kextIdentifier,
855 const char * resourceName,
856 OSKextRequestResourceCallback callback,
857 void * context,
858 OSKextRequestTag * requestTagOut);
859 static OSReturn cancelRequest(
860 OSKextRequestTag requestTag,
861 void ** contextOut);
862
863 static void considerUnloads(Boolean rescheduleOnlyFlag = false);
864 static void flushNonloadedKexts(Boolean flushPrelinkedKexts);
865 static void setIOKitDaemonActive(bool active = true);
866 static void setDeferredLoadSucceeded(Boolean succeeded = true);
867 static void considerRebuildOfPrelinkedKernel(void);
868 static void createExcludeListFromBooterData(
869 OSDictionary * theDictionary,
870 OSCollectionIterator * theIterator);
871 static void createExcludeListFromPrelinkInfo(OSArray * theInfoArray);
872 static boolean_t updateExcludeList(OSDictionary * infoDict);
873
874 static bool pendingIOKitDaemonRequests(void);
875
876 virtual bool setAutounloadEnabled(bool flag);
877
878 virtual const OSObject * getBundleExecutable(void);
879 virtual const OSSymbol * getIdentifier(void);
880 virtual const char * getIdentifierCString(void);
881 virtual OSKextVersion getVersion(void);
882 virtual OSKextVersion getCompatibleVersion(void);
883 virtual bool isLibrary(void);
884 virtual bool isCompatibleWithVersion(OSKextVersion aVersion);
885 virtual OSObject * getPropertyForHostArch(const char * key);
886
887 virtual OSKextLoadTag getLoadTag(void);
888 virtual void getSizeInfo(uint32_t *loadSize, uint32_t *wiredSize);
889 virtual OSPtr<OSData> copyUUID(void);
890 OSPtr<OSData> copyTextUUID(void);
891 OSPtr<OSData> copyMachoUUID(const kernel_mach_header_t * header);
892 OSPtr<OSDextStatistics> copyDextStatistics();
893 virtual OSPtr<OSArray> copyPersonalitiesArray(void);
894 static bool copyUserExecutablePath(const OSSymbol * bundleID, char * pathResult, size_t pathSize);
895 virtual void setDriverKitUUID(LIBKERN_CONSUMED OSData *uuid);
896 static bool incrementDextLaunchCount(OSKext *dext, OSData *dextUniqueIDToMatch);
897 static bool decrementDextLaunchCount(OSString *bundleID);
898
899/* This removes personalities naming the kext (by CFBundleIdentifier),
900 * not all personalities defined by the kext (IOPersonalityPublisher or CFBundleIdentifier).
901 */
902 virtual void removePersonalitiesFromCatalog(void);
903/*
904 * This removes the personalities naming the kext (by CFBundleIdentifier), and atomically adds
905 * the new personalities upgradedPersonalities.
906 */
907 virtual void updatePersonalitiesInCatalog(OSArray *upgradedPersonalities);
908
909/* Converts common string-valued properties to OSSymbols for lower memory consumption.
910 */
911 static void uniquePersonalityProperties(OSDictionary * personalityDict);
912#ifdef XNU_KERNEL_PRIVATE
913 static void uniquePersonalityProperties(OSDictionary * personalityDict, bool defaultAddKernelBundleIdentifier);
914#endif
915
916 static bool iokitDaemonActive(void);
917
918 virtual bool declaresExecutable(void); // might be missing
919 virtual bool isInterface(void);
920 virtual bool isKernel(void);
921 virtual bool isKernelComponent(void);
922 virtual bool isExecutable(void);
923 virtual bool isSpecialKernelBinary(void);
924 virtual bool isLoadableInSafeBoot(void);
925 virtual bool isPrelinked(void);
926 virtual bool isLoaded(void);
927 virtual bool isStarted(void);
928 virtual bool isCPPInitialized(void);
929
930 const char *
931 getKCTypeString(void)
932 {
933 switch (kc_type) {
934 case KCKindPrimary:
935 return kKCTypePrimary;
936 case KCKindPageable:
937 return kKCTypeSystem;
938 case KCKindAuxiliary:
939 return kKCTypeAuxiliary;
940 case KCKindNone:
941 return kKCTypeCodeless;
942 default:
943 return "??";
944 }
945 }
946};
947
948extern "C" void OSKextResetAfterUserspaceReboot(void);
949
950#endif /* !_LIBKERN_OSKEXT_H */
951