1/*
2 * Copyright (c) 2008 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_OSKEXTLIB_H
30#define _LIBKERN_OSKEXTLIB_H
31
32#include <sys/cdefs.h>
33__BEGIN_DECLS
34
35#include <stdint.h>
36#include <mach/kmod.h>
37#include <mach/vm_types.h>
38
39#ifdef KERNEL
40#include <libkern/OSTypes.h>
41#include <libkern/OSReturn.h>
42#else
43#include <CoreFoundation/CoreFoundation.h>
44#include <System/libkern/OSReturn.h>
45#endif /* KERNEL */
46
47/*!
48 * @header
49 *
50 * Declares functions, basic return values, and other constants
51 * related to kernel extensions (kexts).
52 */
53
54#if PRAGMA_MARK
55#pragma mark -
56/********************************************************************/
57#pragma mark OSReturn Values for Kernel Extensions
58/********************************************************************/
59#endif
60/*!
61 * @group OSReturn Values for Kernel Extensions
62 * Many kext-related functions return these values,
63 * as well as those defined under
64 * <code>@link //apple_ref/c/tdef/OSReturn OSReturn@/link</code>
65 * and other variants of <code>kern_return_t</code>.
66 */
67
68#ifdef XNU_KERNEL_PRIVATE
69/*********************************************************************
70* Check libsyscall/mach/err_libkern.sub when editing or adding
71* result codes!
72*********************************************************************/
73#endif /* XNU_KERNEL_PRIVATE */
74
75#define sub_libkern_kext           err_sub(2)
76#define libkern_kext_err(code)     (sys_libkern|sub_libkern_kext|(code))
77
78
79/*!
80 * @define   kOSKextReturnInternalError
81 * @abstract An internal error in the kext library.
82 *           Contrast with <code>@link //apple_ref/c/econst/OSReturnError
83 *           OSReturnError@/link</code>.
84 */
85#define kOSKextReturnInternalError                   libkern_kext_err(0x1)
86
87/*!
88 * @define   kOSKextReturnNoMemory
89 * @abstract Memory allocation failed.
90 */
91#define kOSKextReturnNoMemory                        libkern_kext_err(0x2)
92
93/*!
94 * @define   kOSKextReturnNoResources
95 * @abstract Some resource other than memory (such as available load tags)
96 *           is exhausted.
97 */
98#define kOSKextReturnNoResources                     libkern_kext_err(0x3)
99
100/*!
101 * @define   kOSKextReturnNotPrivileged
102 * @abstract The caller lacks privileges to perform the requested operation.
103 */
104#define kOSKextReturnNotPrivileged                   libkern_kext_err(0x4)
105
106/*!
107 * @define   kOSKextReturnInvalidArgument
108 * @abstract Invalid argument.
109 */
110#define kOSKextReturnInvalidArgument                 libkern_kext_err(0x5)
111
112/*!
113 * @define   kOSKextReturnNotFound
114 * @abstract Search item not found.
115 */
116#define kOSKextReturnNotFound                        libkern_kext_err(0x6)
117
118/*!
119 * @define   kOSKextReturnBadData
120 * @abstract Malformed data (not used for XML).
121 */
122#define kOSKextReturnBadData                         libkern_kext_err(0x7)
123
124/*!
125 * @define   kOSKextReturnSerialization
126 * @abstract Error converting or (un)serializing URL, string, or XML.
127 */
128#define kOSKextReturnSerialization                   libkern_kext_err(0x8)
129
130/*!
131 * @define   kOSKextReturnUnsupported
132 * @abstract Operation is no longer or not yet supported.
133 */
134#define kOSKextReturnUnsupported                     libkern_kext_err(0x9)
135
136/*!
137 * @define   kOSKextReturnDisabled
138 * @abstract Operation is currently disabled.
139 */
140#define kOSKextReturnDisabled                        libkern_kext_err(0xa)
141
142/*!
143 * @define   kOSKextReturnNotAKext
144 * @abstract Bundle is not a kernel extension.
145 */
146#define kOSKextReturnNotAKext                        libkern_kext_err(0xb)
147
148/*!
149 * @define   kOSKextReturnValidation
150 * @abstract Validation failures encountered; check diagnostics for details.
151 */
152#define kOSKextReturnValidation                      libkern_kext_err(0xc)
153
154/*!
155 * @define   kOSKextReturnAuthentication
156 * @abstract Authetication failures encountered; check diagnostics for details.
157 */
158#define kOSKextReturnAuthentication                  libkern_kext_err(0xd)
159
160/*!
161 * @define   kOSKextReturnDependencies
162 * @abstract Dependency resolution failures encountered; check diagnostics for details.
163 */
164#define kOSKextReturnDependencies                    libkern_kext_err(0xe)
165
166/*!
167 * @define   kOSKextReturnArchNotFound
168 * @abstract Kext does not contain code for the requested architecture.
169 */
170#define kOSKextReturnArchNotFound                    libkern_kext_err(0xf)
171
172/*!
173 * @define   kOSKextReturnCache
174 * @abstract An error occurred processing a system kext cache.
175 */
176#define kOSKextReturnCache                           libkern_kext_err(0x10)
177
178/*!
179 * @define   kOSKextReturnDeferred
180 * @abstract Operation has been posted asynchronously to user space (kernel only).
181 */
182#define kOSKextReturnDeferred                        libkern_kext_err(0x11)
183
184/*!
185 * @define   kOSKextReturnBootLevel
186 * @abstract Kext not loadable or operation not allowed at current boot level.
187 */
188#define kOSKextReturnBootLevel                       libkern_kext_err(0x12)
189
190/*!
191 * @define   kOSKextReturnNotLoadable
192 * @abstract Kext cannot be loaded; check diagnostics for details.
193 */
194#define kOSKextReturnNotLoadable                     libkern_kext_err(0x13)
195
196/*!
197 * @define   kOSKextReturnLoadedVersionDiffers
198 * @abstract A different version (or executable UUID, or executable by checksum)
199 *           of the requested kext is already loaded.
200 */
201#define kOSKextReturnLoadedVersionDiffers            libkern_kext_err(0x14)
202
203/*!
204 * @define   kOSKextReturnDependencyLoadError
205 * @abstract A load error occurred on a dependency of the kext being loaded.
206 */
207#define kOSKextReturnDependencyLoadError             libkern_kext_err(0x15)
208
209/*!
210 * @define   kOSKextReturnLinkError
211 * @abstract A link failure occured with this kext or a dependency.
212 */
213#define kOSKextReturnLinkError                       libkern_kext_err(0x16)
214
215/*!
216 * @define   kOSKextReturnStartStopError
217 * @abstract The kext start or stop routine returned an error.
218 */
219#define kOSKextReturnStartStopError                  libkern_kext_err(0x17)
220
221/*!
222 * @define   kOSKextReturnInUse
223 * @abstract The kext is currently in use or has outstanding references,
224 *           and cannot be unloaded.
225 */
226#define kOSKextReturnInUse                           libkern_kext_err(0x18)
227
228/*!
229 * @define   kOSKextReturnTimeout
230 * @abstract A kext request has timed out.
231 */
232#define kOSKextReturnTimeout                         libkern_kext_err(0x19)
233
234/*!
235 * @define   kOSKextReturnStopping
236 * @abstract The kext is in the process of stopping; requests cannot be made.
237 */
238#define kOSKextReturnStopping                        libkern_kext_err(0x1a)
239
240#if PRAGMA_MARK
241#pragma mark -
242/********************************************************************/
243#pragma mark Kext/OSBundle Property List Keys
244/********************************************************************/
245#endif
246/*!
247 * @group Kext Property List Keys
248 * These constants cover CFBundle properties defined for kernel extensions.
249 * Because they are used in the kernel, if you want to use one with
250 * CFBundle APIs you'll need to wrap it in a <code>CFSTR()</code> macro.
251 */
252
253#ifdef KERNEL
254/* Define C-string versions of the CFBundle keys for use in the kernel.
255 */
256#define kCFBundleIdentifierKey                  "CFBundleIdentifier"
257#define kCFBundleVersionKey                     "CFBundleVersion"
258#define kCFBundleNameKey                        "CFBundleName"
259#define kCFBundleExecutableKey                  "CFBundleExecutable"
260#endif /* KERNEL */
261
262/*!
263 * @define   kOSBundleCompatibleVersionKey
264 * @abstract A string giving the backwards-compatible version of a library kext
265 *           in extended Mac OS 'vers' format (####.##.##s{1-255} where 's'
266 *           is a build stage 'd', 'a', 'b', 'f' or 'fc').
267 */
268#define kOSBundleCompatibleVersionKey           "OSBundleCompatibleVersion"
269
270/*!
271 * @define   kOSBundleEnableKextLoggingKey
272 * @abstract Set to true to have the kernel kext logging spec applied
273 *           to the kext.
274 *           See <code>@link //apple_ref/c/econst/OSKextLogSpec
275 *           OSKextLogSpec@/link</code>.
276 */
277#define kOSBundleEnableKextLoggingKey           "OSBundleEnableKextLogging"
278
279/*!
280 * @define   kOSBundleIsInterfaceKey
281 * @abstract A boolean value indicating whether the kext executable
282 *           contains only symbol references.
283 */
284#define kOSBundleIsInterfaceKey                 "OSBundleIsInterface"
285
286/*!
287 * @define   kOSBundleLibrariesKey
288 * @abstract A dictionary listing link dependencies for this kext.
289 *           Keys are bundle identifiers, values are version strings.
290 */
291#define kOSBundleLibrariesKey                   "OSBundleLibraries"
292
293/*!
294 * @define   kOSBundleRequiredKey
295 * @abstract A string indicating in which kinds of startup this kext
296 *           may need to load during early startup (before
297 *           <code>@link //apple_ref/doc/man/8/kextd kextcache(8)@/link</code>).
298 * @discussion
299 * The value is one of:
300 * <ul>
301 * <li>@link kOSBundleRequiredRoot "OSBundleRequiredRoot"@/link</li>
302 * <li>@link kOSBundleRequiredLocalRoot "OSBundleRequiredLocalRoot"@/link</li>
303 * <li>@link kOSBundleRequiredNetworkRoot "OSBundleRequiredNetworkRoot"@/link</li>
304 * <li>@link kOSBundleRequiredSafeBoot "OSBundleRequiredSafeBoot"@/link</li>
305 * <li>@link kOSBundleRequiredConsole "OSBundleRequiredConsole"@/link</li>
306 * </ul>
307 *
308 * Use this property judiciously.
309 * Every kext that declares a value other than "OSBundleRequiredSafeBoot"
310 * increases startup time, as the booter must read it into memory,
311 * or startup kext caches must include it.
312 */
313#define kOSBundleRequiredKey                    "OSBundleRequired"
314
315/*!
316 * @define   kOSBundleAllowUserLoadKey
317 * @abstract A boolean value indicating whether
318 *           <code>@link //apple_ref/doc/man/8/kextd kextcache(8)@/link</code>
319 *           will honor a non-root process's request to load a kext.
320 * @discussion
321 * See <code>@link //apple_ref/doc/compositePage/c/func/KextManagerLoadKextWithURL
322 * KextManagerLoadKextWithURL@/link</code>
323 * and <code>@link //apple_ref/doc/compositePage/c/func/KextManagerLoadKextWithIdentifier
324 * KextManagerLoadKextWithIdentifier@/link</code>.
325 */
326#define kOSBundleAllowUserLoadKey               "OSBundleAllowUserLoad"
327
328/*!
329 * @define   kOSKernelResourceKey
330 * @abstract A boolean value indicating whether the kext represents a built-in
331 *           component of the kernel.
332 */
333#define kOSKernelResourceKey                    "OSKernelResource"
334
335/*!
336 * @define   kIOKitPersonalitiesKey
337 * @abstract A dictionary of dictionaries used in matching for I/O Kit drivers.
338 */
339#define kIOKitPersonalitiesKey                  "IOKitPersonalities"
340
341/*
342 * @define   kIOPersonalityPublisherKey
343 * @abstract Used in personalities sent to the I/O Kit,
344 *           contains the CFBundleIdentifier of the kext
345 *           that the personality originated in.
346 */
347#define kIOPersonalityPublisherKey              "IOPersonalityPublisher"
348
349#if CONFIG_KEC_FIPS
350/*
351 * @define   kAppleTextHashesKey
352 * @abstract A dictionary conataining hashes for corecrypto kext.
353 */
354#define kAppleTextHashesKey                     "AppleTextHashes"
355#endif
356
357
358
359#if PRAGMA_MARK
360/********************************************************************/
361#pragma mark Kext/OSBundle Property Deprecated Keys
362/********************************************************************/
363#endif
364/*
365 * @define   kOSBundleDebugLevelKey
366 * @abstract
367 * Deprecated (used on some releases of Mac OS X prior to 10.6 Snow Leopard).
368 * Value is an integer from 1-6, corresponding to the verbose levels
369 * of kext tools on those releases.
370 * On 10.6 Snow Leopard, use <code>@link OSKextEnableKextLogging
371 * OSKextEnableKextLogging@/link</code>.
372 */
373#define kOSBundleDebugLevelKey                  "OSBundleDebugLevel"
374
375/*!
376 * @define   kOSBundleSharedExecutableIdentifierKey
377 * @abstract Deprecated (used on some releases of Mac OS X
378 *           prior to 10.6 Snow Leopard).
379 *           Value is the bundle identifier of the pseudokext
380 *           that contains an executable shared by this kext.
381 */
382#define kOSBundleSharedExecutableIdentifierKey  "OSBundleSharedExecutableIdentifier"
383
384
385#if PRAGMA_MARK
386/********************************************************************/
387#pragma mark Kext/OSBundle Property List Values
388/********************************************************************/
389#endif
390
391/*!
392 * @group Kext Property List Values
393 * These constants encompass established values
394 * for kernel extension bundle properties.
395 */
396
397/*!
398* @define   kOSKextKernelIdentifier
399* @abstract
400* This is the CFBundleIdentifier user for the kernel itself.
401*/
402#define kOSKextKernelIdentifier                 "__kernel__"
403
404/*!
405* @define   kOSBundleRequiredRoot
406* @abstract
407* This <code>@link kOSBundleRequiredKey OSBundleRequired@/link</code>
408* value indicates that the kext may be needed to mount the root filesystem
409* whether starting from a local or a network volume.
410*/
411#define kOSBundleRequiredRoot                   "Root"
412
413/*!
414* @define   kOSBundleRequiredLocalRoot
415* @abstract
416* This <code>@link kOSBundleRequiredKey OSBundleRequired@/link</code>
417* value indicates that the kext may be needed to mount the root filesystem
418* when starting from a local disk.
419*/
420#define kOSBundleRequiredLocalRoot              "Local-Root"
421
422/*!
423* @define   kOSBundleRequiredNetworkRoot
424* @abstract
425* This <code>@link kOSBundleRequiredKey OSBundleRequired@/link</code>
426* value indicates that the kext may be needed to mount the root filesystem
427* when starting over a network connection.
428*/
429#define kOSBundleRequiredNetworkRoot            "Network-Root"
430
431/*!
432* @define   kOSBundleRequiredSafeBoot
433* @abstract
434* This <code>@link kOSBundleRequiredKey OSBundleRequired@/link</code>
435* value indicates that the kext can be loaded during a safe startup.
436* This value does not normally cause the kext to be read by the booter
437* or included in startup kext caches.
438*/
439#define kOSBundleRequiredSafeBoot               "Safe Boot"
440
441/*!
442* @define   kOSBundleRequiredConsole
443* @abstract
444* This <code>@link kOSBundleRequiredKey OSBundleRequired@/link</code>
445* value indicates that the kext may be needed for console access
446* (specifically in a single-user startup when
447* <code>@link //apple_ref/doc/man/8/kextd kextd(8)@/link</code>.
448* does not run)
449* and should be loaded during early startup.
450*/
451#define kOSBundleRequiredConsole                "Console"
452
453
454#if PRAGMA_MARK
455#pragma mark -
456/********************************************************************/
457#pragma mark Kext Information
458/********************************************************************/
459#endif
460/*!
461 * @group Kext Information
462 * Types, constants, and macros providing a kext with information
463 * about itself.
464 */
465
466/*!
467 * @typedef OSKextLoadTag
468 *
469 * @abstract
470 * A unique identifier assigned to a loaded instanace of a kext.
471 *
472 * @discussion
473 * If a kext is unloaded and later reloaded, the new instance
474 * has a different load tag.
475 *
476 * A kext can get its own load tag in the <code>kmod_info_t</code>
477 * structure passed into its module start routine, as the
478 * <code>id</code> field (cast to this type).
479 * You can use the load tag with the functions
480 * <code>@link OSKextRetainKextWithLoadTag
481 * OSKextRetainKextWithLoadTag@/link</code> and
482 * <code>@link OSKextReleaseKextWithLoadTag
483 * OSKextReleaseKextWithLoadTag@/link</code>.
484 */
485typedef uint32_t  OSKextLoadTag;
486
487/*!
488 * @define kOSKextInvalidLoadTag
489 *
490 * @abstract
491 * A load tag value that will never be used for a loaded kext;
492 * indicates kext not found.
493 */
494#define  kOSKextInvalidLoadTag  ((OSKextLoadTag)(-1))
495
496
497#ifdef KERNEL
498
499/* Make these visible to kexts only and *not* the kernel.
500 */
501#if !XNU_KERNEL_PRIVATE
502
503/*!
504 * @function OSKextGetCurrentLoadTag
505 *
506 * @abstract
507 * Returns the run-time load tag for the calling kext as an
508 * <code>@link OSKextLoadTag OSKextLoadTag@/link</code>.
509 *
510 * @result
511 * The run-time load tag for the calling kext as an
512 * <code>@link OSKextLoadTag@/link</code>.
513 *
514 * @discussion
515 * The load tag identifies this loaded instance of the kext to the kernel
516 * and to kernel functions that operate on kexts.
517 */
518OSKextLoadTag OSKextGetCurrentLoadTag(void);
519
520/*!
521 * @function OSKextGetCurrentIdentifier
522 *
523 * @abstract
524 * Returns the CFBundleIdentifier for the calling kext as a C string.
525 *
526 * @result
527 * The CFBundleIdentifier for the calling kext as a C string.
528 */
529const char * OSKextGetCurrentIdentifier(void);
530
531/*!
532 * @function OSKextGetCurrentVersionString
533 *
534 * @abstract
535 * Returns the CFBundleVersion for the calling kext as a C string.
536 *
537 * @result
538 * The CFBundleVersion for the calling kext as a C string.
539 */
540const char * OSKextGetCurrentVersionString(void);
541
542#endif /* !XNU_KERNEL_PRIVATE */
543
544#if PRAGMA_MARK
545#pragma mark -
546/********************************************************************/
547#pragma mark Kext Loading C Functions
548/********************************************************************/
549#endif
550/*!
551 * @group Kext Loading C Functions
552 * Functions for loading and tracking kexts in the kernel.
553 */
554
555/*!
556 * @function OSKextLoadKextWithIdentifier
557 *
558 * @abstract
559 * Request that a kext be loaded.
560 *
561 * @param  kextIdentifier  The bundle identifier of the kext to be loaded.
562 *
563 * @result
564 * <code>@link //apple_ref/c/macro/kOSReturnSuccess kOSReturnSuccess@/link</code>
565 * if the kext was loaded (or was already loaded).
566 * <code>@link //apple_ref/c/macro/kOSKextReturnDeferred kOSKextReturnDeferred@/link</code>
567 * if the kext was not found and a request
568 * was queued to <code>@link //apple_ref/doc/man/8/kextd kextd(8)@/link</code>.
569 * Other return values indicate a failure to load the kext.
570 *
571 * @discussion
572 * If a kext is already in the kernel but not loaded, it is loaded immediately.
573 * If it isn't found, an asynchronous load request is
574 * made to <code>@link //apple_ref/doc/man/8/kextd kextd(8)@/link</code>
575 * and  <code>@link //apple_ref/c/macro/kOSKextReturnDeferred kOSKextReturnDeferred@/link</code> is returned.
576 * There is no general notification or callback mechanism for load requests.
577 */
578OSReturn OSKextLoadKextWithIdentifier(const char * kextIdentifier);
579
580
581/*!
582 * @function OSKextRetainKextWithLoadTag
583 *
584 * @abstract
585 * Retain a loaded kext based on its load tag,
586 * and enable autounload for that kext.
587 *
588 * @param  loadTag   The load tag of the kext to be retained.
589 *                   See <code>@link OSKextGetCurrentLoadTag@/link</code>.
590 *
591 * @result
592 * <code>@link //apple_ref/c/macro/kOSReturnSuccess kOSReturnSuccess@/link</code>
593 * if the kext was retained.
594 * <code>@link //apple_ref/c/macro/kOSKextReturnNotFound kOSKextReturnNotFound@/link</code>
595 * if the kext was not found.
596 * <code>@link //apple_ref/c/macro/kOSKextReturnInvalidArgument
597 * kOSKextReturnInvalidArgument@/link</code>
598 * if <code>loadTag</code> is
599 * <code>@link kOSKextInvalidLoadTag kOSKextInvalidLoadTag@/link</code>.
600 *
601 * @discussion
602 * Retaining a kext prevents it from being unloaded,
603 * either explicitly or automatically, and enables autounload for the kext.
604 * When autounload is enabled, then shortly after the kext's last reference
605 * is dropped, it will be unloaded if there are no outstanding references to it
606 * and there are no instances of its Libkern C++ subclasses (if any).
607 *
608 * Kexts that define subclasses of
609 * <code>@link //apple_ref/doc/class/IOService IOService@/link</code>
610 * have autounload enabled automatically.
611 * Other kexts can use the reference count to manage automatic unload
612 * without having to define and create Libkern C++ objects.
613 * For example, a filesystem kext can retain itself whenever a new mount
614 * is created, and release itself when a mount is removed.
615 * When the last mount is removed, the kext will be unloaded after a brief delay.
616 *
617 * A kext can get its own load tag using the
618 * <code>@link OSKextGetCurrentLoadTag@/link</code>.
619 *
620 * Kexts should not retain and release other kexts; linkage references
621 * are accounted for internally.
622 */
623OSReturn OSKextRetainKextWithLoadTag(OSKextLoadTag loadTag);
624
625
626/*!
627 * @function OSKextReleaseKextWithLoadTag
628 *
629 * @abstract
630 * Release a loaded kext based on its load tag.
631 *
632 * @param  loadTag   The load tag of the kext to be released.
633 *                   See <code>@link OSKextGetCurrentLoadTag@/link</code>.
634 *
635 * @result
636 * <code>@link //apple_ref/c/macro/kOSReturnSuccess kOSReturnSuccess@/link</code>
637 * if the kext was released.
638 * <code>@link //apple_ref/c/macro/kOSKextReturnNotFound
639 * kOSKextReturnNotFound@/link</code>
640 * if the kext was not found.
641 * <code>@link //apple_ref/c/macro/kOSKextReturnInvalidArgument
642 * kOSKextReturnInvalidArgument@/link</code>
643 * if <code>loadTag</code> is
644 * <code>@link kOSKextInvalidLoadTag kOSKextInvalidLoadTag@/link</code>.
645 *
646 * @discussion
647 * The kext should have been retained previously via
648 * <code>@link OSKextRetainKextWithLoadTag@/link</code>.
649 *
650 * This function schedules an autounload scan for all kexts.
651 * When that scan occurs, if a kext has autounload enabled,
652 * it will be unloaded if there are no outstanding references to it
653 * and there are no instances of its Libkern C++ classes (if any).
654 *
655 * Kexts that define subclasses of
656 * <code>@link //apple_ref/doc/class/IOService IOService@/link</code>
657 * have autounload enabled automatically.
658 * Other kexts can use the reference count to manage automatic unload
659 * without having to define and create Libkern C++ objects.
660 * For example, a filesystem kext can be retained whenever a new mount
661 * is created, and released when a mount is removed.
662 * When the last mount is removed, the kext will be unloaded after a brief delay.
663 *
664 * While the autounload scan takes place after a delay of at least a minute,
665 * a kext that manages its own reference counts for autounload should
666 * be prepared to have its module stop function called even while the function
667 * calling this function is still running.
668 *
669 * A kext can get its own load tag using the
670 * <code>@link OSKextGetCurrentLoadTag@/link</code>.
671 *
672 * Kexts should not retain and release other kexts; linkage references
673 * are accounted for internally.
674 */
675OSReturn OSKextReleaseKextWithLoadTag(OSKextLoadTag loadTag);
676
677#if PRAGMA_MARK
678/********************************************************************/
679#pragma mark -
680#pragma mark Kext Requests
681/********************************************************************/
682#endif
683/*!
684 * @group Kext Requests to User Space
685 * Functions for making requests to kextd in user space.
686 */
687
688/*!
689 * @typedef OSKextRequestTag
690 *
691 * @abstract
692 * Identifies a kext request made to user space.
693 */
694typedef uint32_t OSKextRequestTag;
695
696/*!
697 * @define kOSKextRequestTagInvalid
698 *
699 * @abstract
700 * A request tag value that will never be used for a kext request;
701 * indicates failure to create/queue the request.
702 */
703#define kOSKextRequestTagInvalid  ((OSKextRequestTag)-1)
704
705/*!
706 * @typedef OSKextRequestResourceCallback
707 *
708 * @abstract
709 * Invoked to provide results for a kext resource request.
710 *
711 * @param  requestTag          The tag of the request that the callback pertains to.
712 * @param  result              The result of the request:
713 *                             <code>@link kOSReturnSuccess
714 *                             kOSReturnSuccess@/link</code>
715 *                             if the request was fulfilled;
716 *                             <code>@link kOSKextReturnTimeout
717 *                             kOSKextReturnTimeout@/link</code>
718 *                             if the request has timed out;
719 *                             <code>@link kOSKextReturnStopping
720 *                             kOSKextReturnStopping@/link</code>
721 *                             if the kext containing the callback
722 *                             address for the kext is being unloaded;
723 *                             or other values on error.
724 * @param  resourceData        A pointer to the requested resource data.
725 *                             Owned by the system; the kext should make a copy
726 *                             if it needs to keep the data past the callback.
727 * @param  resourceDataLength  The length of <code>resourceData</code>.
728 * @param  context             The context pointer originally passed to
729 *                             <code>@link OSKextRequestResource
730 *                             OSKextRequestResource@/link</code>.
731 */
732typedef void (* OSKextRequestResourceCallback)(
733    OSKextRequestTag                requestTag,
734    OSReturn                        result,
735    const void                    * resourceData,
736    uint32_t                        resourceDataLength,
737    void                          * context);
738
739/*!
740 * @function OSKextRequestResource
741 *
742 * @abstract
743 * Requests data from a nonlocalized resource file in a kext bundle on disk.
744 *
745 * @param  kextIdentifier  The CFBundleIdentifier of the kext
746 *                         from which to read the file.
747 * @param  resourceName    The name of the resource file to read.
748 * @param  callback        A pointer to a callback function; the address
749 *                         must be within a currently-loaded kext.
750 * @param  context         A pointer to arbitrary run-time data
751 *                         that will be passed to the callback
752 *                         when it is invoked. May be <code>NULL</code>.
753 * @param  requestTagOut   If non-<code>NULL</code>,
754 *                         filled on success with a tag identifying the
755 *                         pending request
756 *                         (or on failure with <code>@link kOSKextRequestTagInvalid
757 *                         kOSKextRequestTagInvalid@/link</code>;
758 *                         can be used with
759 *                         <code>@link OSKextCancelRequest
760 *                         OSKextCancelRequest@/link</code>.
761 *
762 * @result
763 * <code>@link kOSReturnSuccess kOSReturnSuccess@/link</code>
764 * if the request is successfully queued.
765 * <code>@link kOSKextReturnInvalidArgument kOSKextReturnInvalidArgument@/link</code>
766 * if <code>kextIdentifier</code> or <code>resourceName</code> or if
767 * <code>callback</code> is not an address within a loaded kext executable.
768 * <code>@link kOSKextReturnStopping kOSKextReturnStopping@/link</code>
769 * if an unload attempt is being made
770 * on the kext containing <code>callback</code>.
771 * Other <code>OSKextReturn...</code> errors are possible.
772 *
773 * @discussion
774 * This function queues an asynchronous request to the user-space kext daemon
775 * <code>@link //apple_ref/doc/man/8/kextd kextd(8)@/link</code>;
776 * requests for resources early in system startup
777 * will not be fulfilled until that daemon starts.
778 * Requests made by a kext while that kext is loading
779 * (specifically in the kext's module start routine)
780 * will not be fulfilled until after the start routine returns and
781 * the kext is completely loaded.
782 * Kexts requesting resources should be sure to perform appropriate locking
783 * in the callback function.
784 *
785 * Kext resources are stored in the kext's on-disk bundle under the
786 * Resources subdirectory.
787 * See {@linkdoc //apple_ref/doc/uid/10000123i Bundle Programming Guide}
788 * for an overview of bundle structure.
789 * The localization context of the kext daemon
790 * (namely that of the superuser)
791 * will be used in retrieving resources;
792 * kext resources intended for use in the kernel
793 * should generally not be localized.
794 *
795 * <code>callback</code> is guaranteed to be invoked except when:
796 * <ul>
797 * <li>@link OSKextCancelRequest <code>OSKextCancelRequest</code>@/link
798 *     is used to cancel the request.
799 *     In this case the kext gets the <code>context</code> pointer
800 *     and can clean it up.</li>
801 * <li>The request is made during a kext's module start routine
802 *     and the start routine returns an error.
803 *     In this case, callbacks cannot be safely invoked, so
804 *     the kext should clean up all request contexts
805 *     when returning the error from the start routine.</li>
806 * </ul>
807 *
808 * Kexts with pending requests are not subject to autounload,
809 * but requests are subject to timeout after a few minutes.
810 * If that amount of time passes with no response from user space,
811 * <code>callback</code> is invoked with a result of.
812 * <code>@link kOSKextReturnTimeout kOSKextReturnTimeout@/link</code>.
813 *
814 * Kexts that are explicitly unloaded have all pending request callbacks
815 * invoked with a result of
816 * <code>@link kOSKextReturnStopping kOSKextReturnStopping@/link</code>.
817 * The kext must handle these callbacks,
818 * even if its stop routine will prevent unloading.
819 * If the kext does prevent unloading, it can reissue resource requests
820 * outside of the stop function.
821 */
822OSReturn OSKextRequestResource(
823    const char                    * kextIdentifier,
824    const char                    * resourceName,
825    OSKextRequestResourceCallback   callback,
826    void                          * context,
827    OSKextRequestTag              * requestTagOut);
828
829/*!
830 * @function OSKextCancelRequest
831 *
832 * @abstract
833 * Cancels a pending user-space kext request without invoking the callback.
834 *
835 * @param  requestTag  A tag identifying a pending request.
836 * @param  contextOut  If non-<code>NULL</code>, filled with the context pointer
837 *                     originally passed with the request.
838 *
839 * @result
840 * <code>@link kOSReturnSuccess kOSReturnSuccess@/link</code>
841 * if the request is successfully canceled.
842 * <code>@link kOSKextReturnNotFound kOSKextReturnNotFound@/link</code>
843 * if <code>requestTag</code> does not identify any pending request.
844 * Other <code>OSKextReturn...</code> errors are possible.
845 *
846 * @discussion
847 * This function cancels a pending request if it exists,
848 * so that its callback will not be invoked.
849 * It returns in <code>contextOut</code>
850 * the context pointer used to create the request
851 * so that any resources allocated for the request can be cleaned up.
852 *
853 * Kexts do not need to cancel outstanding requests
854 * in their module stop functions;
855 * when a kext is unloaded, all pending request callbacks
856 * are invoked with a result of
857 * <code>@link kOSKextReturnTimeout kOSKextReturnTimeout@/link</code>
858 * before the stop function is called.
859 */
860OSReturn OSKextCancelRequest(
861    OSKextRequestTag    requestTag,
862    void             ** contextOut);
863
864
865#if PRAGMA_MARK
866#pragma mark -
867/********************************************************************/
868#pragma mark Weak linking
869/********************************************************************/
870#endif
871/*!
872 * @group Weak Linking
873 * Support for weak references to symbols in kexts.
874 */
875
876/*!
877 * @var gOSKextUnresolved
878 *
879 * @abstract
880 * The value to which a kext's unresolved, weakly-referenced symbols are bound.
881 *
882 * @discussion
883 * A kext must test a weak symbol before using it.  A weak symbol
884 * is only safe to use if it is not equal to <code>gOSKextUnresolved</code>.
885 *
886 * Example for a weak symbol named <code>foo</code>:
887 * <pre>
888 * @textblock
889 *      if (&foo != gOSKextUnresolved) {
890 *          foo();
891 *      } else {
892 *          printf("foo() is not supported\n");
893 *      }
894 * @/textblock
895 * </pre>
896 */
897extern const void * gOSKextUnresolved;
898
899/*!
900 * @define OSKextSymbolIsResolved
901 *
902 * @abstract
903 * Checks whether a weakly-referenced symbol has been resolved.
904 *
905 * @param weak_sym   The weak symbol to be tested for resolution.
906 *
907 * @result
908 * <code>TRUE</code> if weak_sym is resolved, or <code>FALSE</code>
909 * if weak_sym is unresolved.
910 *
911 * @discussion
912 * This is a convenience macro for testing if weak symbols are resolved.
913 *
914 * Example for a weak symbol named <code>foo</code>:
915 * <pre>
916 * @textblock
917 *      if (OSKextSymbolIsResolved(foo)) {
918 *          foo();
919 *      } else {
920 *          printf("foo() is not resolved\n");
921 *      }
922 * @/textblock
923 * </pre>
924 */
925#define OSKextSymbolIsResolved(weak_sym)        \
926    (&(weak_sym) != gOSKextUnresolved)
927
928
929#if CONFIG_KEC_FIPS
930
931#if PRAGMA_MARK
932#pragma mark -
933/********************************************************************/
934#pragma mark Kernel External Components for FIPS compliance
935/********************************************************************/
936#endif
937
938// Kernel External Components for FIPS compliance (KEC_FIPS)
939// WARNING - ath_hash is owned by the kernel, do not free
940typedef struct AppleTEXTHash {
941    const int       ath_version;    // version of this structure (value is 1)
942    int             ath_length;     // length of hash data
943    void *          ath_hash;       // hash extracted from AppleTextHashes dict
944} AppleTEXTHash_t;
945#endif // CONFIG_KEC_FIPS
946
947#endif /* KERNEL */
948
949__END_DECLS
950
951#endif /* _LIBKERN_OSKEXTLIB_H */
952