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 | |
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 | |
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 |
57 | extern "C" { |
58 | void osdata_kmem_free(void * ptr, unsigned int length); |
59 | void osdata_phys_free(void * ptr, unsigned int length); |
60 | void osdata_vm_deallocate(void * ptr, unsigned int length); |
61 | void osdata_kext_free(void * ptr, unsigned int length); |
62 | void 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 | *********************************************************************/ |
74 | class OSKext; |
75 | class OSDextStatistics; |
76 | |
77 | extern "C" { |
78 | void OSKextLog( |
79 | OSKext * aKext, |
80 | OSKextLogSpec msgLogSpec, |
81 | const char * format, ...) __printflike(3, 4); |
82 | |
83 | void OSKextVLog( |
84 | OSKext * aKext, |
85 | OSKextLogSpec msgLogSpec, |
86 | const char * format, |
87 | va_list srcArgList) __printflike(3, 0);; |
88 | |
89 | #ifdef XNU_KERNEL_PRIVATE |
90 | void OSKextRemoveKextBootstrap(void); |
91 | |
92 | kern_return_t OSRuntimeInitializeCPP( |
93 | OSKext * kext); |
94 | kern_return_t OSRuntimeFinalizeCPP( |
95 | OSKext * kext); |
96 | void OSRuntimeUnloadCPPForSegment( |
97 | kernel_segment_command_t * segment); |
98 | void |
99 | OSRuntimeSignStructors( |
100 | kernel_mach_header_t * ); |
101 | void |
102 | OSRuntimeSignStructorsInFileset( |
103 | kernel_mach_header_t * ); |
104 | |
105 | kern_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 | |
112 | void kmod_dump_log(vm_offset_t*, unsigned int, boolean_t); |
113 | void *OSKextKextForAddress(const void *addr); |
114 | |
115 | kern_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 | |
127 | struct list_head { |
128 | struct list_head *prev; |
129 | struct list_head *next; |
130 | }; |
131 | |
132 | struct 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 | |
148 | struct 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 | |
163 | struct OSKextActiveAccount { |
164 | uintptr_t address; |
165 | uintptr_t address_end; |
166 | OSKextAccount * account; |
167 | }; |
168 | typedef struct OSKextActiveAccount OSKextActiveAccount; |
169 | |
170 | class OSKextSavedMutableSegment : public OSObject { |
171 | OSDeclareDefaultStructors(OSKextSavedMutableSegment); |
172 | public: |
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; |
178 | private: |
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 | |
186 | typedef enum { |
187 | kOSDextCrashPolicyNone, |
188 | kOSDextCrashPolicyReboot, |
189 | } OSDextCrashPolicy; |
190 | |
191 | enum { |
192 | kMaxDextCrashesInOneDayDefault = 3, |
193 | }; |
194 | |
195 | class OSDextStatistics : public OSObject { |
196 | OSDeclareDefaultStructors(OSDextStatistics); |
197 | public: |
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 | |
205 | private: |
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 | /********************************************************************/ |
222 | class 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 | |
304 | private: |
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 | */ |
393 | public: |
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 | |
407 | private: |
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 (kernel_mach_header_t *mh, |
543 | OSDictionary *infoDict, const char *text_seg_name, |
544 | OSData **kcUUID, kc_kind_t type); |
545 | |
546 | static bool (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 (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 (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 | */ |
728 | public: |
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); |
746 | private: |
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 |
779 | public: |
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 |
791 | public: |
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> (const kernel_mach_header_t * ); |
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 | |
948 | extern "C" void OSKextResetAfterUserspaceReboot(void); |
949 | |
950 | #endif /* !_LIBKERN_OSKEXT_H */ |
951 | |