Loading...
--- xnu/xnu-12377.101.15/libkern/c++/OSKext.cpp
+++ xnu/xnu-8019.80.24/libkern/c++/OSKext.cpp
@@ -36,7 +36,7 @@
#include <firehose/tracepoint_private.h>
#include <firehose/chunk_private.h>
#include <os/firehose_buffer_private.h>
-#include <vm/vm_map_xnu.h>
+#include <vm/vm_map.h>
#include <kextd/kextd_mach.h>
#include <libkern/kernel_mach_header.h>
#include <libkern/kext_panic_report.h>
@@ -50,9 +50,7 @@
#include <mach/mach_time.h>
#include <uuid/uuid.h>
#include <sys/random.h>
-#include <sys/reboot.h>
#include <pexpert/pexpert.h>
-#include <pexpert/device_tree.h>
#include <sys/pgo.h>
@@ -68,7 +66,7 @@
#include <security/mac_framework.h>
#endif
-#include <vm/vm_kern_xnu.h>
+#include <vm/vm_kern.h>
#include <sys/sysctl.h>
#include <kern/task.h>
#include <os/cpp_util.h>
@@ -88,10 +86,6 @@
#include <IOKit/IOPlatformExpert.h>
#include <san/kasan.h>
-
-#if CONFIG_SPTM
-#include <arm64/sptm/sptm.h>
-#endif
#if PRAGMA_MARK
#pragma mark External & Internal Function Protos
@@ -122,6 +116,7 @@
extern unsigned long gVirtBase;
extern unsigned long gPhysBase;
+extern vm_map_t g_kext_map;
bool pageableKCloaded = false;
bool auxKCloaded = false;
@@ -143,12 +138,11 @@
OSDictionary * requestDict,
const char * argName);
static bool _OSKextSetRequestArgument(
- OSDictionary * requestDict,
- const char * argName,
- OSMetaClassBase * value);
-template <typename T>
-static T * _OSKextExtractPointer(OSValueObject<T *> * wrapper);
-static OSKextRequestResourceCallback _OSKextExtractCallbackPointer(OSValueObject<OSKextRequestResourceCallback> * wrapper);
+ OSDictionary * requestDict,
+ const char * argName,
+ OSObject * value);
+static void * _OSKextExtractPointer(OSData * wrapper);
+static OSKextRequestResourceCallback _OSKextExtractCallbackPointer(OSData * wrapper);
static OSReturn _OSDictionarySetCStringValue(
OSDictionary * dict,
const char * key,
@@ -162,8 +156,6 @@
// So few pad slots, though....
static bool _OSArrayContainsCString(OSArray * array, const char * cString);
static void OSKextLogKextInfo(OSKext *aKext, uint64_t address, uint64_t size, firehose_tracepoint_code_t code);
-
-static const char *getDextUniqueIDCString(OSData *dextUniqueID, unsigned int *size);
/* Prelinked arm kexts do not have VM entries because the method we use to
* fake an entry (see libsa/bootstrap.cpp:readPrelinkedExtensions()) does
@@ -191,16 +183,12 @@
/* Use this number to create containers.
*/
#define kOSKextTypicalLoadCount (150)
-#define kOSKextTypicalUpgradeCount (5)
/* Any kext will have at least 1 retain for the internal lookup-by-ID dict.
* A loaded kext will no dependents or external retains will have 2 retains.
*/
#define kOSKextMinRetainCount (1)
#define kOSKextMinLoadedRetainCount (2)
-
-#define kOSKextMaxDextLaunchedCount (~((uint32_t)0))
-#define KOSBundleDextUniqueIdentifierMaxStringLength (KOSBundleDextUniqueIdentifierMaxLength * 2 +1)
/**********
* Strings and substrings used in dependency resolution.
@@ -329,7 +317,6 @@
static OSSharedPtr<OSDictionary> sNonLoadableKextsByID;
static OSSharedPtr<OSArray> sUnloadedPrelinkedKexts;
static OSSharedPtr<OSArray> sLoadedDriverKitKexts;
-static OSSharedPtr<OSDictionary> sDriverKitToUpgradeByID;
// Requests to the IOKit daemon waiting to be picked up.
static OSSharedPtr<OSArray> sKernelRequests;
@@ -362,16 +349,6 @@
* Stuff for the OSKext representing the kernel itself.
**********/
static OSKext * sKernelKext = NULL;
-
-/* Load Tag IDs used by statically loaded binaries (e.g, the kernel itself). */
-enum : uint32_t {
- kOSKextKernelLoadTag = 0,
-#if CONFIG_SPTM
- kOSKextSPTMLoadTag = 1,
- kOSKextTXMLoadTag = 2,
-#endif /* CONFIG_SPTM */
- kOSKextLoadTagCount
-};
/* Set up a fake kmod_info struct for the kernel.
* It's used in OSRuntime.cpp to call OSRuntimeInitializeCPP()
@@ -388,7 +365,7 @@
kmod_info_t g_kernel_kmod_info = {
.next = NULL,
.info_version = KMOD_INFO_VERSION,
- .id = kOSKextKernelLoadTag, // loadTag: kernel is always 0
+ .id = 0, // loadTag: kernel is always 0
.name = kOSKextKernelIdentifier,// bundle identifier
.version = "0", // filled in in OSKext::initialize()
.reference_count = -1, // never adjusted; kernel never unloads
@@ -399,39 +376,6 @@
.start = NULL,
.stop = NULL
};
-
-#if CONFIG_SPTM
-/* The SPTM and TXM need fake kmod structures just like the kernel. */
-kmod_info_t g_sptm_kmod_info = {
- .next = NULL,
- .info_version = KMOD_INFO_VERSION,
- .id = kOSKextSPTMLoadTag, // Always one after the kernel
- .name = kOSKextSPTMIdentifier,// bundle identifier
- .version = "0", // filled in by OSKext::initialize()
- .reference_count = -1, // never adjusted; SPTM never unloads
- .reference_list = NULL,
- .address = 0,
- .size = 0, // filled in by OSKext::initialize()
- .hdr_size = 0,
- .start = NULL,
- .stop = NULL
-};
-
-kmod_info_t g_txm_kmod_info = {
- .next = NULL,
- .info_version = KMOD_INFO_VERSION,
- .id = kOSKextTXMLoadTag, // Always one after the SPTM
- .name = kOSKextTXMIdentifier,// bundle identifier
- .version = "0", // filled in by OSKext::initialize()
- .reference_count = -1, // never adjusted; TXM never unloads
- .reference_list = NULL,
- .address = 0,
- .size = 0, // filled in by OSKext::initialize()
- .hdr_size = 0,
- .start = NULL,
- .stop = NULL
-};
-#endif /* CONFIG_SPTM */
/* Set up a fake kmod_info struct for statically linked kexts that don't have one. */
@@ -536,9 +480,8 @@
* to automatically parse the list of loaded kexts.
**********/
static IOLock * sKextSummariesLock = NULL;
-extern "C" lck_grp_t vm_page_lck_grp_bucket;
-static lck_grp_t * sKextAccountsLockGrp = &vm_page_lck_grp_bucket;
-#define sKextAccountsLock (&vm_allocation_sites_lock)
+extern "C" lck_spin_t vm_allocation_sites_lock;
+static IOSimpleLock * sKextAccountsLock = &vm_allocation_sites_lock;
void(*const sLoadedKextSummariesUpdated)(void) = OSKextLoadedKextSummariesUpdated;
OSKextLoadedKextSummaryHeader * gLoadedKextSummaries __attribute__((used)) = NULL;
@@ -552,7 +495,7 @@
/*********************************************************************
* sKextLoggingLock protects the logging variables declared immediately below.
**********/
-__static_testable IOLock * sKextLoggingLock = NULL;
+static IOLock * sKextLoggingLock = NULL;
static const OSKextLogSpec kDefaultKernelLogFilter = kOSKextLogBasicLevel |
kOSKextLogVerboseFlagsMask;
@@ -569,16 +512,6 @@
* End scope for sKextInnerLock-protected variables.
*********************************************************************/
-/*********************************************************************
- * OSValueObject concrete type instantiations
- **********/
-OSDefineValueObjectForDependentType(void*)
-OSDefineValueObjectForDependentType(OSKextRequestResourceCallback)
-
-
-/**********************************************************************/
-
-TUNABLE(uint32_t, kMaxDextCrashesInOneDay, "daily_max_dext_crashes", kMaxDextCrashesInOneDayDefault);
/*********************************************************************
* helper function used for collecting PGO data upon unload of a kext
@@ -797,175 +730,15 @@
OSDefineMetaClassAndStructors(OSKextSavedMutableSegment, OSObject);
-OSDefineMetaClassAndStructors(OSDextStatistics, OSObject);
-
-/*********************************************************************
-*********************************************************************/
-/**
- * Allocate and intialize a fake/representative OSKext object for a statically
- * loaded (by iBoot) binary (e.g., the XNU kernel itself).
- *
- * @param kmod_info Pointer to the kmod_info structure for the binary being
- * setup. At least the "name" and "id" fields needs to already
- * be set correctly.
- *
- * @return The allocated and initialized OSKext object.
- */
-/* static */
-OSKext *
-OSKext::allocAndInitFakeKext(kmod_info_t *kmod_info)
-{
- vm_offset_t load_address = 0;
- const char *bundle_name = NULL;
- bool macho_is_unslid = false;
- bool set_custom_path = false;
- const char *executable_fallback_name = NULL;
-
- if (kmod_info->id == kOSKextKernelLoadTag) {
- load_address = (vm_offset_t)&_mh_execute_header;
- bundle_name = "mach_kernel";
-
- /* The kernel Mach-O header is fixed up to slide all of its addresses. */
- macho_is_unslid = false;
-
- /**
- * No path to the binary is set for the kernel in its OSKext object. The
- * kernel binary is located in fixed directories depending on the OS.
- */
- set_custom_path = false;
- executable_fallback_name = NULL;
-#if CONFIG_SPTM
- } else if (kmod_info->id == kOSKextSPTMLoadTag) {
- load_address = (vm_offset_t)SPTMArgs->debug_header->image[DEBUG_HEADER_ENTRY_SPTM];
- bundle_name = "sptm";
-
- /* The addresses in the SPTM Mach-O header are all unslid. */
- macho_is_unslid = true;
-
- set_custom_path = true;
- executable_fallback_name = "sptm.no.binname.in.macho";
- } else if (kmod_info->id == kOSKextTXMLoadTag) {
- load_address = (vm_offset_t)SPTMArgs->debug_header->image[DEBUG_HEADER_ENTRY_TXM];
- bundle_name = "txm";
-
- /* The addresses in the TXM Mach-O header are all unslid. */
- macho_is_unslid = true;
-
- set_custom_path = true;
- executable_fallback_name = "txm.no.binname.in.macho";
-#endif /* CONFIG_SPTM */
- } else {
- panic("%s: Unsupported kmod_info->id (%d)", __func__, kmod_info->id);
- }
-
- /* Set up an OSKext instance to represent the statically loaded binary. */
- OSKext *fakeKext = new OSKext;
- assert(fakeKext);
- assert(load_address != 0);
-
- /*
- * The start address is always a slid address whereas the last VA returned
- * by getlastaddr() might be unslid depending on the Mach-O. If the address
- * coming from the Mach-O is unslid, then unslide the start address before
- * computing the length of the executable.
- */
- size_t binaryLength = getlastaddr((kernel_mach_header_t*)load_address);
- binaryLength -= (macho_is_unslid) ? ml_static_unslide(load_address) : load_address;
- assert(binaryLength <= UINT_MAX);
-
- /**
- * The load address is always slid. That value will be unslid before being
- * exposed to userspace.
- */
- OSSharedPtr<OSData> executable = OSData::withBytesNoCopy(
- (void*)load_address, (unsigned int)binaryLength);
- assert(executable);
-
- fakeKext->loadTag = sNextLoadTag++;
- fakeKext->bundleID = OSSymbol::withCString(kmod_info->name);
-
- fakeKext->version = OSKextParseVersionString(osrelease);
- fakeKext->compatibleVersion = fakeKext->version;
- fakeKext->linkedExecutable = os::move(executable);
- fakeKext->interfaceUUID = fakeKext->copyUUID();
-
- fakeKext->flags.hasAllDependencies = 1;
- fakeKext->flags.kernelComponent = 1;
- fakeKext->flags.prelinked = 0;
- fakeKext->flags.loaded = 1;
- fakeKext->flags.started = 1;
- fakeKext->flags.CPPInitialized = 0;
- fakeKext->flags.jettisonLinkeditSeg = 0;
- fakeKext->flags.unslidMachO = macho_is_unslid;
-
-#if CONFIG_SPTM
- if (set_custom_path) {
- /* Only SPTM/TXM should have custom paths to their executables set. */
- assert((kmod_info->id == kOSKextSPTMLoadTag) ||
- (kmod_info->id == kOSKextTXMLoadTag));
-
- /* All SPTM/TXM binaries are placed into the same path on internal systems. */
- fakeKext->path = OSString::withCStringNoCopy("/usr/appleinternal/standalone/platform");
-
- /**
- * Each SPTM/TXM Mach-O should contain a __TEXT,__binname section which contains
- * a character array representing the name of the Mach-O executable.
- */
- kernel_section_t *binname_sect =
- getsectbynamefromheader((kernel_mach_header_t*)load_address, "__TEXT", "__binname");
-
- if (binname_sect != NULL) {
- const char *binname = (const char *)ml_static_slide(binname_sect->addr);
- fakeKext->executableRelPath = OSString::withCStringNoCopy(binname);
- } else {
- fakeKext->executableRelPath = OSString::withCStringNoCopy(executable_fallback_name);
- }
- }
-#endif /* CONFIG_SPTM */
-
- fakeKext->kmod_info = kmod_info;
- strlcpy(kmod_info->version, osrelease,
- sizeof(kmod_info->version));
- kmod_info->size = binaryLength;
- assert(kmod_info->id == fakeKext->loadTag);
-
- /*
- * Con up an info dict, so we don't have to have special-case checking all
- * over.
- */
- fakeKext->infoDict = OSDictionary::withCapacity(5);
- assert(fakeKext->infoDict);
- bool setResult = fakeKext->infoDict->setObject(kCFBundleIdentifierKey,
- fakeKext->bundleID.get());
- assert(setResult);
- setResult = fakeKext->infoDict->setObject(kOSKernelResourceKey,
- kOSBooleanTrue);
- assert(setResult);
-
- {
- OSSharedPtr<OSString> scratchString(OSString::withCStringNoCopy(osrelease));
- assert(scratchString);
- setResult = fakeKext->infoDict->setObject(kCFBundleVersionKey,
- scratchString.get());
- assert(setResult);
- }
-
- {
- OSSharedPtr<OSString> scratchString(OSString::withCStringNoCopy(bundle_name));
- assert(scratchString);
- setResult = fakeKext->infoDict->setObject(kCFBundleNameKey,
- scratchString.get());
- assert(setResult);
- }
-
- return fakeKext;
-}
-
+/*********************************************************************
+*********************************************************************/
/* static */
void
OSKext::initialize(void)
{
OSSharedPtr<OSData> kernelExecutable = NULL;// do not release
+ u_char * kernelStart = NULL;// do not free
+ size_t kernelLength = 0;
IORegistryEntry * registryRoot = NULL;// do not release
OSSharedPtr<OSNumber> kernelCPUType;
OSSharedPtr<OSNumber> kernelCPUSubtype;
@@ -993,11 +766,9 @@
sPostedKextLoadIdentifiers = OSSet::withCapacity(0);
sAllKextLoadIdentifiers = OSSet::withCapacity(kOSKextTypicalLoadCount);
sRequestCallbackRecords = OSArray::withCapacity(0);
- sDriverKitToUpgradeByID = OSDictionary::withCapacity(kOSKextTypicalUpgradeCount);
-
assert(sKextsByID && sLoadedKexts && sLoadedDriverKitKexts && sKernelRequests &&
sPostedKextLoadIdentifiers && sAllKextLoadIdentifiers &&
- sRequestCallbackRecords && sUnloadedPrelinkedKexts && sDriverKitToUpgradeByID);
+ sRequestCallbackRecords && sUnloadedPrelinkedKexts);
/* Read the log flag boot-args and set the log flags.
*/
@@ -1038,10 +809,10 @@
sKeepSymbols = true;
}
#endif /* CONFIG_DTRACE */
-#if KASAN_DYNAMIC_DENYLIST
+#if KASAN_DYNAMIC_BLACKLIST
/* needed for function lookup */
sKeepSymbols = true;
-#endif /* KASAN_DYNAMIC_DENYLIST */
+#endif
/*
* Should we panic when the SystemKC is not linked against the
@@ -1052,15 +823,76 @@
sPanicOnKCMismatch = PE_parse_boot_argn("-nokcmismatchpanic", bootArgBuffer,
sizeof(bootArgBuffer)) ? false : true;
- /* Set up an OSKext instance to represent the kernel itself. */
- sKernelKext = allocAndInitFakeKext(&g_kernel_kmod_info);
+ /* Set up an OSKext instance to represent the kernel itself.
+ */
+ sKernelKext = new OSKext;
assert(sKernelKext);
-#if CONFIG_SPTM
- /* Set up OSKext instances to represent the SPTM/TXM. */
- OSKext *SPTMKext = allocAndInitFakeKext(&g_sptm_kmod_info);
- OSKext *TXMKext = allocAndInitFakeKext(&g_txm_kmod_info);
+ kernelStart = (u_char *)&_mh_execute_header;
+ kernelLength = getlastaddr() - (vm_offset_t)kernelStart;
+ assert(kernelLength <= UINT_MAX);
+ kernelExecutable = OSData::withBytesNoCopy(
+ kernelStart, (unsigned int)kernelLength);
+ assert(kernelExecutable);
+
+#if KASLR_KEXT_DEBUG
+ IOLog("kaslr: kernel start 0x%lx end 0x%lx length %lu vm_kernel_slide %lu (0x%016lx) \n",
+ (unsigned long)kernelStart,
+ (unsigned long)getlastaddr(),
+ kernelLength,
+ (unsigned long)vm_kernel_slide,
+ (unsigned long)vm_kernel_slide);
#endif
+
+ sKernelKext->loadTag = sNextLoadTag++; // the kernel is load tag 0
+ sKernelKext->bundleID = OSSymbol::withCString(kOSKextKernelIdentifier);
+
+ sKernelKext->version = OSKextParseVersionString(osrelease);
+ sKernelKext->compatibleVersion = sKernelKext->version;
+ sKernelKext->linkedExecutable = os::move(kernelExecutable);
+ sKernelKext->interfaceUUID = sKernelKext->copyUUID();
+
+ sKernelKext->flags.hasAllDependencies = 1;
+ sKernelKext->flags.kernelComponent = 1;
+ sKernelKext->flags.prelinked = 0;
+ sKernelKext->flags.loaded = 1;
+ sKernelKext->flags.started = 1;
+ sKernelKext->flags.CPPInitialized = 0;
+ sKernelKext->flags.jettisonLinkeditSeg = 0;
+
+ sKernelKext->kmod_info = &g_kernel_kmod_info;
+ strlcpy(g_kernel_kmod_info.version, osrelease,
+ sizeof(g_kernel_kmod_info.version));
+ g_kernel_kmod_info.size = kernelLength;
+ g_kernel_kmod_info.id = sKernelKext->loadTag;
+
+ /* Cons up an info dict, so we don't have to have special-case
+ * checking all over.
+ */
+ sKernelKext->infoDict = OSDictionary::withCapacity(5);
+ assert(sKernelKext->infoDict);
+ setResult = sKernelKext->infoDict->setObject(kCFBundleIdentifierKey,
+ sKernelKext->bundleID.get());
+ assert(setResult);
+ setResult = sKernelKext->infoDict->setObject(kOSKernelResourceKey,
+ kOSBooleanTrue);
+ assert(setResult);
+
+ {
+ OSSharedPtr<OSString> scratchString(OSString::withCStringNoCopy(osrelease));
+ assert(scratchString);
+ setResult = sKernelKext->infoDict->setObject(kCFBundleVersionKey,
+ scratchString.get());
+ assert(setResult);
+ }
+
+ {
+ OSSharedPtr<OSString> scratchString(OSString::withCStringNoCopy("mach_kernel"));
+ assert(scratchString);
+ setResult = sKernelKext->infoDict->setObject(kCFBundleNameKey,
+ scratchString.get());
+ assert(setResult);
+ }
/* Add the kernel kext to the bookkeeping dictionaries. Note that
* the kernel kext doesn't have a kmod_info struct. copyInfo()
@@ -1071,25 +903,9 @@
setResult = sLoadedKexts->setObject(sKernelKext);
assert(setResult);
-#if CONFIG_SPTM
- setResult = sKextsByID->setObject(SPTMKext->bundleID.get(), SPTMKext);
- assert(setResult);
- setResult = sLoadedKexts->setObject(SPTMKext);
- assert(setResult);
-
- setResult = sKextsByID->setObject(TXMKext->bundleID.get(), TXMKext);
- assert(setResult);
- setResult = sLoadedKexts->setObject(TXMKext);
- assert(setResult);
-#endif /* CONFIG_SPTM */
-
// XXX: better way with OSSharedPtr?
// sKernelKext remains a valid pointer even after the decref
sKernelKext->release();
-#if CONFIG_SPTM
- SPTMKext->release();
- TXMKext->release();
-#endif /* CONFIG_SPTM */
registryRoot = IORegistryEntry::getRegistryRoot();
kernelCPUType = OSNumber::withNumber(
@@ -1141,10 +957,6 @@
"Kext system initialized.");
notifyKextLoadObservers(sKernelKext, sKernelKext->kmod_info);
-#if CONFIG_SPTM
- notifyKextLoadObservers(SPTMKext, SPTMKext->kmod_info);
- notifyKextLoadObservers(TXMKext, TXMKext->kmod_info);
-#endif
return;
}
@@ -1222,7 +1034,7 @@
#if __arm__ || __arm64__
/* Free the memory that was set up by iBoot.
*/
-#if !defined(KERNEL_INTEGRITY_KTRR) && !defined(KERNEL_INTEGRITY_CTRR) && !defined(KERNEL_INTEGRITY_PV_CTRR)
+#if !defined(KERNEL_INTEGRITY_KTRR) && !defined(KERNEL_INTEGRITY_CTRR)
/* We cannot free the KLD segment with CTRR enabled as it contains text and
* is covered by the contiguous rorgn.
*/
@@ -1232,12 +1044,8 @@
(int)segment_size); // calls ml_static_mfree
} else if (seg_kld && seg_kld->vmaddr && seg_kld->vmsize) {
/* With fileset KCs, the Kernel KLD segment is not recorded in the DT. */
-#if !CONFIG_SPTM
ml_static_mfree(ml_static_ptovirt(seg_kld->vmaddr - gVirtBase + gPhysBase),
seg_kld->vmsize);
-#else
- ml_static_mfree(seg_kld->vmaddr, seg_kld->vmsize);
-#endif
}
#endif
dt_segment_name = "Kernel-__KLDDATA";
@@ -1246,12 +1054,8 @@
(int)segment_size); // calls ml_static_mfree
} else if (seg_klddata && seg_klddata->vmaddr && seg_klddata->vmsize) {
/* With fileset KCs, the Kernel KLDDATA segment is not recorded in the DT. */
-#if !CONFIG_SPTM
ml_static_mfree(ml_static_ptovirt(seg_klddata->vmaddr - gVirtBase + gPhysBase),
seg_klddata->vmsize);
-#else
- ml_static_mfree(seg_klddata->vmaddr, seg_klddata->vmsize);
-#endif
}
#elif __i386__ || __x86_64__
/* On x86, use the mapping data from the segment load command to
@@ -1311,7 +1115,7 @@
/* Allocate space for the LINKEDIT copy.
*/
mem_result = kmem_alloc(kernel_map, (vm_offset_t *) &seg_copy,
- seg_length, KMA_ZERO, VM_KERN_MEMORY_KEXT);
+ seg_length, VM_KERN_MEMORY_KEXT);
if (mem_result != KERN_SUCCESS) {
OSKextLog(/* kext */ NULL,
kOSKextLogErrorLevel |
@@ -1331,11 +1135,13 @@
/* Set up the VM region.
*/
- mem_result = mach_vm_map_kernel(
+ mem_result = vm_map_enter_mem_object(
kernel_map,
&seg_offset,
seg_length, /* mask */ 0,
- VM_MAP_KERNEL_FLAGS_FIXED(.vmf_overwrite = true),
+ VM_FLAGS_FIXED | VM_FLAGS_OVERWRITE,
+ VM_MAP_KERNEL_FLAGS_NONE,
+ VM_KERN_MEMORY_NONE,
(ipc_port_t)NULL,
(vm_object_offset_t) 0,
/* copy */ FALSE,
@@ -1593,49 +1399,6 @@
/*********************************************************************
*********************************************************************/
/* static */
-
-bool
-OSKext::driverkitEnabled(void)
-{
- #if XNU_TARGET_OS_WATCH
- /*
- * Driverkit support is available on watchOS only if the device
- * tree has the "supports-driverkit" property in its "/product" node
- */
- DTEntry entry;
- void const *prop = NULL;
- unsigned int prop_size;
-
- if (kSuccess != SecureDTLookupEntry(NULL, "/product", &entry)) {
- return false;
- }
- if (kSuccess != SecureDTGetProperty(entry, "supports-driverkit", &prop, &prop_size)) {
- return false;
- }
- #endif /* XNU_TARGET_OS_WATCH */
-
- return true;
-}
-
-/*********************************************************************
-*********************************************************************/
-/* static */
-bool
-OSKext::iokitDaemonAvailable(void)
-{
-#if XNU_TARGET_OS_XR || XNU_TARGET_OS_BRIDGE
- int notused;
- if (PE_parse_boot_argn("-restore", ¬used, sizeof(notused))) {
- return false;
- }
-#endif /* XNU_TARGET_OS_XR || XNU_TARGET_OS_BRIDGE */
-
- return driverkitEnabled();
-}
-
-/*********************************************************************
-*********************************************************************/
-/* static */
void
OSKext::setDeferredLoadSucceeded(Boolean succeeded)
{
@@ -1696,10 +1459,10 @@
}
void
-OSKext::setWillUserspaceReboot(void)
+OSKext::willUserspaceReboot(void)
{
OSKext::willShutdown();
- IOService::setWillUserspaceReboot();
+ IOService::userSpaceWillReboot();
gIOCatalogue->terminateDriversForUserspaceReboot();
}
@@ -1719,12 +1482,6 @@
OSKext::setKernelRequestsEnabled(true);
sOSKextWasResetAfterUserspaceReboot = true;
IORecursiveLockUnlock(sKextLock);
-}
-
-extern "C" int
-OSKextIsInUserspaceReboot(void)
-{
- return IOService::getWillUserspaceReboot();
}
extern "C" void
@@ -1987,68 +1744,6 @@
return newKext;
}
-OSData *
-OSKext::parseDextUniqueID(
- OSDictionary * anInfoDict,
- const char *dextIDCS)
-{
- OSData *ret = NULL;
- OSData *data_duid = OSDynamicCast(OSData, anInfoDict->getObject(kOSBundleDextUniqueIdentifierKey));
- if (data_duid != NULL) {
- if (data_duid->getLength() > KOSBundleDextUniqueIdentifierMaxLength) {
- OSKextLog(NULL,
- kOSKextLogErrorLevel | kOSKextLogLoadFlag,
- "Dext %s DextUniqueIdentifier too long.",
- dextIDCS);
- } else {
- /*
- * If the DextUniqueID exists it should be
- * present also into the personalities.
- */
- setDextUniqueIDInPersonalities(anInfoDict, data_duid);
- ret = data_duid;
- }
- } else {
- OSKextLog(NULL,
- kOSKextLogDebugLevel | kOSKextLogLoadFlag,
- "Dext %s does not have a DextUniqueIdentifier",
- dextIDCS);
- }
- return ret;
-}
-
-void
-OSKext::setDextUniqueIDInPersonalities(
- OSDictionary * anInfoDict,
- OSData * dextUniqueID)
-{
- OSDictionary * dextPersonalities = NULL;
- OSSharedPtr<OSCollectionIterator> personalitiesIterator;
- OSString * personalityName = NULL;
-
- dextPersonalities = OSDynamicCast(OSDictionary,
- anInfoDict->getObject(kIOKitPersonalitiesKey));
- if (!dextPersonalities || !dextPersonalities->getCount()) {
- return;
- }
-
- personalitiesIterator =
- OSCollectionIterator::withCollection(dextPersonalities);
- if (!personalitiesIterator) {
- return;
- }
- while ((personalityName = OSDynamicCast(OSString,
- personalitiesIterator->getNextObject()))) {
- OSDictionary * personality = OSDynamicCast(OSDictionary,
- dextPersonalities->getObject(personalityName));
- if (personality) {
- OSObject *duid = personality->getObject(kOSBundleDextUniqueIdentifierKey);
- if (duid == NULL) {
- personality->setObject(kOSBundleDextUniqueIdentifierKey, dextUniqueID);
- }
- }
- }
-}
/*********************************************************************
*********************************************************************/
bool
@@ -2068,7 +1763,6 @@
uint32_t length = 0; // reused
uintptr_t kext_slide = PE_get_kc_slide(type);
bool shouldSaveSegments = false;
- kc_format format = KCFormatUnknown;
if (!super::init()) {
goto finish;
@@ -2184,21 +1878,11 @@
goto finish;
}
- /*
- * Fileset KCs are mapped as a whole by iBoot.
- * Individual kext executables should not be unmapped
- * by xnu.
- * Doing so may result in panics like rdar://85419651
- */
- if (PE_get_kc_format(kc_type, &format) && (format == KCFormatFileset)) {
- prelinkedExecutable->setDeallocFunction(NULL);
- } else { // Not from a Fileset KC
#if VM_MAPPED_KEXTS
- prelinkedExecutable->setDeallocFunction(osdata_kext_free);
+ prelinkedExecutable->setDeallocFunction(osdata_kext_free);
#else
- prelinkedExecutable->setDeallocFunction(osdata_phys_free);
+ prelinkedExecutable->setDeallocFunction(osdata_phys_free);
#endif
- }
setLinkedExecutable(prelinkedExecutable.get());
addressNum = OSDynamicCast(OSNumber,
anInfoDict->getObject(kPrelinkKmodInfoKey));
@@ -2315,7 +1999,7 @@
kOSKextLogErrorLevel |
kOSKextLogGeneralFlag,
"Kext %s failed to save mutable segment %llx->%llx.", getIdentifierCString(), unslid_vmaddr, unslid_vmaddr + vmsize - 1);
- result = false;
+ result = kOSKextReturnInternalError;
goto finish;
}
savedMutableSegments->setObject(savedSegment);
@@ -2335,18 +2019,13 @@
flags.prelinked = true;
- if (isDriverKit()) {
- dextStatistics = OSDextStatistics::create();
- dextUniqueID.reset(parseDextUniqueID(anInfoDict, getIdentifierCString()), OSRetain);
- dextLaunchedCount = 0;
- }
-
/* If we created a kext from prelink info,
* we must be booting from a prelinked kernel.
*/
sPrelinkBoot = true;
- result = (registerIdentifier() == kOSKextInitialized);
+ result = registerIdentifier();
+
finish:
return result;
}
@@ -2355,32 +2034,25 @@
*********************************************************************/
/* static */
OSSharedPtr<OSKext>
-OSKext::withCodelessInfo(OSDictionary * anInfoDict, OSKextInitResult *result)
+OSKext::withCodelessInfo(OSDictionary * anInfoDict)
{
OSSharedPtr<OSKext> newKext = OSMakeShared<OSKext>();
- if (!newKext) {
+
+ if (newKext && !newKext->initWithCodelessInfo(anInfoDict)) {
return NULL;
}
- OSKextInitResult ret = newKext->initWithCodelessInfo(anInfoDict);
- if (result != NULL) {
- *result = ret;
- }
- if (ret != kOSKextInitialized) {
- return NULL;
- }
-
return newKext;
}
/*********************************************************************
*********************************************************************/
-OSKextInitResult
+bool
OSKext::initWithCodelessInfo(OSDictionary * anInfoDict)
{
- OSKextInitResult result = kOSKextInitFailure;
- OSString * kextPath = NULL; // do not release
- OSBoolean * scratchBool = NULL; // do not release
+ bool result = false;
+ OSString * kextPath = NULL; // do not release
+ OSBoolean * scratchBool = NULL; // do not release
if (anInfoDict == NULL || !super::init()) {
goto finish;
@@ -2443,12 +2115,6 @@
/* remove unnecessary paths from the info dict */
anInfoDict->removeObject(kKextRequestArgumentCodelessInfoBundlePathKey);
-
- if (isDriverKit()) {
- dextStatistics = OSDextStatistics::create();
- dextUniqueID.reset(parseDextUniqueID(anInfoDict, getIdentifierCString()), OSRetain);
- dextLaunchedCount = 0;
- }
result = registerIdentifier();
@@ -2667,13 +2333,7 @@
}
}
- if (isDriverKit()) {
- dextStatistics = OSDextStatistics::create();
- dextUniqueID.reset(parseDextUniqueID(theInfoDict, getIdentifierCString()), OSRetain);
- dextLaunchedCount = 0;
- }
-
- result = (registerIdentifier() == kOSKextInitialized);
+ result = registerIdentifier();
finish:
return result;
@@ -2681,25 +2341,21 @@
/*********************************************************************
*********************************************************************/
-OSKextInitResult
+bool
OSKext::registerIdentifier(void)
{
- OSKextInitResult result = kOSKextInitFailure;
- OSKext * existingKext = NULL; // do not release
- bool existingIsLoaded = false;
- bool existingIsPrelinked = false;
- bool existingIsCodeless = false;
- bool existingIsDext = false;
- OSKextVersion newVersion = -1;
- OSKextVersion existingVersion = -1;
+ bool result = false;
+ OSKext * existingKext = NULL; // do not release
+ bool existingIsLoaded = false;
+ bool existingIsPrelinked = false;
+ bool existingIsCodeless = false;
+ bool existingIsDext = false;
+ OSKextVersion newVersion = -1;
+ OSKextVersion existingVersion = -1;
char newVersionCString[kOSKextVersionMaxLength];
char existingVersionCString[kOSKextVersionMaxLength];
OSSharedPtr<OSData> newUUID;
OSSharedPtr<OSData> existingUUID;
- const char *newDextUniqueIDCString = NULL;
- const char *existingDextUniqueIDCString = NULL;
- unsigned int newDextUniqueIDCStringSize = 0;
- unsigned int existingDextUniqueIDCStringSize = 0;
IORecursiveLockLock(sKextLock);
@@ -2715,7 +2371,7 @@
existingKext = OSDynamicCast(OSKext, sKextsByID->getObject(bundleID.get()));
if (!existingKext) {
sKextsByID->setObject(bundleID.get(), this);
- result = kOSKextInitialized;
+ result = true;
goto finish;
}
@@ -2729,76 +2385,6 @@
existingIsPrelinked = existingKext->isPrelinked();
existingIsDext = existingKext->isDriverKit();
existingIsCodeless = !existingKext->declaresExecutable() && !existingIsDext;
-
- /*
- * Check if we are trying to upgrade a dext
- * with another dext.
- */
- if (isDriverKit() && existingIsDext) {
- OSData *newDextUID = getDextUniqueID();
- if (!newDextUID) {
- OSKextLog(this,
- kOSKextLogDebugLevel | kOSKextLogLoadFlag,
- "New dext %s, v%s requested does not have a unique dext identifier\n",
- getIdentifierCString(), newVersionCString);
- goto finish;
- }
- newDextUniqueIDCString = getDextUniqueIDCString(newDextUID, &newDextUniqueIDCStringSize);
- assert(newDextUniqueIDCString != NULL);
-
- OSData *existingDextUID = existingKext->getDextUniqueID();
- if (!existingDextUID) {
- OSKextLog(this,
- kOSKextLogDebugLevel | kOSKextLogLoadFlag,
- "Found a dext %s, v%s: with no unique dext identifier\n",
- existingKext->getIdentifierCString(), existingVersionCString);
- goto finish;
- }
- existingDextUniqueIDCString = getDextUniqueIDCString(existingDextUID, &existingDextUniqueIDCStringSize);
- assert(existingDextUniqueIDCString != NULL);
-
- /*
- * We might get multiple requests to save the same dext.
- * Check if we already have saved it or if this is an upgrade
- * for a dext with the same BundleID.
- * Dexts are uniquely identified by DextUniqueID, if a new DextUniqueID
- * is requested for a BundleID we are going to upgrade to the newest
- * received irrespective from the dext version.
- */
- if (newDextUID->isEqualTo(existingDextUID) && existingKext->flags.dextToReplace == 0) {
- OSKextLog(this,
- kOSKextLogDebugLevel | kOSKextLogLoadFlag,
- "Refusing new dext %s, v%s:"
- "a dext v %s with the same unique dext identifier (%s) already exists\n",
- getIdentifierCString(), newVersionCString,
- existingVersionCString, newDextUniqueIDCString);
- result = kOSKextAlreadyExist;
- goto finish;
- }
-
- bool upgraded = upgradeDext(existingKext, this);
- if (upgraded) {
- /* If the dext was upgraded existingKext might have been deallocated */
- existingKext = NULL;
- OSKextLog(this,
- kOSKextLogDebugLevel | kOSKextLogLoadFlag,
- "Dext %s, v%s , unique dext identifier %s "
- "Upgraded to v%s, unique dext identifier %s \n",
- getIdentifierCString(), existingVersionCString, existingDextUniqueIDCString,
- newVersionCString, newDextUniqueIDCString);
- result = kOSKextInitialized;
- } else {
- OSKextLog(this,
- kOSKextLogDebugLevel | kOSKextLogLoadFlag,
- "Upgrade delayed for %s v%s, unique dext identifier %s "
- "with v%s, unique dext identifier %s.\n",
- getIdentifierCString(), existingVersionCString, existingDextUniqueIDCString,
- newVersionCString, newDextUniqueIDCString);
- result = kOSKextAlreadyExist;
- }
-
- goto finish;
- }
/* If we have a non-codeless kext with this identifier that's already
* loaded/prelinked, we can't use the new one, but let's be really
@@ -2921,7 +2507,6 @@
* See: OSKext::loadFileSetKexts()
*/
-
/* We have two nonloaded/nonprelinked kexts, so our decision depends on whether
* user loads are happening or if we're still in early boot. User agents are
* supposed to resolve dependencies topside and include only the exact
@@ -2930,7 +2515,7 @@
*/
if (sUserLoadsActive) {
sKextsByID->setObject(bundleID.get(), this);
- result = kOSKextInitialized;
+ result = true;
OSKextLog(this,
kOSKextLogStepLevel |
@@ -2949,7 +2534,7 @@
*/
if (newVersion > existingVersion) {
sKextsByID->setObject(bundleID.get(), this);
- result = kOSKextInitialized;
+ result = true;
OSKextLog(this,
kOSKextLogStepLevel |
@@ -2975,14 +2560,7 @@
IORecursiveLockUnlock(sKextLock);
- if (newDextUniqueIDCString != NULL) {
- kfree_data(newDextUniqueIDCString, newDextUniqueIDCStringSize);
- }
- if (existingDextUniqueIDCString != NULL) {
- kfree_data(existingDextUniqueIDCString, existingDextUniqueIDCStringSize);
- }
-
- if (result == kOSKextInitialized) {
+ if (result) {
OSKextLog(this,
kOSKextLogStepLevel |
kOSKextLogKextBookkeepingFlag,
@@ -3343,12 +2921,6 @@
panic("Attempt to free loaded kext %s.", getIdentifierCString());
}
- if (isDriverKit()) {
- if (dextLaunchedCount > 0) {
- panic("Freeing dext %s but dextLaunchedCount is %d\n", getIdentifierCString(), dextLaunchedCount);
- }
- }
-
infoDict.reset();
bundleID.reset();
path.reset();
@@ -3359,8 +2931,6 @@
metaClasses.reset();
interfaceUUID.reset();
driverKitUUID.reset();
- dextStatistics.reset();
- dextUniqueID.reset();
if (isInterface() && kmod_info) {
kfree_type(kmod_info_t, kmod_info);
@@ -3722,7 +3292,8 @@
}
}
- result = (registerIdentifier() == kOSKextInitialized);
+ result = registerIdentifier();
+
finish:
return result;
}
@@ -3747,7 +3318,7 @@
entryRef.mkext = (mkext_basic_header *)mkextBuffer;
entryRef.fileinfo = mkextBuffer + entryOffset;
- if (!result->appendValue(entryRef)) {
+ if (!result->appendBytes(&entryRef, sizeof(entryRef))) {
result.reset();
goto finish;
}
@@ -3798,8 +3369,8 @@
}
uint32_t allocSize = (uint32_t)allocSize64;
- zmem = (z_mem *)kalloc_data_tag(allocSize, Z_WAITOK,
- VM_KERN_MEMORY_OSKEXT);
+ zmem = (z_mem *)kheap_alloc_tag(KHEAP_DATA_BUFFERS, allocSize,
+ Z_WAITOK, VM_KERN_MEMORY_OSKEXT);
if (!zmem) {
goto finish;
}
@@ -3814,7 +3385,8 @@
{
uint32_t * skipper = (uint32_t *)ptr - 1;
z_mem * zmem = (z_mem *)skipper;
- kfree_data(zmem, zmem->alloc_size);
+ kheap_free(KHEAP_DATA_BUFFERS, zmem, zmem->alloc_size);
+ return;
}
};
@@ -3845,8 +3417,7 @@
}
if (KERN_SUCCESS != kmem_alloc(kernel_map,
- (vm_offset_t*)&uncompressedDataBuffer, fullSize,
- KMA_DATA_SHARED, VM_KERN_MEMORY_OSKEXT)) {
+ (vm_offset_t*)&uncompressedDataBuffer, fullSize, VM_KERN_MEMORY_OSKEXT)) {
/* How's this for cheesy? The kernel is only asked to extract
* kext plists so we tailor the log messages.
*/
@@ -4230,35 +3801,34 @@
"Failed to create serializer on log info for request from user space.");
/* Incidental error; we're going to (try to) allow the request
* itself to succeed. */
+ }
+
+ if (!logInfoArray->serialize(serializer.get())) {
+ OSKextLog(/* kext */ NULL,
+ kOSKextLogErrorLevel |
+ kOSKextLogIPCFlag,
+ "Failed to serialize log info for request from user space.");
+ /* Incidental error; we're going to (try to) allow the request
+ * itself to succeed. */
} else {
- if (!logInfoArray->serialize(serializer.get())) {
+ logInfo = serializer->text();
+ logInfoLength = serializer->getLength();
+
+ kmem_result = kmem_alloc(kernel_map, (vm_offset_t *)&buffer, round_page(logInfoLength), VM_KERN_MEMORY_OSKEXT);
+ if (kmem_result != KERN_SUCCESS) {
OSKextLog(/* kext */ NULL,
kOSKextLogErrorLevel |
kOSKextLogIPCFlag,
- "Failed to serialize log info for request from user space.");
+ "Failed to copy log info for request from user space.");
/* Incidental error; we're going to (try to) allow the request
- * itself to succeed. */
+ * to succeed. */
} else {
- logInfo = serializer->text();
- logInfoLength = serializer->getLength();
-
- kmem_result = kmem_alloc(kernel_map, (vm_offset_t *)&buffer, round_page(logInfoLength),
- KMA_DATA_SHARED, VM_KERN_MEMORY_OSKEXT);
- if (kmem_result != KERN_SUCCESS) {
- OSKextLog(/* kext */ NULL,
- kOSKextLogErrorLevel |
- kOSKextLogIPCFlag,
- "Failed to copy log info for request from user space.");
- /* Incidental error; we're going to (try to) allow the request
- * to succeed. */
- } else {
- /* 11981737 - clear uninitialized data in last page */
- bzero((void *)(buffer + logInfoLength),
- (round_page(logInfoLength) - logInfoLength));
- memcpy(buffer, logInfo, logInfoLength);
- *logInfoOut = buffer;
- *logInfoLengthOut = logInfoLength;
- }
+ /* 11981737 - clear uninitialized data in last page */
+ bzero((void *)(buffer + logInfoLength),
+ (round_page(logInfoLength) - logInfoLength));
+ memcpy(buffer, logInfo, logInfoLength);
+ *logInfoOut = buffer;
+ *logInfoLengthOut = logInfoLength;
}
}
@@ -4290,26 +3860,6 @@
OSKext::lookupKextWithIdentifier(OSString * kextIdentifier)
{
return OSKext::lookupKextWithIdentifier(kextIdentifier->getCStringNoCopy());
-}
-
-/*********************************************************************
-*********************************************************************/
-OSSharedPtr<OSKext>
-OSKext::lookupDextWithIdentifier(OSString * dextIdentifier, OSData *dextUniqueIdentifier)
-{
- OSSharedPtr<OSKext> foundDext;
- foundDext.reset();
-
- IORecursiveLockLock(sKextLock);
- OSKext *dext = OSDynamicCast(OSKext, sKextsByID->getObject(dextIdentifier->getCStringNoCopy()));
- if (dext != NULL && dext->isDriverKit()) {
- if (dext->dextUniqueID == NULL || dext->dextUniqueID->isEqualTo(dextUniqueIdentifier)) {
- foundDext.reset(dext, OSRetain);
- }
- }
- IORecursiveLockUnlock(sKextLock);
-
- return foundDext;
}
/*********************************************************************
@@ -4377,15 +3927,6 @@
}
#if defined(__arm64__)
textExecBase = (uintptr_t) getsegdatafromheader((kernel_mach_header_t *)kmod_info->address, "__TEXT_EXEC", &textExecSize);
-
- /**
- * If the addresses within the Mach-O are unslid, then manually
- * slide any addresses coming from the Mach-O before usage.
- */
- if (thisKext->flags.unslidMachO) {
- textExecBase = (uintptr_t) ml_static_slide((vm_offset_t) textExecBase);
- }
-
if ((textExecBase <= address) && (address < textExecBase + textExecSize)) {
foundKext.reset(thisKext, OSRetain);
goto finish;
@@ -4393,8 +3934,7 @@
#endif /* defined (__arm64__) */
}
}
-
- if (kernel_text_contains(address)) {
+ if ((address >= vm_kernel_stext) && (address < vm_kernel_etext)) {
foundKext.reset(sKernelKext, OSRetain);
goto finish;
}
@@ -4558,16 +4098,15 @@
bool terminateServicesAndRemovePersonalitiesFlag)
{
#if CONFIG_EMBEDDED
- if (!aKext->isDriverKit()) {
- OSKextLog(aKext,
- kOSKextLogErrorLevel |
- kOSKextLogKextBookkeepingFlag,
- "removeKext() called for %s, only supported on embedded for DriverKit dexts",
- aKext->getIdentifier() ? aKext->getIdentifierCString() : "unknown kext");
-
- return kOSReturnSuccess;
- }
-#endif /* CONFIG_EMBEDDED */
+ OSKextLog(aKext,
+ kOSKextLogErrorLevel |
+ kOSKextLogKextBookkeepingFlag,
+ "removeKext() called for %s, not supported on embedded",
+ aKext->getIdentifier() ? aKext->getIdentifierCString() : "unknown kext");
+
+ return kOSReturnSuccess;
+#else /* CONFIG_EMBEDDED */
+
OSReturn result = kOSKextReturnInUse;
OSKext * checkKext = NULL; // do not release
#if CONFIG_MACF
@@ -4592,7 +4131,7 @@
goto finish;
}
- if (aKext->isLoaded() || aKext->isDriverKit()) {
+ if (aKext->isLoaded()) {
#if CONFIG_MACF
if (current_task() != kernel_task) {
cred = kauth_cred_get_with_ref();
@@ -4612,7 +4151,7 @@
#endif
/* make sure there are no resource requests in flight - 17187548 */
- if (aKext->declaresExecutable() && aKext->countRequestCallbacks()) {
+ if (aKext->countRequestCallbacks()) {
goto finish;
}
if (aKext->flags.unloadUnsupported) {
@@ -4645,11 +4184,6 @@
result = aKext->unload();
if (result != kOSReturnSuccess) {
- OSKextLog(aKext,
- kOSKextLogErrorLevel |
- kOSKextLogKextBookkeepingFlag,
- "Can't remove kext %s; kext failed to unload - 0x%x.",
- aKext->getIdentifierCString(), result);
goto finish;
}
}
@@ -4684,6 +4218,7 @@
finish:
IORecursiveLockUnlock(sKextLock);
return result;
+#endif /* CONFIG_EMBEDDED */
}
/*********************************************************************
@@ -4959,15 +4494,6 @@
#if PRAGMA_MARK
#pragma mark Accessors
#endif
-
-/*********************************************************************
-*********************************************************************/
-const OSObject *
-OSKext::getBundleExecutable(void)
-{
- return infoDict->getObject(kCFBundleExecutableKey);
-}
-
/*********************************************************************
*********************************************************************/
const OSSymbol *
@@ -5129,20 +4655,6 @@
}
/*********************************************************************
-*********************************************************************/
-bool
-OSKext::isSpecialKernelBinary(void)
-{
-#if CONFIG_SPTM
- return (this->kmod_info) &&
- ((this->kmod_info->id == kOSKextSPTMLoadTag) ||
- (this->kmod_info->id == kOSKextTXMLoadTag));
-#else
- return false;
-#endif
-}
-
-/*********************************************************************
* We might want to check this recursively for all dependencies,
* since a subtree of dependencies could get loaded before we hit
* a dependency that isn't safe-boot-loadable.
@@ -5336,7 +4848,7 @@
for (i = 0; i < header->ncmds; i++) {
if (load_cmd->cmd == LC_UUID) {
uuid_cmd = (struct uuid_command *)load_cmd;
- result = OSData::withValue(uuid_cmd->uuid);
+ result = OSData::withBytes(uuid_cmd->uuid, sizeof(uuid_cmd->uuid));
goto finish;
}
load_cmd = (struct load_command *)((caddr_t)load_cmd + load_cmd->cmdsize);
@@ -5352,424 +4864,6 @@
if (!OSCompareAndSwapPtr(nullptr, uuid, &driverKitUUID)) {
OSSafeReleaseNULL(uuid);
}
-}
-
-OSData *
-OSKext::getDextUniqueID(void)
-{
- if (isDriverKit() && dextUniqueID != NULL) {
- return dextUniqueID.get();
- }
-
- return NULL;
-}
-
-/*
- * In case a DextUniqueID exists this function returns
- * an allocated char* with the hexadecimal represantition of
- * DextUniqueID.
- * The returned pinter needs to be freed with kfree_data, the
- * size of the allocated buffer is returned in size.
- */
-static const char *
-getDextUniqueIDCString(OSData *dextUniqueID, unsigned int *size)
-{
- if (dextUniqueID != NULL) {
- char *s_buffer = NULL;
- unsigned int d_length = dextUniqueID->getLength();
- /*
- * We are converting in hex, so for every byte we will have
- * 2 hex chars and one last \0.
- */
- unsigned int s_length = d_length * 2 + 1;
- s_buffer = (char *) kalloc_data(s_length, Z_WAITOK_ZERO);
-
- char *uid = (char*) dextUniqueID->getBytesNoCopy();
- int cpos = 0;
- for (unsigned int i = 0; i < d_length && cpos < (s_length - 1); i++) {
- int ret = snprintf(s_buffer + cpos, s_length - cpos - 1, "%02X", uid[i]);
- if (ret <= 0) {
- break;
- }
- cpos += ret;
- }
- *size = s_length;
-
- return s_buffer;
- }
-
- return NULL;
-}
-
-/*
- * Atomically swaps the olddext with newdext.
- * olddext will be unloaded, so it might be freed
- * after this call unless it was previously retained.
- *
- * If newdext is NULL, this unloads olddext and does not perform an upgrade
- */
-void
-OSKext::replaceDextInternal(OSKext *olddext, OSKext *newdext)
-{
- OSReturn result;
- const OSSymbol * dextID = olddext->getIdentifier();
- OSData * oldDextUniqueIdentifier = olddext->getDextUniqueID();
- OSSharedPtr<OSArray> new_personalities;
- OSSharedPtr<OSString> kextIdentifier;
- __assert_only bool lock_held = IORecursiveLockHaveLock(sKextLock);
- assert(lock_held);
-
- // The old dext will be unloaded and release dextID, so we need to retain dextID here
- dextID->retain();
-
- if (newdext != NULL) {
- __assert_only bool eq = dextID->isEqualTo(newdext->getIdentifier());
- assert(eq);
- }
-
- if (newdext != NULL) {
- /*
- * Swap the catalog personalities.
- */
- new_personalities = newdext->copyPersonalitiesArray();
- olddext->updatePersonalitiesInCatalog(new_personalities.get());
- }
-
- if (NULL != oldDextUniqueIdentifier) {
- oldDextUniqueIdentifier->retain();
- }
-
- /*
- * Unload the dext.
- */
- result = olddext->unload();
- if (result != kOSReturnSuccess) {
- OSKextLog(NULL,
- kOSKextLogErrorLevel | kOSKextLogLoadFlag,
- "Cannot unload dext for upgrade %s: %d\n",
- dextID->getCStringNoCopy(), result);
- }
-
- if (newdext != NULL) {
- /*
- * Swap the dexts on the OSKext dictionary.
- * This might free the dext.
- */
- sKextsByID->setObject(dextID, newdext);
- } else {
- /*
- * Remove the old dext
- */
- removeKext(olddext, true);
- }
-
- /*
- * Inform userspace.
- */
- if (newdext != NULL) {
- result = notifyDextUpgrade(OSDynamicCast(OSString, dextID), newdext->getDextUniqueID());
- if (result != kOSReturnSuccess) {
- OSKextLog(NULL,
- kOSKextLogErrorLevel | kOSKextLogLoadFlag,
- "Cannot send upgrade notification for %s\n",
- dextID->getCStringNoCopy());
- }
- } else {
- // notify dext removal
- queueKextNotification(kKextRequestPredicateUnloadNotification,
- OSDynamicCast(OSString, dextID), oldDextUniqueIdentifier);
- }
-
- OSSafeReleaseNULL(dextID);
- OSSafeReleaseNULL(oldDextUniqueIdentifier);
-}
-
-/*
- * To be called with sKextLock held.
- * NOTE: this could unload the olddext.
- */
-bool
-OSKext::upgradeDext(OSKext *olddext, OSKext *newdext)
-{
- const char * dextIDCS = newdext->getIdentifierCString();
- __assert_only bool old_isDext = olddext->isDriverKit();
- __assert_only bool new_isDext = newdext->isDriverKit();
- __assert_only bool lock_held = IORecursiveLockHaveLock(sKextLock);
-
- assert(old_isDext && new_isDext);
- assert(lock_held);
-
- /*
- * New dext and old dext have the same ID.
- * We use this ID as key on the OSKext
- * dictionarys/arrays.
- */
- const OSSymbol * dextID = newdext->getIdentifier();
- __assert_only bool eq = dextID->isEqualTo(olddext->getIdentifier());
- assert(eq);
-
- /*
- * Set this OSKect as to update.
- * Note that this flags will never be removed once set.
- * When a OSKext is marked, it will be substitued by a new
- * OSKext, and every subsystem having a reference on this
- * OSKext need to know they have check if they can use
- * this OSKext or look for a new one.
- */
- olddext->flags.dextToReplace = 1;
-
- /*
- * Check if the current OSKext has any
- * userspace processes launched.
- * In this case we cannot upgrade and we have to
- * delay the upgrade until all processes
- * are done.
- */
- if (olddext->dextLaunchedCount == 0) {
- /*
- * Be sure that if there are no launched dexts, no
- * pending upgrades exist.
- * This is an error if it happens, as the decrement
- * should have removed the dext from sDriverKitToUpgradeByID
- * in case it reached 0.
- */
- OSObject *pending_upgdare = sDriverKitToUpgradeByID->getObject(dextID);
- if (pending_upgdare != NULL) {
- OSKextLog(NULL,
- kOSKextLogErrorLevel | kOSKextLogLoadFlag,
- "Pending upgrade found for %s but dextLaunchedCount is 0!\n",
- dextIDCS);
- goto out;
- }
-
- replaceDextInternal(olddext, newdext);
- return true;
- }
-
-out:
-
- /*
- * Delay the upgrade.
- * Make the new dext available in sDriverKitToUpgradeByID.
- * In case there was already a pending upgrade, this will
- * overwrite it.
- */
- sDriverKitToUpgradeByID->setObject(dextID, newdext);
- return false;
-}
-
-/*
- * To be called with sKextLock held.
- * NOTE: this could unload the dext.
- */
-bool
-OSKext::removeDext(OSKext *dext)
-{
- __assert_only bool dext_isDext = dext->isDriverKit();
- __assert_only bool lock_held = IORecursiveLockHaveLock(sKextLock);
- IOReturn result;
-
- assert(dext_isDext);
- assert(lock_held);
-
- /*
- * Set this OSKext to be unloaded when all running instances exit.
- */
- dext->flags.dextToReplace = 1;
-
- result = gIOCatalogue->terminateDriversForModule(
- dext->getIdentifierCString(), /* unload */ false, /* asynchronous */ true);
- if (result != kOSReturnSuccess) {
- OSKextLog(dext,
- kOSKextLogErrorLevel |
- kOSKextLogKextBookkeepingFlag,
- "%s services failed to terminate - 0x%x.",
- dext->getIdentifierCString(), result);
- }
-
- dext->removePersonalitiesFromCatalog();
- sDriverKitToUpgradeByID->removeObject(dext->getIdentifier());
-
- /*
- * Check if the current OSKext has any
- * userspace processes launched.
- * In this case we cannot unload and we have to
- * delay the unload until all processes
- * are done.
- */
- if (dext->dextLaunchedCount == 0) {
- replaceDextInternal(dext, NULL);
- return true;
- }
-
- return false;
-}
-
-bool
-OSKext::incrementDextLaunchCount(OSKext *dext, OSData *dextUniqueIDToMatch)
-{
- bool ret = false;
- __assert_only bool isDext = dext->isDriverKit();
- assert(isDext);
-
- const char * dextIDCS = dext->getIdentifierCString();
- OSData *myDextUniqueID = dext->getDextUniqueID();
-
- if (!myDextUniqueID || !dextUniqueIDToMatch) {
- OSKextLog(dext,
- kOSKextLogErrorLevel | kOSKextLogLoadFlag,
- "Cannot find dext UniqueID for %s, cannot increment dext launches\n",
- dextIDCS);
- return ret;
- }
-
- unsigned int dextUniqueIDCStringSize = 0, dextUniqueIDToMatchCStringSize = 0;
- const char *dextUniqueIDCString = getDextUniqueIDCString(myDextUniqueID, &dextUniqueIDCStringSize);
- const char *dextUniqueIDToMatchCString = getDextUniqueIDCString(dextUniqueIDToMatch, &dextUniqueIDToMatchCStringSize);
- assert(dextUniqueIDCString != NULL);
- assert(dextUniqueIDToMatchCString != NULL);
-
- IORecursiveLockLock(sKextLock);
-
- /*
- * Check that the dext we are referencing is the same
- * looked for the match.
- */
- if (myDextUniqueID->isEqualTo(dextUniqueIDToMatch)) {
- if (dext->flags.dextToReplace == 0 || dext->dextLaunchedCount > 0) {
- if (dext->dextLaunchedCount == kOSKextMaxDextLaunchedCount) {
- OSKextLog(dext,
- kOSKextLogErrorLevel | kOSKextLogLoadFlag,
- "Too many dexts launched for %s UniqueID %s\n",
- dextIDCS, dextUniqueIDCString);
- } else {
- dext->dextLaunchedCount++;
- ret = true;
-
- OSKextLog(dext,
- kOSKextLogProgressLevel | kOSKextLogLoadFlag,
- "New dext launched for %s UniqueID %s",
- dextIDCS, dextUniqueIDCString);
- }
- } else {
- OSKextLog(dext,
- kOSKextLogProgressLevel | kOSKextLogLoadFlag,
- "Dext %s UniqueID %s requires update, cannot launch a new dext\n",
- dextIDCS, dextUniqueIDCString);
- }
- } else {
- OSKextLog(dext,
- kOSKextLogProgressLevel | kOSKextLogLoadFlag,
- "Dext %s: UniqueID %s does not match UniqueID looked for %s, cannot launch a new dext\n",
- dextIDCS, dextUniqueIDCString, dextUniqueIDToMatchCString);
- }
-
- IORecursiveLockUnlock(sKextLock);
-
- if (dextUniqueIDCString != NULL) {
- kfree_data(dextUniqueIDCString, dextUniqueIDCStringSize);
- }
- if (dextUniqueIDToMatchCString != NULL) {
- kfree_data(dextUniqueIDToMatchCString, dextUniqueIDToMatchCStringSize);
- }
- return ret;
-}
-
-bool
-OSKext::decrementDextLaunchCount(OSString *bundleID)
-{
- bool ret = false;
- const char * dextIDCS;
- OSData *myDextUniqueID;
- unsigned int dextUniqueIDCStringSize = 0;
- const char * dextUniqueIDCString = NULL;
- OSKext* dext = NULL;
-
- if (!bundleID) {
- return ret;
- }
- dextIDCS = bundleID->getCStringNoCopy();
-
- IORecursiveLockLock(sKextLock);
-
- /*
- * Look for the dext with the bundle it. This
- * call is triggered only if a previous increment was
- * performed. It means that the dext could have not
- * been upgraded as its dextLaunchedCount was at least 1.
- * Because of this it still needs to be available
- * in sKextsByID.
- */
- dext = OSDynamicCast(OSKext, sKextsByID->getObject(dextIDCS));
- if (!dext || !dext->isDriverKit()) {
- OSKextLog(NULL,
- kOSKextLogErrorLevel | kOSKextLogLoadFlag,
- "Cannot find dext for %s, cannot decrement dext launches\n",
- dextIDCS);
-
- goto out_locked;
- }
-
- myDextUniqueID = dext->getDextUniqueID();
- if (!myDextUniqueID) {
- OSKextLog(dext,
- kOSKextLogErrorLevel | kOSKextLogLoadFlag,
- "Cannot find dext UniqueID for %s, cannot decrement dext launches\n",
- dextIDCS);
-
- goto out_locked;
- }
- dextUniqueIDCString = getDextUniqueIDCString(myDextUniqueID, &dextUniqueIDCStringSize);
- assert(dextUniqueIDCString != NULL);
-
- if (dext->dextLaunchedCount == 0) {
- OSKextLog(dext,
- kOSKextLogErrorLevel | kOSKextLogLoadFlag,
- "Over decrementing dext launch for %s UniqueID %s\n",
- dextIDCS, dextUniqueIDCString);
-
- goto out_locked;
- }
-
- dext->dextLaunchedCount--;
-
- OSKextLog(dext,
- kOSKextLogProgressLevel | kOSKextLogLoadFlag,
- "Dext terminated for %s UniqueID %s",
- dextIDCS, dextUniqueIDCString);
-
- if (dext->dextLaunchedCount == 0 && dext->flags.dextToReplace == 1) {
- /*
- * Find the upgraded dext.
- */
- OSKext *newdext = OSDynamicCast(OSKext, sDriverKitToUpgradeByID->getObject(dextIDCS));
- if (newdext) {
- OSKextLog(dext,
- kOSKextLogProgressLevel | kOSKextLogLoadFlag,
- "Dext upgrade for %s UniqueID %s",
- dextIDCS, dextUniqueIDCString);
- replaceDextInternal(dext, newdext);
- /* NOTE dext could have been freed past this point */
-
- sDriverKitToUpgradeByID->removeObject(dextIDCS);
- } else {
- OSKextLog(dext,
- kOSKextLogProgressLevel | kOSKextLogLoadFlag,
- "Dext unload for %s UniqueID %s",
- dextIDCS, dextUniqueIDCString);
- replaceDextInternal(dext, NULL);
- }
-
- ret = true;
- }
-out_locked:
- IORecursiveLockUnlock(sKextLock);
-
- if (dextUniqueIDCString != NULL) {
- kfree_data(dextUniqueIDCString, dextUniqueIDCStringSize);
- }
-
- return ret;
}
/*********************************************************************
@@ -6364,18 +5458,8 @@
{
// instantiate a new kext, and don't hold a reference
// (the kext subsystem will hold one implicitly)
- OSKextInitResult ret;
- OSSharedPtr<OSKext> newKext = OSKext::withCodelessInfo(anInfoDict, &ret);
+ OSSharedPtr<OSKext> newKext = OSKext::withCodelessInfo(anInfoDict);
if (!newKext) {
- /*
- * We might have failed to create a new OSKext
- * because the old one should still be used.
- * Check if that is the case.
- */
- if (ret != kOSKextInitFailure) {
- result = kOSReturnSuccess;
- goto finish;
- }
OSKextLog(/* kext */ NULL,
kOSKextLogErrorLevel |
kOSKextLogGeneralFlag | kOSKextLogLoadFlag,
@@ -6749,7 +5833,6 @@
"task_%s", getIdentifierCString());
account->task_refgrp.grp_name = account->task_refgrp_name;
account->task_refgrp.grp_parent = &task_external_refgrp;
- account->task_refgrp.grp_flags = OS_REFGRP_F_ALWAYS_ENABLED;
os_ref_log_init(&account->task_refgrp);
#endif /* DEVELOPMENT || DEBUG */
@@ -6853,7 +5936,7 @@
getIdentifierCString());
queueKextNotification(kKextRequestPredicateLoadNotification,
- OSDynamicCast(OSString, bundleID.get()), getDextUniqueID());
+ OSDynamicCast(OSString, bundleID.get()));
}
return result;
}
@@ -6873,7 +5956,8 @@
}
size = 1 + strlen(string);
- result = (char *)kalloc_data_tag(size, Z_WAITOK, VM_KERN_MEMORY_OSKEXT);
+ result = (char *)kheap_alloc_tag(KHEAP_DATA_BUFFERS, size,
+ Z_WAITOK, VM_KERN_MEMORY_OSKEXT);
if (!result) {
goto finish;
}
@@ -6944,7 +6028,6 @@
uint32_t i = 0;
int reloc_size;
vm_offset_t new_kextsize;
- kc_format format = KCFormatUnknown;
if (linkedExecutable == NULL || flags.builtin) {
result = kOSReturnSuccess;
@@ -7136,21 +6219,11 @@
/* Fix up kmod info and linkedExecutable.
*/
kmod_info->size = new_kextsize;
- /*
- * Fileset KCs are mapped as a whole by iBoot.
- * Individual kext executables should not be unmapped
- * by xnu.
- * Doing so may result in panics like rdar://85419651
- */
- if (PE_get_kc_format(kc_type, &format) && (format == KCFormatFileset)) {
- new_osdata->setDeallocFunction(NULL);
- } else { // Not from a Fileset KC
#if VM_MAPPED_KEXTS
- new_osdata->setDeallocFunction(osdata_kext_free);
+ new_osdata->setDeallocFunction(osdata_kext_free);
#else
- new_osdata->setDeallocFunction(osdata_phys_free);
+ new_osdata->setDeallocFunction(osdata_phys_free);
#endif
- }
linkedExecutable->setDeallocFunction(NULL);
linkedExecutable = os::move(new_osdata);
@@ -7558,11 +6631,11 @@
if (kxlddeps[i].kext_name) {
size = 1 + strlen(kxlddeps[i].kext_name);
- kfree_data(kxlddeps[i].kext_name, size);
+ kheap_free(KHEAP_DATA_BUFFERS, kxlddeps[i].kext_name, size);
}
if (kxlddeps[i].interface_name) {
size = 1 + strlen(kxlddeps[i].interface_name);
- kfree_data(kxlddeps[i].interface_name, size);
+ kheap_free(KHEAP_DATA_BUFFERS, kxlddeps[i].interface_name, size);
}
}
if (kxlddeps) {
@@ -7623,11 +6696,7 @@
linkeditseg->vmaddr, linkeditseg->vmsize);
#else
/* BootKC on arm64 is not vm mapped, but is slid */
-#if !CONFIG_SPTM
vm_offset_t linkedit_vmaddr = ml_static_ptovirt((vm_offset_t)(linkeditseg->vmaddr - gVirtBase + gPhysBase));
-#else
- vm_offset_t linkedit_vmaddr = linkeditseg->vmaddr;
-#endif
ml_static_mfree(linkedit_vmaddr, (vm_size_t)linkeditseg->vmsize);
@@ -7653,7 +6722,6 @@
vm_offset_t start;
vm_size_t linkeditsize, kextsize;
OSSharedPtr<OSData> data;
- kc_format format = KCFormatUnknown;
if (isInFileset()) {
return;
@@ -7702,20 +6770,11 @@
*/
kmod_info->size = kextsize;
- /*
- * Fileset KCs are mapped as a whole by iBoot.
- * Individual kext executables should not be unmapped by xnu
- * Doing so may result in panics like rdar://85419651
- */
- if (PE_get_kc_format(kc_type, &format) && (format == KCFormatFileset)) {
- data->setDeallocFunction(NULL);
- } else { // Not from a Fileset KC
#if VM_MAPPED_KEXTS
- data->setDeallocFunction(osdata_kext_free);
+ data->setDeallocFunction(osdata_kext_free);
#else
- data->setDeallocFunction(osdata_phys_free);
+ data->setDeallocFunction(osdata_phys_free);
#endif
- }
linkedExecutable->setDeallocFunction(NULL);
linkedExecutable = os::move(data);
flags.jettisonLinkeditSeg = 1;
@@ -7855,6 +6914,7 @@
uint32_t modflag = 0;
OSObject * forceInit = getPropertyForHostArch("OSBundleForceDTraceInit");
+#if XNU_TARGET_OS_OSX
if (!sKeepSymbols && kc_type == KCKindPrimary) {
if (forceInit == kOSBooleanTrue) {
OSKextLog(this,
@@ -7867,7 +6927,7 @@
/* Linkedit segment of the Boot KC is gone, make sure fbt_provide_module don't use kernel symbols */
modflag |= KMOD_DTRACE_NO_KERNEL_SYMS;
}
-
+#endif /* XNU_TARGET_OS_OSX */
if (forceInit == kOSBooleanTrue) {
modflag |= KMOD_DTRACE_FORCE_INIT;
}
@@ -7908,13 +6968,11 @@
kernel_mach_header_t *kext_mh,
vm_map_t map,
vm_map_offset_t start,
- vm_map_size_t size,
+ vm_map_offset_t end,
vm_prot_t new_prot,
boolean_t set_max,
kc_kind_t kc_type)
{
- vm_map_offset_t end = start + size;
-
#pragma unused(kext_mh,map,kc_type)
assert(map == kernel_map); // we can handle KEXTs arising from the PRELINK segment and no others
assert(start <= end);
@@ -7923,7 +6981,7 @@
} else if (set_max) {
return KERN_SUCCESS; // Punt set_max, as there's no mechanism to record that state
} else {
- return ml_static_protect(start, size, new_prot);
+ return ml_static_protect(start, end - start, new_prot);
}
}
@@ -7949,13 +7007,11 @@
kernel_mach_header_t *kext_mh,
vm_map_t map,
vm_map_offset_t start,
- vm_map_size_t size,
+ vm_map_offset_t end,
vm_prot_t new_prot,
boolean_t set_max,
kc_kind_t kc_type)
{
- vm_map_offset_t end = start + size;
-
if (start == end) { // 10538581
return KERN_SUCCESS;
}
@@ -7964,9 +7020,9 @@
* XXX: This will probably need to be different for AuxKC and
* pageableKC!
*/
- return ml_static_protect(start, size, new_prot);
- }
- return mach_vm_protect(map, start, size, set_max, new_prot);
+ return ml_static_protect(start, end - start, new_prot);
+ }
+ return vm_map_protect(map, start, end, new_prot, set_max);
}
static inline kern_return_t
@@ -7995,7 +7051,6 @@
vm_map_offset_t start_protect = 0;
vm_map_offset_t start_wire = 0;
vm_map_offset_t end_protect = 0;
- vm_map_size_t size_protect = 0;
vm_map_offset_t end_wire = 0;
OSReturn result = kOSReturnError;
@@ -8034,7 +7089,7 @@
/* Protect the headers as read-only; they do not need to be wired */
result = (protect) ? OSKext_protect((kernel_mach_header_t *)kmod_info->address,
kext_map, kmod_info->address,
- kmod_info->hdr_size, VM_PROT_READ, TRUE, kc_type)
+ kmod_info->address + kmod_info->hdr_size, VM_PROT_READ, TRUE, kc_type)
: KERN_SUCCESS;
if (result != KERN_SUCCESS) {
goto finish;
@@ -8064,7 +7119,6 @@
*/
start_protect = round_page(seg->vmaddr);
end_protect = trunc_page(seg->vmaddr + seg->vmsize);
- size_protect = end_protect - start_protect;
start_wire = trunc_page(seg->vmaddr);
end_wire = round_page(seg->vmaddr + seg->vmsize);
@@ -8078,7 +7132,7 @@
strncmp(seg->segname, SEG_LINKINFO, sizeof(seg->segname)) != 0) ||
(kc_type != KCKindPageable && kc_type != KCKindAuxiliary))) {
result = OSKext_protect((kernel_mach_header_t *)kmod_info->address,
- kext_map, start_protect, size_protect, seg->maxprot, TRUE, kc_type);
+ kext_map, start_protect, end_protect, seg->maxprot, TRUE, kc_type);
if (result != KERN_SUCCESS) {
OSKextLog(this,
kOSKextLogErrorLevel |
@@ -8090,7 +7144,7 @@
}
result = OSKext_protect((kernel_mach_header_t *)kmod_info->address,
- kext_map, start_protect, size_protect, seg->initprot, FALSE, kc_type);
+ kext_map, start_protect, end_protect, seg->initprot, FALSE, kc_type);
if (result != KERN_SUCCESS) {
OSKextLog(this,
kOSKextLogErrorLevel |
@@ -8373,7 +7427,7 @@
} else {
uuid_info->ftui_address = ml_static_unslide(address);
}
- os_log_encoded_metadata(trace_id, stamp, uuid_info, uuid_info_len);
+ firehose_trace_metadata(firehose_stream_metadata, trace_id, stamp, uuid_info, uuid_info_len);
return;
}
@@ -8673,14 +7727,14 @@
OSKextLog(this,
kOSKextLogErrorLevel |
kOSKextLogKextBookkeepingFlag,
- "Can't unload kext %s; outstanding references %d (linkage or tracking object).",
- getIdentifierCString(), getRetainCount());
+ "Can't unload kext %s; outstanding references (linkage or tracking object).",
+ getIdentifierCString());
result = kOSKextReturnInUse;
goto finish;
}
if (isDriverKit()) {
- index = sLoadedDriverKitKexts->getNextIndexOfObject(this, 0);
+ index = sLoadedKexts->getNextIndexOfObject(this, 0);
if (index != (unsigned int)-1) {
sLoadedDriverKitKexts->removeObject(index);
OSKextLogKextInfo(this, loadTag, 1, firehose_tracepoint_code_unload);
@@ -8819,7 +7873,7 @@
notifyKextUnloadObservers(this);
freeAccount = NULL;
- lck_ticket_lock(sKextAccountsLock, sKextAccountsLockGrp);
+ IOSimpleLockLock(sKextAccountsLock);
account->kext = NULL;
if (account->site.tag) {
account->site.flags |= VM_TAG_UNLOAD;
@@ -8832,7 +7886,7 @@
"unloading a kext with active task references");
#endif /* DEVELOPMENT || DEBUG */
- lck_ticket_unlock(sKextAccountsLock);
+ IOSimpleLockUnlock(sKextAccountsLock);
if (freeAccount) {
IOFreeType(freeAccount, OSKextAccount);
}
@@ -8947,7 +8001,7 @@
"Kext %s unloaded.", getIdentifierCString());
queueKextNotification(kKextRequestPredicateUnloadNotification,
- OSDynamicCast(OSString, bundleID.get()), getDextUniqueID());
+ OSDynamicCast(OSString, bundleID.get()));
finish:
OSKext::saveLoadedKextPanicList();
@@ -8964,8 +8018,7 @@
OSReturn
OSKext::queueKextNotification(
const char * notificationName,
- OSString * kextIdentifier,
- OSData * dextUniqueIdentifier)
+ OSString * kextIdentifier)
{
OSReturn result = kOSReturnError;
OSSharedPtr<OSDictionary> loadRequest;
@@ -8986,13 +8039,6 @@
kKextRequestArgumentBundleIdentifierKey, kextIdentifier)) {
result = kOSKextReturnNoMemory;
goto finish;
- }
- if (NULL != dextUniqueIdentifier) {
- if (!_OSKextSetRequestArgument(loadRequest.get(),
- kKextRequestArgumentDriverUniqueIdentifier, dextUniqueIdentifier)) {
- result = kOSKextReturnNoMemory;
- goto finish;
- }
}
if (!sKernelRequests->setObject(loadRequest.get())) {
result = kOSKextReturnNoMemory;
@@ -9201,17 +8247,15 @@
do {
OSDictionary * callbackRecord = OSDynamicCast(OSDictionary,
sRequestCallbackRecords->getObject(i));
- if (callbackRecord) {
- OSBoolean * stale = OSDynamicCast(OSBoolean,
- callbackRecord->getObject(kKextRequestStaleKey));
-
- if (stale == kOSBooleanTrue) {
- OSKext::invokeRequestCallback(callbackRecord,
- kOSKextReturnTimeout);
- } else {
- callbackRecord->setObject(kKextRequestStaleKey,
- kOSBooleanTrue);
- }
+ OSBoolean * stale = OSDynamicCast(OSBoolean,
+ callbackRecord->getObject(kKextRequestStaleKey));
+
+ if (stale == kOSBooleanTrue) {
+ OSKext::invokeRequestCallback(callbackRecord,
+ kOSKextReturnTimeout);
+ } else {
+ callbackRecord->setObject(kKextRequestStaleKey,
+ kOSBooleanTrue);
}
} while (i--);
}
@@ -10274,16 +9318,6 @@
return result;
}
-bool
-OSKext::iokitDaemonActive()
-{
- bool result;
- IORecursiveLockLock(sKextLock);
- result = sIOKitDaemonActive && !sOSKextWasResetAfterUserspaceReboot;
- IORecursiveLockUnlock(sKextLock);
- return result;
-}
-
/*********************************************************************
* XXX - this function is a big ugly mess
*********************************************************************/
@@ -10324,7 +9358,6 @@
OSKext * theKext = NULL; // do not release
OSBoolean * boolArg = NULL; // do not release
-
IORecursiveLockLock(sKextLock);
if (responseOut) {
@@ -10378,6 +9411,7 @@
result = kOSKextReturnInvalidArgument;
goto finish;
}
+
OSKextLog(/* kext */ NULL,
kOSKextLogDebugLevel |
kOSKextLogIPCFlag,
@@ -10399,9 +9433,6 @@
predicate->isEqualTo(kKextRequestPredicateMissingAuxKCBundles) ||
predicate->isEqualTo(kKextRequestPredicateAuxKCBundleAvailable) ||
predicate->isEqualTo(kKextRequestPredicateDaemonReady)) {
- if (!iokitDaemonAvailable()) {
- panic("Received unexpected request in environment where " kIOKitDaemonName " is unavailable");
- }
if (hostPriv == HOST_PRIV_NULL) {
OSKextLog(/* kext */ NULL,
kOSKextLogErrorLevel |
@@ -10471,6 +9502,7 @@
result = kOSKextReturnNotPrivileged;
goto finish;
}
+
result = kOSKextReturnInvalidArgument;
if (predicate->isEqualTo(kKextRequestPredicateStart)) {
@@ -10562,14 +9594,10 @@
kextIdentifier->getCStringNoCopy());
result = kOSKextReturnNotFound;
} else {
- if (theKext->isDriverKit()) {
- result = OSKext::removeDext(theKext);
- } else {
- OSBoolean * terminateFlag = OSDynamicCast(OSBoolean,
- _OSKextGetRequestArgument(requestDict,
- kKextRequestArgumentTerminateIOServicesKey));
- result = OSKext::removeKext(theKext, terminateFlag == kOSBooleanTrue);
- }
+ OSBoolean * terminateFlag = OSDynamicCast(OSBoolean,
+ _OSKextGetRequestArgument(requestDict,
+ kKextRequestArgumentTerminateIOServicesKey));
+ result = OSKext::removeKext(theKext, terminateFlag == kOSBooleanTrue);
}
} else if (predicate->isEqualTo(kKextRequestPredicateSendResource)) {
result = OSKext::dispatchResource(requestDict);
@@ -10587,8 +9615,7 @@
}
} else if (predicate->isEqualTo(kKextRequestPredicateGetLoaded) ||
predicate->isEqualTo(kKextRequestPredicateGetLoadedByUUID) ||
- predicate->isEqualTo(kKextRequestPredicateGetKextsInCollection) ||
- predicate->isEqualTo(kKextRequestPredicateGetDexts)) {
+ predicate->isEqualTo(kKextRequestPredicateGetKextsInCollection)) {
OSBoolean * delayAutounloadBool = NULL;
OSObject * infoKeysRaw = NULL;
OSArray * infoKeys = NULL;
@@ -10635,8 +9662,6 @@
responseObject = OSKext::copyLoadedKextInfoByUUID(kextIdentifiers, infoKeys);
} else if (predicate->isEqualTo(kKextRequestPredicateGetKextsInCollection)) {
responseObject = OSKext::copyKextCollectionInfo(requestDict, infoKeys);
- } else if (predicate->isEqualTo(kKextRequestPredicateGetDexts)) {
- responseObject = OSKext::copyDextsInfo(kextIdentifiers, infoKeys);
}
if (!responseObject) {
@@ -10672,12 +9697,8 @@
printf("KextLog: Loading FileSet KC(s)\n");
result = OSKext::loadFileSetKexts(requestDict);
} else if (predicate->isEqualTo(kKextRequestPredicateDaemonReady)) {
- bool active = iokitDaemonActive();
- printf("KextLog: " kIOKitDaemonName " is %s\n", active ? "active" : "not active");
- if (sOSKextWasResetAfterUserspaceReboot) {
- printf("KextLog: was reset after userspace reboot\n");
- }
- result = active ? kOSReturnSuccess : kIOReturnNotReady;
+ printf("KextLog: " kIOKitDaemonName " is %s\n", sIOKitDaemonActive ? "active" : "not active");
+ result = (sIOKitDaemonActive && !sOSKextWasResetAfterUserspaceReboot) ? kOSReturnSuccess : kIOReturnNotReady;
} else {
OSKextLog(/* kext */ NULL,
kOSKextLogDebugLevel |
@@ -10751,7 +9772,7 @@
/* This kmem_alloc sets the return value of the function.
*/
kmem_result = kmem_alloc(kernel_map, (vm_offset_t *)&buffer,
- round_page(responseLength), KMA_DATA_SHARED, VM_KERN_MEMORY_OSKEXT);
+ round_page(responseLength), VM_KERN_MEMORY_OSKEXT);
if (kmem_result != KERN_SUCCESS) {
OSKextLog(/* kext */ NULL,
kOSKextLogErrorLevel |
@@ -11089,30 +10110,21 @@
// #include <InstrProfiling.h>
extern "C" {
-uint64_t __llvm_profile_get_size_for_buffer_internal(
- const char *DataBegin,
- const char *DataEnd,
- const char *CountersBegin,
- const char *CountersEnd,
- const char *BitmapBegin,
- const char *BitmapEnd,
- const char *NamesBegin,
- const char *NamesEnd,
- const char *VTableBegin,
- const char *VTableEnd,
- const char *VNamesBegin,
- const char *VNamesEnd);
-int __llvm_profile_write_buffer_internal(
- char *Buffer,
- const char *DataBegin,
- const char *DataEnd,
- const char *CountersBegin,
- const char *CountersEnd,
- const char *BitmapBegin,
- const char *BitmapEnd,
- const char *NamesBegin,
- const char *NamesEnd);
-}
+uint64_t __llvm_profile_get_size_for_buffer_internal(const char *DataBegin,
+ const char *DataEnd,
+ const char *CountersBegin,
+ const char *CountersEnd,
+ const char *NamesBegin,
+ const char *NamesEnd);
+int __llvm_profile_write_buffer_internal(char *Buffer,
+ const char *DataBegin,
+ const char *DataEnd,
+ const char *CountersBegin,
+ const char *CountersEnd,
+ const char *NamesBegin,
+ const char *NamesEnd);
+}
+
static
void
@@ -11239,9 +10251,6 @@
}
sect_prf_cnts = kext->lookupSection("__DATA", "__llvm_prf_cnts");
- // Ignore some sections used by optional PGO variants.
- const char *unused_section = NULL;
-
if (!sect_prf_data || !sect_prf_name || !sect_prf_cnts) {
err = ENOTSUP;
goto out;
@@ -11250,10 +10259,7 @@
size = __llvm_profile_get_size_for_buffer_internal(
(const char*) sect_prf_data->addr, (const char*) sect_prf_data->addr + sect_prf_data->size,
(const char*) sect_prf_cnts->addr, (const char*) sect_prf_cnts->addr + sect_prf_cnts->size,
- unused_section /* bits */, unused_section /* bits end */,
- (const char*) sect_prf_name->addr, (const char*) sect_prf_name->addr + sect_prf_name->size,
- unused_section /* vtab */, unused_section /* vtab end */,
- unused_section /* vnam */, unused_section /* vnam end */);
+ (const char*) sect_prf_name->addr, (const char*) sect_prf_name->addr + sect_prf_name->size);
if (metadata) {
metadata_size = OSKextPgoMetadataSize(kext);
@@ -11276,7 +10282,6 @@
pBuffer,
(const char*) sect_prf_data->addr, (const char*) sect_prf_data->addr + sect_prf_data->size,
(const char*) sect_prf_cnts->addr, (const char*) sect_prf_cnts->addr + sect_prf_cnts->size,
- unused_section /* bits */, unused_section /* bits end */,
(const char*) sect_prf_name->addr, (const char*) sect_prf_name->addr + sect_prf_name->size);
if (err) {
@@ -11682,202 +10687,6 @@
} // end block scope
IORecursiveLockUnlock(sKextLock);
-finish:
- return result;
-}
-
-/* static */
-OSSharedPtr<OSArray>
-OSKext::copyDextsInfo(
- OSArray *kextIdentifiers,
- OSArray *infoKeys)
-{
- OSSharedPtr<OSArray> result = NULL;
- uint32_t idCount = 0;
- bool getActive = false;
- bool getLoaded = false;
- bool getUnloaded = false;
- bool getPendingUpgrade = false;
- unsigned int avgDextCount = 0;
-
-#if CONFIG_MACF
- /* Is the calling process allowed to query dext info? */
- if (current_task() != kernel_task) {
- int macCheckResult = 0;
- kauth_cred_t cred = NULL;
-
- cred = kauth_cred_get_with_ref();
- macCheckResult = mac_kext_check_query(cred);
- kauth_cred_unref(&cred);
-
- if (macCheckResult != 0) {
- OSKextLog(/* kext */ NULL,
- kOSKextLogErrorLevel | kOSKextLogLoadFlag,
- "Failed to query kext info (MAC policy error 0x%x).",
- macCheckResult);
- goto finish;
- }
- }
-#endif
- /*
- * No infoKeys means return everything we
- * know about the dexts.
- */
- if (infoKeys && !infoKeys->getCount()) {
- infoKeys = NULL;
- }
-
- /*
- * Empty list of bundle ids is equivalent to
- * no list (get all).
- */
- if (kextIdentifiers && !kextIdentifiers->getCount()) {
- kextIdentifiers = NULL;
- } else if (kextIdentifiers) {
- idCount = kextIdentifiers->getCount();
- }
-
- /*
- * Caller can specify which state of dexts to query.
- */
- if (infoKeys && _OSArrayContainsCString(infoKeys, kOSBundleDextStateActiveKey)) {
- getActive = true;
- }
- if (infoKeys && _OSArrayContainsCString(infoKeys, kOSBundleDextStateActiveLoadedKey)) {
- getLoaded = true;
- }
- if (infoKeys && _OSArrayContainsCString(infoKeys, kOSBundleDextStateActiveUnloadedKey)) {
- getUnloaded = true;
- }
- if (infoKeys && _OSArrayContainsCString(infoKeys, kOSBundleDextStatePendingUpgradeKey)) {
- getPendingUpgrade = true;
- }
-
- /*
- * By default we are going to return all active and pendingUpgrade dexts
- * only.
- */
- if (!(getActive || getLoaded || getUnloaded || getPendingUpgrade)) {
- getActive = true;
- getPendingUpgrade = true;
- }
-
- /*
- * We return a dictionary of dexts
- * for every group requested.
- */
- avgDextCount = sLoadedDriverKitKexts->getCount() + sDriverKitToUpgradeByID->getCount();
- result = OSArray::withCapacity(avgDextCount);
- if (!result) {
- goto finish;
- }
-
- IORecursiveLockLock(sKextLock);
- { // start block scope
- if (getActive || getLoaded || getUnloaded) {
- sKextsByID->iterateObjects(^bool (const OSSymbol *thisKextID, OSObject *obj)
- {
- OSKext *thisKext = NULL; // do not release
- OSSharedPtr<OSDictionary> kextInfo;
- Boolean includeThis = true;
- (void)thisKextID;
-
- thisKext = OSDynamicCast(OSKext, obj);
- if (!thisKext || !thisKext->isDriverKit()) {
- return false;
- }
-
- /*
- * Skip current dext if we have a list of bundle IDs and
- * it isn't in the list.
- */
- if (kextIdentifiers) {
- includeThis = false;
-
- for (uint32_t idIndex = 0; idIndex < idCount; idIndex++) {
- const OSString * thisRequestID = OSDynamicCast(OSString,
- kextIdentifiers->getObject(idIndex));
- if (thisKextID->isEqualTo(thisRequestID)) {
- includeThis = true;
- break;
- }
- }
- }
-
- if (!includeThis) {
- return false;
- }
-
- OSSharedPtr<OSString> state;
- if (sLoadedDriverKitKexts->getNextIndexOfObject(thisKext, 0) == -1U) {
- if (!(getActive || getUnloaded)) {
- return false;
- }
- state = OSString::withCString(kOSBundleDextStateActiveUnloadedKey);
- } else {
- if (!(getActive || getLoaded)) {
- return false;
- }
- state = OSString::withCString(kOSBundleDextStateActiveLoadedKey);
- }
-
- kextInfo = thisKext->copyInfo(infoKeys);
- if (kextInfo) {
- kextInfo->setObject(kOSBundleDextStateKey, state.get());
- result->setObject(kextInfo.get());
- }
-
- return false;
- });
- }
-
- if (getPendingUpgrade) {
- sDriverKitToUpgradeByID->iterateObjects(^bool (const OSSymbol *thisKextID, OSObject *obj)
- {
- OSKext *thisKext = NULL; // do not release
- OSSharedPtr<OSDictionary> kextInfo;
- Boolean includeThis = true;
- (void)thisKextID;
-
- thisKext = OSDynamicCast(OSKext, obj);
- if (!thisKext) {
- return false;
- }
- __assert_only bool isDext = thisKext->isDriverKit();
- assert(isDext == true);
-
- /*
- * Skip current dext if we have a list of bundle IDs and
- * it isn't in the list.
- */
- if (kextIdentifiers) {
- includeThis = false;
-
- for (uint32_t idIndex = 0; idIndex < idCount; idIndex++) {
- const OSString * thisRequestID = OSDynamicCast(OSString,
- kextIdentifiers->getObject(idIndex));
- if (thisKextID->isEqualTo(thisRequestID)) {
- includeThis = true;
- break;
- }
- }
- }
-
- if (!includeThis) {
- return false;
- }
-
- kextInfo = thisKext->copyInfo(infoKeys);
- if (kextInfo) {
- OSSharedPtr<OSString> state = OSString::withCString(kOSBundleDextStatePendingUpgradeKey);
- kextInfo->setObject(kOSBundleDextStateKey, state.get());
- result->setObject(kextInfo.get());
- }
- return false;
- });
- }
- } // end block scope
- IORecursiveLockUnlock(sKextLock);
finish:
return result;
}
@@ -12105,7 +10914,7 @@
}
lcp = (struct load_command *) (temp_kext_mach_hdr + 1);
- for (i = 0; (i < temp_kext_mach_hdr->ncmds) && !flags.unslidMachO; i++) {
+ for (i = 0; i < temp_kext_mach_hdr->ncmds; i++) {
if (lcp->cmd == LC_SEGMENT_KERNEL) {
kernel_segment_command_t * segp;
kernel_section_t * secp;
@@ -12180,21 +10989,10 @@
bool res;
os_log_data = getsectdatafromheader(kext_mach_hdr, "__TEXT", "__os_log", &os_log_size);
+ os_log_offset = (uintptr_t)os_log_data - (uintptr_t)kext_mach_hdr;
cstring_data = getsectdatafromheader(kext_mach_hdr, "__TEXT", "__cstring", &cstring_size);
+ cstring_offset = (uintptr_t)cstring_data - (uintptr_t)kext_mach_hdr;
asan_cstring_data = getsectdatafromheader(kext_mach_hdr, "__TEXT", "__asan_cstring", &asan_cstring_size);
-
- /*
- * If the addresses in the Mach-O header are unslid, manually
- * slide them to allow for dereferencing.
- */
- if (flags.unslidMachO) {
- os_log_data = (os_log_data != nullptr) ? (void*)ml_static_slide((vm_offset_t)os_log_data) : nullptr;
- cstring_data = (cstring_data != nullptr) ? (void*)ml_static_slide((vm_offset_t)cstring_data) : nullptr;
- asan_cstring_data = (asan_cstring_data != nullptr) ? (void*)ml_static_slide((vm_offset_t)asan_cstring_data) : nullptr;
- }
-
- os_log_offset = (uintptr_t)os_log_data - (uintptr_t)kext_mach_hdr;
- cstring_offset = (uintptr_t)cstring_data - (uintptr_t)kext_mach_hdr;
asan_cstring_offset = (uintptr_t)asan_cstring_data - (uintptr_t)kext_mach_hdr;
header = (osLogDataHeaderRef *) headerBytes;
@@ -12208,7 +11006,7 @@
header->sections[ASAN_CSTRING_SECT_IDX].sect_size = (uint32_t) asan_cstring_size;
- logData = OSData::withValue(*header);
+ logData = OSData::withBytes(header, (u_int) (sizeof(osLogDataHeaderRef)));
if (!logData) {
goto finish;
}
@@ -12272,7 +11070,7 @@
header->sections[ASAN_CSTRING_SECT_IDX].sect_offset = 0;
header->sections[ASAN_CSTRING_SECT_IDX].sect_size = (uint32_t) 0;
- logData = OSData::withValue(*header);
+ logData = OSData::withBytes(header, (u_int) (sizeof(osLogDataHeaderRef)));
if (!logData) {
goto finish;
}
@@ -12288,12 +11086,6 @@
/* CFBundleIdentifier. We set this regardless because it's just stupid not to.
*/
result->setObject(kCFBundleIdentifierKey, bundleID.get());
-
- /* kOSBundleDextUniqueIdentifierKey if present.
- */
- if (isDriverKit() && dextUniqueID != NULL) {
- result->setObject(kOSBundleDextUniqueIdentifierKey, dextUniqueID.get());
- }
/* CFBundlePackageType
*/
@@ -12527,7 +11319,7 @@
*/
for (seg = firstsegfromheader(mh); seg != NULL; seg = nextsegfromheader(mh, seg)) {
if (seg->initprot & VM_PROT_EXECUTE) {
- execLoadAddress = (flags.unslidMachO) ? seg->vmaddr : ml_static_unslide(seg->vmaddr);
+ execLoadAddress = ml_static_unslide(seg->vmaddr);
execLoadSize = (uint32_t)seg->vmsize;
break;
}
@@ -12766,9 +11558,9 @@
OSSharedPtr<OSString> resourceName;
OSSharedPtr<OSDictionary> callbackRecord;
- OSSharedPtr<OSValueObject<OSKextRequestResourceCallback> > callbackWrapper;
-
- OSSharedPtr<OSValueObject<void *> > contextWrapper;
+ OSSharedPtr<OSData> callbackWrapper;
+
+ OSSharedPtr<OSData> contextWrapper;
IORecursiveLockLock(sKextLock);
@@ -12856,9 +11648,9 @@
goto finish;
}
// we validate callback address at call time
- callbackWrapper = OSValueObjectWithValue(callback);
+ callbackWrapper = OSData::withBytes((void *)&callback, sizeof(void *));
if (context) {
- contextWrapper = OSValueObjectWithValue(context);
+ contextWrapper = OSData::withBytes((void *)&context, sizeof(void *));
}
if (!callbackWrapper || !_OSKextSetRequestArgument(callbackRecord.get(),
kKextRequestArgumentCallbackKey, callbackWrapper.get())) {
@@ -12920,24 +11712,13 @@
OSString *kextIdentifier,
OSString *serverName,
OSNumber *serverTag,
- OSBoolean *reslide,
- IOUserServerCheckInToken * checkInToken,
- OSData *serverDUI)
+ IOUserServerCheckInToken * checkInToken)
{
OSReturn result = kOSReturnError;
OSSharedPtr<OSDictionary> requestDict;
- unsigned int size = 0;
- const char *dextUniqueIDCString = NULL;
if (!kextIdentifier || !serverName || !serverTag || !checkInToken) {
return kOSKextReturnInvalidArgument;
- }
- if (!iokitDaemonAvailable()) {
- panic("Received unexpected request in environment where " kIOKitDaemonName " is unavailable");
- }
-
- if (serverDUI != NULL) {
- dextUniqueIDCString = getDextUniqueIDCString(serverDUI, &size);
}
IORecursiveLockLock(sKextLock);
@@ -12945,12 +11726,10 @@
OSKextLog(/* kext */ NULL,
kOSKextLogDebugLevel |
kOSKextLogGeneralFlag,
- "Requesting daemon launch for %s %s with serverName %s and tag %llu%s",
+ "Requesting daemon launch for %s with serverName %s and tag %llu",
kextIdentifier->getCStringNoCopy(),
- (dextUniqueIDCString != NULL)?dextUniqueIDCString:"",
serverName->getCStringNoCopy(),
- serverTag->unsigned64BitValue(),
- reslide == kOSBooleanTrue ? " with reslid shared cache" : ""
+ serverTag->unsigned64BitValue()
);
result = _OSKextCreateRequest(kKextRequestPredicateRequestDaemonLaunch, requestDict);
@@ -12965,21 +11744,11 @@
!_OSKextSetRequestArgument(requestDict.get(),
kKextRequestArgumentDriverExtensionServerTag, serverTag) ||
!_OSKextSetRequestArgument(requestDict.get(),
- kKextRequestArgumentDriverExtensionReslideSharedCache, reslide) ||
- !_OSKextSetRequestArgument(requestDict.get(),
kKextRequestArgumentCheckInToken, checkInToken)) {
result = kOSKextReturnNoMemory;
goto finish;
}
- if (serverDUI) {
- if (!_OSKextSetRequestArgument(requestDict.get(),
- kOSBundleDextUniqueIdentifierKey, serverDUI)) {
- result = kOSKextReturnNoMemory;
- goto finish;
- }
- }
-
/* Only post the requests after all the other potential failure points
* have been passed.
*/
@@ -12987,68 +11756,11 @@
result = kOSKextReturnNoMemory;
goto finish;
}
- result = OSKext::pingIOKitDaemon();
- if (result != kOSReturnSuccess) {
- goto finish;
- }
+ OSKext::pingIOKitDaemon();
result = kOSReturnSuccess;
finish:
IORecursiveLockUnlock(sKextLock);
- if (dextUniqueIDCString) {
- kfree_data(dextUniqueIDCString, size);
- }
- return result;
-}
-
-OSReturn
-OSKext::notifyDextUpgrade(
- OSString *kextIdentifier,
- OSData *dextUniqueIdentifier)
-{
- OSReturn result = kOSReturnError;
- OSSharedPtr<OSDictionary> requestDict;
- unsigned int size = 0;
- const char *dextUniqueIDCString = getDextUniqueIDCString(dextUniqueIdentifier, &size);
- assert(dextUniqueIDCString != NULL);
-
- IORecursiveLockLock(sKextLock);
-
- OSKextLog(NULL,
- kOSKextLogDebugLevel |
- kOSKextLogGeneralFlag,
- "Notifying of dext upgrade for %s with UniqueID %s",
- kextIdentifier->getCStringNoCopy(), dextUniqueIDCString);
-
- result = _OSKextCreateRequest(kKextRequestPredicateRequestDaemonUpgradeNotification, requestDict);
- if (result != kOSReturnSuccess) {
- goto finish;
- }
-
- if (!_OSKextSetRequestArgument(requestDict.get(),
- kKextRequestArgumentBundleIdentifierKey, kextIdentifier) ||
- !_OSKextSetRequestArgument(requestDict.get(),
- kKextRequestArgumentDriverUniqueIdentifier, dextUniqueIdentifier)) {
- result = kOSKextReturnNoMemory;
- goto finish;
- }
-
- /* Only post the requests after all the other potential failure points
- * have been passed.
- */
- if (!sKernelRequests->setObject(requestDict.get())) {
- result = kOSKextReturnNoMemory;
- goto finish;
- }
- OSKext::pingIOKitDaemon();
-
- result = kOSReturnSuccess;
-finish:
- IORecursiveLockUnlock(sKextLock);
-
- if (dextUniqueIDCString != NULL) {
- kfree_data(dextUniqueIDCString, size);
- }
return result;
}
@@ -13173,23 +11885,21 @@
return sRequestCallbackRecords && sRequestCallbackRecords->getCount();
}
+extern "C" int vm_enable_driverkit_shared_region;
+
/*********************************************************************
* Acquires and releases sKextLock
*
-* This function is designed to be called by kernelmanagerd and driverkitd
-* and it gathers all codeless kext and dext personalities, and then attempts
-* to map a System (pageable) KC and an Auxiliary (aux) KC.
+* This function is designed to be called exactly once on boot by
+* the IOKit management daemon, kernelmanagerd. It gathers all codeless
+* kext and dext personalities, and then attempts to map a System
+* (pageable) KC and an Auxiliary (aux) KC.
*
-* The pageable and aux KC can be loaded only once at boot time.
* Even if the pageable or aux KC fail to load - this function will
-* not allow a new pageable or aux KC to be installed by subsequent calls.
-* This is done to avoid security issues where userspace has been compromised
-* or the pageable kc has been tampered with and the attacker
-* attempts to re-load a malicious variant.
-* However dexts can be dynamically loaded, so this function can be used
-* to request the installation of a new set of dexts even after boot time.
-*
-*
+* not allow a second call. This avoids security issues where
+* kernelmanagerd has been compromised or the pageable kc has been
+* tampered with and the attacker attempts to re-load a malicious
+* variant.
*
* Return: if a KC fails to load the return value will contain:
* kOSKextReturnKCLoadFailure. If the pageable KC fails,
@@ -13240,6 +11950,7 @@
OSString * pageable_filepath = NULL; // do not release
OSString * aux_filepath = NULL; // do not release
OSArray * codeless_kexts = NULL; // do not release
+ OSNumber * enable_dk_shared_region = NULL; // do not release
kernel_mach_header_t *akc_mh = NULL;
@@ -13415,13 +12126,21 @@
}
// instantiate a new kext, and don't hold a reference
// (the kext subsystem will hold one implicitly)
- OSKext::withCodelessInfo(infoDict, NULL);
+ OSKext::withCodelessInfo(infoDict);
}
/* ignore errors that are not KC load failures */
if (ret != kOSKextReturnKCLoadFailure) {
ret = kOSReturnSuccess;
}
start_matching = true;
+ }
+
+ enable_dk_shared_region = OSDynamicCast(OSNumber,
+ requestArgs->getObject(kKextRequestEnableDriverKitSharedRegionKey));
+ if (enable_dk_shared_region != NULL && enable_dk_shared_region->unsigned64BitValue() == 1) {
+ OSKextLog(NULL, kOSKextLogDebugLevel | kOSKextLogIPCFlag,
+ "KextLog: Enabling DriverKit shared region.");
+ vm_enable_driverkit_shared_region = 1;
}
/* send personalities to the IOCatalog once */
@@ -13945,7 +12664,6 @@
kernel_segment_command_t * seg = NULL;
vm_map_offset_t start = 0;
vm_map_offset_t end = 0;
- vm_map_size_t size = 0;
OSReturn ret = 0;
/* Set VM permissions */
@@ -13953,7 +12671,6 @@
while (seg) {
start = round_page(seg->vmaddr);
end = trunc_page(seg->vmaddr + seg->vmsize);
- size = end - start;
/*
* Wire down and protect __TEXT, __BRANCH_STUBS and __BRANCH_GOTS
@@ -13966,14 +12683,14 @@
(type == KCKindAuxiliary && !resetAuxKCSegmentOnUnload &&
strncmp(seg->segname, SEG_LINKEDIT, sizeof(seg->segname)) == 0)) {
ret = OSKext_protect((kernel_mach_header_t *)mh,
- kext_map, start, size, seg->maxprot, TRUE, type);
+ kext_map, start, end, seg->maxprot, TRUE, type);
if (ret != KERN_SUCCESS) {
printf("OSKext protect failed with error %d", ret);
return kOSKextReturnInvalidArgument;
}
ret = OSKext_protect((kernel_mach_header_t *)mh,
- kext_map, start, size, seg->initprot, FALSE, type);
+ kext_map, start, end, seg->initprot, FALSE, type);
if (ret != KERN_SUCCESS) {
printf("OSKext protect failed with error %d", ret);
return kOSKextReturnInvalidArgument;
@@ -14170,12 +12887,10 @@
vm_object_offset_t fileoffset,
vm_prot_t max_prot)
{
- vm_map_kernel_flags_t vmk_flags = {
- .vmf_fixed = true,
- .vmkf_no_copy_on_read = true,
- .vmkf_cs_enforcement_override = true,
- .vm_tag = VM_KERN_MEMORY_OSKEXT,
- };
+ vm_map_kernel_flags_t vmk_flags;
+ vmk_flags.vmkf_no_copy_on_read = 1;
+ vmk_flags.vmkf_cs_enforcement = 0;
+ vmk_flags.vmkf_cs_enforcement_override = 1;
kern_return_t ret;
/* Add Write to max prot to allow fixups */
@@ -14191,7 +12906,9 @@
start,
size,
(mach_vm_offset_t)0,
+ VM_FLAGS_FIXED,
vmk_flags,
+ VM_KERN_MEMORY_OSKEXT,
(memory_object_control_t)control,
fileoffset,
TRUE, /* copy */
@@ -14328,9 +13045,9 @@
OSData * dataObj = NULL; // do not release
uint32_t dataLength = 0;
const void * dataPtr = NULL; // do not free
- OSValueObject<OSKextRequestResourceCallback> * callbackWrapper = nullptr; // do not release
+ OSData * callbackWrapper = NULL; // do not release
OSKextRequestResourceCallback callback = NULL;
- OSValueObject<void *> * contextWrapper = nullptr; // do not release
+ OSData * contextWrapper = NULL; // do not release
void * context = NULL; // do not free
OSSharedPtr<OSKext> callbackKext;
@@ -14356,14 +13073,14 @@
/*****
* Get the context pointer of the callback record (if there is one).
*/
- contextWrapper = OSDynamicCast(OSValueObject<void *>, _OSKextGetRequestArgument(
- callbackRecord.get(), kKextRequestArgumentContextKey));
+ contextWrapper = OSDynamicCast(OSData, _OSKextGetRequestArgument(callbackRecord.get(),
+ kKextRequestArgumentContextKey));
context = _OSKextExtractPointer(contextWrapper);
if (contextWrapper && !context) {
goto finish;
}
- callbackWrapper = OSDynamicCast(OSValueObject<OSKextRequestResourceCallback>,
+ callbackWrapper = OSDynamicCast(OSData,
_OSKextGetRequestArgument(callbackRecord.get(),
kKextRequestArgumentCallbackKey));
callback = _OSKextExtractCallbackPointer(callbackWrapper);
@@ -14528,7 +13245,7 @@
{
OSReturn result = kOSKextReturnNoMemory;
OSSharedPtr<OSDictionary> callbackRecord;
- OSValueObject<void *> * contextWrapper = nullptr; // do not release
+ OSData * contextWrapper = NULL; // do not release
IORecursiveLockLock(sKextLock);
result = OSKext::dequeueCallbackForRequestTag(requestTag,
@@ -14536,7 +13253,7 @@
IORecursiveLockUnlock(sKextLock);
if (result == kOSReturnSuccess && contextOut) {
- contextWrapper = OSDynamicCast(OSValueObject<void *>,
+ contextWrapper = OSDynamicCast(OSData,
_OSKextGetRequestArgument(callbackRecord.get(),
kKextRequestArgumentContextKey));
*contextOut = _OSKextExtractPointer(contextWrapper);
@@ -14568,7 +13285,7 @@
if (!request) {
continue;
}
- auto * callbackWrapper = OSDynamicCast(OSValueObject<OSKextRequestResourceCallback>,
+ OSData * callbackWrapper = OSDynamicCast(OSData,
_OSKextGetRequestArgument(request,
kKextRequestArgumentCallbackKey));
@@ -14618,7 +13335,7 @@
if (!request) {
continue;
}
- auto * callbackWrapper = OSDynamicCast(OSValueObject<OSKextRequestResourceCallback>,
+ OSData * callbackWrapper = OSDynamicCast(OSData,
_OSKextGetRequestArgument(request,
kKextRequestArgumentCallbackKey));
@@ -14696,9 +13413,9 @@
*********************************************************************/
static bool
_OSKextSetRequestArgument(
- OSDictionary * requestDict,
- const char * argName,
- OSMetaClassBase * value)
+ OSDictionary * requestDict,
+ const char * argName,
+ OSObject * value)
{
OSDictionary * args = OSDynamicCast(OSDictionary,
requestDict->getObject(kKextRequestArgumentsKey));
@@ -14720,25 +13437,36 @@
/*********************************************************************
*********************************************************************/
-template <typename T>
-static T *
-_OSKextExtractPointer(OSValueObject<T *> * wrapper)
-{
+static void *
+_OSKextExtractPointer(OSData * wrapper)
+{
+ void * result = NULL;
+ const void * resultPtr = NULL;
+
if (!wrapper) {
- return nullptr;
- }
- return wrapper->getRef();
+ goto finish;
+ }
+ resultPtr = wrapper->getBytesNoCopy();
+ result = *(void **)resultPtr;
+finish:
+ return result;
}
/*********************************************************************
*********************************************************************/
static OSKextRequestResourceCallback
-_OSKextExtractCallbackPointer(OSValueObject<OSKextRequestResourceCallback> * wrapper)
-{
+_OSKextExtractCallbackPointer(OSData * wrapper)
+{
+ OSKextRequestResourceCallback result = NULL;
+ const void * resultPtr = NULL;
+
if (!wrapper) {
- return nullptr;
- }
- return wrapper->getRef();
+ goto finish;
+ }
+ resultPtr = wrapper->getBytesNoCopy();
+ result = *(OSKextRequestResourceCallback *)resultPtr;
+finish:
+ return result;
}
@@ -14993,21 +13721,19 @@
OSDictionary * personality = OSDynamicCast(OSDictionary,
personalities->getObject(personalityName));
- if (personality) {
- /******
- * If the personality doesn't have a CFBundleIdentifier, or if it
- * differs from the kext's, insert the kext's ID so we can find it.
- * The publisher ID is used to remove personalities from bundles
- * correctly.
- */
- personalityBundleIdentifier = OSDynamicCast(OSString,
- personality->getObject(kCFBundleIdentifierKey));
-
- if (!personalityBundleIdentifier) {
- personality->setObject(kCFBundleIdentifierKey, bundleID.get());
- } else if (!personalityBundleIdentifier->isEqualTo(bundleID.get())) {
- personality->setObject(kIOPersonalityPublisherKey, bundleID.get());
- }
+ /******
+ * If the personality doesn't have a CFBundleIdentifier, or if it
+ * differs from the kext's, insert the kext's ID so we can find it.
+ * The publisher ID is used to remove personalities from bundles
+ * correctly.
+ */
+ personalityBundleIdentifier = OSDynamicCast(OSString,
+ personality->getObject(kCFBundleIdentifierKey));
+
+ if (!personalityBundleIdentifier) {
+ personality->setObject(kCFBundleIdentifierKey, bundleID.get());
+ } else if (!personalityBundleIdentifier->isEqualTo(bundleID.get())) {
+ personality->setObject(kIOPersonalityPublisherKey, bundleID.get());
}
result->setObject(personality);
@@ -15125,26 +13851,6 @@
return;
}
-void
-OSKext::updatePersonalitiesInCatalog(OSArray *upgradedPersonalities)
-{
- if (!upgradedPersonalities || upgradedPersonalities->getCount() == 0) {
- return;
- }
-
- OSSharedPtr<OSDictionary> personalityToRemove = OSDictionary::withCapacity(1);
- if (!personalityToRemove) {
- return;
- }
-
- /*
- * Create a personality dictionary with just the bundleID.
- * We will remove any personality that has a matching bundleID,
- * irrespective of which other keys are present on the dictionary.
- */
- personalityToRemove->setObject(kCFBundleIdentifierKey, getIdentifier());
- gIOCatalogue->exchangeDrivers(personalityToRemove.get(), upgradedPersonalities, true);
-}
#if PRAGMA_MARK
#pragma mark Logging
@@ -15372,6 +14078,8 @@
const char * format,
va_list srcArgList)
{
+ extern int disableConsoleOutput;
+
bool logForKernel = false;
bool logForUser = false;
va_list argList;
@@ -15440,7 +14148,7 @@
/* If we are in console mode and have a custom log filter,
* colorize the log message.
*/
- if (sBootArgLogFilterFound) {
+ if (!disableConsoleOutput && sBootArgLogFilterFound) {
const char * color = ""; // do not free
color = colorForFlags(msgLogSpec);
printf("%s%s%s\n", colorForFlags(msgLogSpec),
@@ -15660,6 +14368,8 @@
{
addr64_t summary_page = 0;
addr64_t last_summary_page = 0;
+ bool found_kmod = false;
+ u_int i = 0;
if (kPrintKextsLock & flags) {
if (!sKextSummariesLock) {
@@ -15683,13 +14393,27 @@
}
}
- foreachKextInBacktrace(addr, cnt, 0, ^(OSKextLoadedKextSummary *summary, uint32_t index) {
- if (index == 0 && !(kPrintKextsTerse & flags)) {
- (*printf_func)(" Kernel Extensions in backtrace:\n");
+ for (i = 0; i < gLoadedKextSummaries->numSummaries; ++i) {
+ OSKextLoadedKextSummary * summary;
+
+ summary = gLoadedKextSummaries->summaries + i;
+ if (!summary->address) {
+ continue;
+ }
+
+ if (!summaryIsInBacktrace(summary, addr, cnt)) {
+ continue;
+ }
+
+ if (!found_kmod) {
+ if (!(kPrintKextsTerse & flags)) {
+ (*printf_func)(" Kernel Extensions in backtrace:\n");
+ }
+ found_kmod = true;
}
printSummary(summary, printf_func, flags);
- });
+ }
finish:
if (kPrintKextsLock & flags) {
@@ -15697,42 +14421,6 @@
}
return;
-}
-
-void
-OSKext::foreachKextInBacktrace(
- vm_offset_t * addr,
- uint32_t cnt,
- uint32_t flags,
- void (^ handler)(OSKextLoadedKextSummary *summary, uint32_t index))
-{
- uint32_t n = 0;
-
- if (kPrintKextsLock & flags) {
- if (!sKextSummariesLock) {
- return;
- }
- IOLockLock(sKextSummariesLock);
- }
-
- for (uint32_t i = 0; i < gLoadedKextSummaries->numSummaries; ++i) {
- OSKextLoadedKextSummary * summary;
-
- summary = gLoadedKextSummaries->summaries + i;
- if (!summary->address) {
- continue;
- }
-
- if (!summaryIsInBacktrace(summary, addr, cnt)) {
- continue;
- }
-
- handler(summary, n++);
- }
-
- if (kPrintKextsLock & flags) {
- IOLockUnlock(sKextSummariesLock);
- }
}
/*********************************************************************
@@ -15806,6 +14494,7 @@
void *
OSKext::kextForAddress(const void *address)
{
+ void * image = NULL;
OSKextActiveAccount * active;
OSKext * kext = NULL;
uint32_t baseIdx;
@@ -15821,16 +14510,14 @@
#endif /* __has_feature(ptrauth_calls) */
if (sKextAccountsCount) {
- lck_ticket_lock(sKextAccountsLock, sKextAccountsLockGrp);
+ IOSimpleLockLock(sKextAccountsLock);
// bsearch sKextAccounts list
for (baseIdx = 0, lim = sKextAccountsCount; lim; lim >>= 1) {
active = &sKextAccounts[baseIdx + (lim >> 1)];
if ((addr >= active->address) && (addr < active->address_end)) {
- if (active->account &&
- (kext = active->account->kext) &&
- kext->kmod_info) {
- lck_ticket_unlock(sKextAccountsLock);
- return (void *)kext->kmod_info->address;
+ kext = active->account->kext;
+ if (kext && kext->kmod_info) {
+ image = (void *) kext->kmod_info->address;
}
break;
} else if (addr > active->address) {
@@ -15840,58 +14527,23 @@
}
// else move left
}
- lck_ticket_unlock(sKextAccountsLock);
- }
- if (kernel_text_contains(addr)) {
- return (void *)&_mh_execute_header;
- }
- if (gLoadedKextSummaries) {
+ IOSimpleLockUnlock(sKextAccountsLock);
+ }
+ if (!image && (addr >= vm_kernel_stext) && (addr < vm_kernel_etext)) {
+ image = (void *) &_mh_execute_header;
+ }
+ if (!image && gLoadedKextSummaries) {
IOLockLock(sKextSummariesLock);
for (i = 0; i < gLoadedKextSummaries->numSummaries; i++) {
OSKextLoadedKextSummary *summary = gLoadedKextSummaries->summaries + i;
if (addr >= summary->address && addr < summary->address + summary->size) {
- void *kextAddress = (void *)summary->address;
- IOLockUnlock(sKextSummariesLock);
- return kextAddress;
+ image = (void *)summary->address;
}
}
IOLockUnlock(sKextSummariesLock);
}
- return NULL;
-}
-
-/* static */
-kern_return_t
-OSKext::summaryForAddressExt(
- const void * address,
- OSKextLoadedKextSummary * summary)
-{
- kern_return_t result = KERN_FAILURE;
- const OSKextLoadedKextSummary * foundSummary = NULL;
-
- /*
- * This needs to be safe to call even before the lock has been initialized
- * in OSKext::initialize(), as we might get here from the ksancov runtime
- * when instrumenting XNU itself with sanitizer coverage.
- */
- if (!sKextSummariesLock) {
- return result;
- }
-
- IOLockLock(sKextSummariesLock);
- if (gLoadedKextSummaries) {
- foundSummary = summaryForAddress((uintptr_t)address);
- if (foundSummary) {
- memcpy(summary, foundSummary, sizeof(*summary));
- result = KERN_SUCCESS;
- } else {
- result = KERN_NOT_FOUND;
- }
- }
- IOLockUnlock(sKextSummariesLock);
-
- return result;
+ return image;
}
/*
@@ -16295,7 +14947,8 @@
}
if (loaded_kext_paniclist) {
- kfree_data(loaded_kext_paniclist, loaded_kext_paniclist_size);
+ kheap_free(KHEAP_DATA_BUFFERS, loaded_kext_paniclist,
+ loaded_kext_paniclist_size);
}
loaded_kext_paniclist = newlist;
newlist = NULL;
@@ -16364,23 +15017,15 @@
last_unloaded_address, last_unloaded_size);
}
- /*
- * In most cases the set of loaded kexts is statically determined by the
- * Boot KC, so it isn't very interesting to see in the paniclog.
- */
- if (auxKCloaded) {
- printf_func("loaded kexts:\n");
- if (loaded_kext_paniclist &&
- pmap_find_phys(kernel_pmap, (addr64_t) (uintptr_t) loaded_kext_paniclist) &&
- loaded_kext_paniclist[0]) {
- printf_func("%.*s",
- strnlen(loaded_kext_paniclist, loaded_kext_paniclist_size),
- loaded_kext_paniclist);
- } else {
- printf_func("(none)\n");
- }
+ printf_func("loaded kexts:\n");
+ if (loaded_kext_paniclist &&
+ pmap_find_phys(kernel_pmap, (addr64_t) (uintptr_t) loaded_kext_paniclist) &&
+ loaded_kext_paniclist[0]) {
+ printf_func("%.*s",
+ strnlen(loaded_kext_paniclist, loaded_kext_paniclist_size),
+ loaded_kext_paniclist);
} else {
- printf_func("loaded kexts: (skipped, see boot kernelcache)\n");
+ printf_func("(none)\n");
}
return;
}
@@ -16396,7 +15041,7 @@
OSKextLoadedKextSummaryHeader *summaryHeader = NULL;
OSKextLoadedKextSummaryHeader *summaryHeaderAlloc = NULL;
OSKext *aKext;
- vm_map_offset_t start;
+ vm_map_offset_t start, end;
size_t summarySize = 0;
size_t size;
u_int count;
@@ -16420,7 +15065,7 @@
count = sLoadedKexts->getCount();
for (i = 0, maxKexts = 0; i < count; ++i) {
aKext = OSDynamicCast(OSKext, sLoadedKexts->getObject(i));
- maxKexts += (aKext && (aKext->isExecutable() || aKext->isSpecialKernelBinary()));
+ maxKexts += (aKext && aKext->isExecutable());
}
if (!maxKexts) {
@@ -16444,8 +15089,7 @@
gLoadedKextSummariesTimestamp = mach_absolute_time();
sLoadedKextSummariesAllocSize = 0;
}
- result = kmem_alloc(kernel_map, (vm_offset_t *)&summaryHeaderAlloc, size,
- KMA_NONE, VM_KERN_MEMORY_OSKEXT);
+ result = kmem_alloc(kernel_map, (vm_offset_t *)&summaryHeaderAlloc, size, VM_KERN_MEMORY_OSKEXT);
if (result != KERN_SUCCESS) {
goto finish;
}
@@ -16456,11 +15100,12 @@
summarySize = sLoadedKextSummariesAllocSize;
start = (vm_map_offset_t) summaryHeader;
- result = mach_vm_protect(kernel_map,
+ end = start + summarySize;
+ result = vm_map_protect(kernel_map,
start,
- summarySize,
- false,
- VM_PROT_DEFAULT);
+ end,
+ VM_PROT_DEFAULT,
+ FALSE);
if (result != KERN_SUCCESS) {
goto finish;
}
@@ -16480,7 +15125,7 @@
accountingListAlloc = 0;
for (i = 0, j = 0; i < count && j < maxKexts; ++i) {
aKext = OSDynamicCast(OSKext, sLoadedKexts->getObject(i));
- if (!aKext || (!aKext->isExecutable() && !aKext->isSpecialKernelBinary())) {
+ if (!aKext || !aKext->isExecutable()) {
continue;
}
@@ -16493,7 +15138,7 @@
accountingListCount = 0;
for (i = 0, j = 0; i < count && j < maxKexts; ++i) {
aKext = OSDynamicCast(OSKext, sLoadedKexts->getObject(i));
- if (!aKext || (!aKext->isExecutable() && !aKext->isSpecialKernelBinary())) {
+ if (!aKext || !aKext->isExecutable()) {
continue;
}
@@ -16514,8 +15159,9 @@
*/
start = (vm_map_offset_t) summaryHeader;
-
- result = mach_vm_protect(kernel_map, start, summarySize, false, VM_PROT_READ);
+ end = start + summarySize;
+
+ result = vm_map_protect(kernel_map, start, end, VM_PROT_READ, FALSE);
if (result != KERN_SUCCESS) {
goto finish;
}
@@ -16532,12 +15178,12 @@
(*sLoadedKextSummariesUpdated)();
}
- lck_ticket_lock(sKextAccountsLock, sKextAccountsLockGrp);
+ IOSimpleLockLock(sKextAccountsLock);
prevAccountingList = sKextAccounts;
prevAccountingListCount = sKextAccountsCount;
sKextAccounts = accountingList;
sKextAccountsCount = accountingListCount;
- lck_ticket_unlock(sKextAccountsLock);
+ IOSimpleLockUnlock(sKextAccountsLock);
finish:
IOLockUnlock(sKextSummariesLock);
@@ -16590,16 +15236,6 @@
// Fallback to __TEXT
summary->text_exec_address = (uint64_t) getsegdatafromheader((kernel_mach_header_t *)summary->address, "__TEXT", &summary->text_exec_size);
}
-
- /**
- * If the addresses within the Mach-O are unslid, then manually slide any
- * addresses coming from the Mach-O as higher layer software using these
- * summaries expects a slid address here.
- */
- if (flags.unslidMachO) {
- summary->text_exec_address = (uint64_t) ml_static_slide((vm_offset_t) summary->text_exec_address);
- }
-
return;
}
@@ -16688,12 +15324,6 @@
return false;
}
-OSSharedPtr<OSDextStatistics>
-OSKext::copyDextStatistics(void)
-{
- return dextStatistics;
-}
-
bool
OSKextSavedMutableSegment::initWithSegment(kernel_segment_command_t *seg)
{
@@ -16704,8 +15334,7 @@
if (seg == nullptr) {
return false;
}
- result = kmem_alloc(kernel_map, (vm_offset_t *)&data, seg->vmsize,
- KMA_PAGEABLE, VM_KERN_MEMORY_KEXT);
+ result = kmem_alloc_pageable(kernel_map, (vm_offset_t *)&data, seg->vmsize, VM_KERN_MEMORY_KEXT);
if (result != KERN_SUCCESS) {
return false;
}
@@ -16783,7 +15412,7 @@
address = (uintptr_t)VM_KERNEL_STRIP_PTR(address);
#endif /* __has_feature(ptrauth_calls) */
- lck_ticket_lock(sKextAccountsLock, sKextAccountsLockGrp);
+ IOSimpleLockLock(sKextAccountsLock);
site = releasesite = NULL;
// bsearch sKextAccounts list
@@ -16802,7 +15431,7 @@
}
// else move left
}
- lck_ticket_unlock(sKextAccountsLock);
+ IOSimpleLockUnlock(sKextAccountsLock);
if (releasesite) {
kern_allocation_name_release(releasesite);
}
@@ -16822,7 +15451,7 @@
address = (uintptr_t)VM_KERNEL_STRIP_PTR(address);
#endif /* __has_feature(ptrauth_calls) */
- lck_ticket_lock(sKextAccountsLock, sKextAccountsLockGrp);
+ IOSimpleLockLock(sKextAccountsLock);
// bsearch sKextAccounts list
for (baseIdx = 0, lim = sKextAccountsCount; lim; lim >>= 1) {
@@ -16837,7 +15466,7 @@
}
// else move left
}
- lck_ticket_unlock(sKextAccountsLock);
+ IOSimpleLockUnlock(sKextAccountsLock);
}
#endif /* DEVELOPMENT || DEBUG */
@@ -16888,135 +15517,17 @@
}
#endif
-
-
-class OSDextCrash : public OSObject {
- OSDeclareDefaultStructors(OSDextCrash);
-public:
- static OSPtr<OSDextCrash> withTimestamp(uint64_t timestamp);
- uint64_t getTimestamp();
-
-private:
- virtual bool initWithTimestamp(uint64_t timestamp);
- uint64_t fTimestamp;
-};
-
-OSDefineMetaClassAndStructors(OSDextCrash, OSObject);
-
-OSSharedPtr<OSDextCrash>
-OSDextCrash::withTimestamp(uint64_t timestamp)
-{
- OSSharedPtr<OSDextCrash> result = OSMakeShared<OSDextCrash>();
- if (!result->initWithTimestamp(timestamp)) {
- return NULL;
- }
- return result;
-}
-
-bool
-OSDextCrash::initWithTimestamp(uint64_t timestamp)
-{
- if (!OSObject::init()) {
- return false;
- }
- fTimestamp = timestamp;
- return true;
-}
-
-uint64_t
-OSDextCrash::getTimestamp()
-{
- return fTimestamp;
-}
-
-OSSharedPtr<OSDextStatistics>
-OSDextStatistics::create()
-{
- OSSharedPtr<OSDextStatistics> result = OSMakeShared<OSDextStatistics>();
- if (!result->init()) {
- return NULL;
- }
- return result;
-}
-
-bool
-OSDextStatistics::init()
-{
- if (!OSObject::init()) {
- return false;
- }
-
- lock = IOLockAlloc();
- crashes = OSArray::withCapacity(kMaxDextCrashesInOneDay);
- return true;
-}
-
-void
-OSDextStatistics::free()
-{
- if (lock) {
- IOLockFree(lock);
- }
- crashes.reset();
- OSObject::free();
-}
-
-OSDextCrashPolicy
-OSDextStatistics::recordCrash()
-{
- size_t i = 0;
- uint64_t timestamp = mach_continuous_time();
- uint64_t interval;
- nanoseconds_to_absolutetime(86400 * NSEC_PER_SEC /* 1 day */, &interval);
- uint64_t lastTimestamp = timestamp > interval ? timestamp - interval : 0;
- OSDextCrashPolicy policy;
-
- IOLockLock(lock);
- OSSharedPtr<OSDextCrash> crash = OSDextCrash::withTimestamp(timestamp);
- for (i = 0; i < crashes->getCount();) {
- OSDextCrash * current = OSDynamicCast(OSDextCrash, crashes->getObject(i));
- assert(current != NULL);
- if (current->getTimestamp() < lastTimestamp) {
- crashes->removeObject(i);
- } else {
- i++;
- }
- }
-
- crashes->setObject(crash);
-
- if (crashes->getCount() > kMaxDextCrashesInOneDay) {
- policy = kOSDextCrashPolicyReboot;
- } else {
- policy = kOSDextCrashPolicyNone;
- }
-
- IOLockUnlock(lock);
-
- return policy;
-}
-
-size_t
-OSDextStatistics::getCrashCount()
-{
- size_t result = 0;
- IOLockLock(lock);
- result = crashes->getCount();
- IOLockUnlock(lock);
- return result;
-}
-
static int
sysctl_willuserspacereboot
(__unused struct sysctl_oid *oidp, __unused void *arg1, __unused int arg2, struct sysctl_req *req)
{
- int new_value = 0, old_value = get_system_inuserspacereboot(), changed = 0;
+ int new_value = 0, old_value = 0, changed = 0;
int error = sysctl_io_number(req, old_value, sizeof(int), &new_value, &changed);
if (error) {
return error;
}
if (changed) {
- OSKext::setWillUserspaceReboot();
+ OSKext::willUserspaceReboot();
}
return 0;
}