Loading...
libkern/c++/OSKext.cpp xnu-12377.101.15 xnu-10063.121.3
--- xnu/xnu-12377.101.15/libkern/c++/OSKext.cpp
+++ xnu/xnu-10063.121.3/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>
@@ -122,6 +120,7 @@
 
 extern unsigned long gVirtBase;
 extern unsigned long gPhysBase;
+extern vm_map_t g_kext_map;
 
 bool pageableKCloaded = false;
 bool auxKCloaded = false;
@@ -536,9 +535,10 @@
  * to automatically parse the list of loaded kexts.
  **********/
 static IOLock                 * sKextSummariesLock                = NULL;
+extern "C" lck_ticket_t         vm_allocation_sites_lock;
 extern "C" lck_grp_t            vm_page_lck_grp_bucket;
+static lck_ticket_t           * sKextAccountsLock = &vm_allocation_sites_lock;
 static lck_grp_t              * sKextAccountsLockGrp = &vm_page_lck_grp_bucket;
-#define sKextAccountsLock       (&vm_allocation_sites_lock)
 
 void(*const sLoadedKextSummariesUpdated)(void) = OSKextLoadedKextSummariesUpdated;
 OSKextLoadedKextSummaryHeader * gLoadedKextSummaries __attribute__((used)) = NULL;
@@ -552,7 +552,7 @@
 /*********************************************************************
  * sKextLoggingLock protects the logging variables declared immediately below.
  **********/
-__static_testable IOLock      * sKextLoggingLock           = NULL;
+static IOLock                 * sKextLoggingLock           = NULL;
 
 static  const OSKextLogSpec     kDefaultKernelLogFilter    = kOSKextLogBasicLevel |
     kOSKextLogVerboseFlagsMask;
@@ -1038,10 +1038,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
@@ -1222,7 +1222,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.
 	 */
@@ -1236,7 +1236,7 @@
 		ml_static_mfree(ml_static_ptovirt(seg_kld->vmaddr - gVirtBase + gPhysBase),
 		    seg_kld->vmsize);
 #else
-		ml_static_mfree(seg_kld->vmaddr, seg_kld->vmsize);
+		ml_static_mfree(seg_kld->vmaddr), seg_kld->vmsize);
 #endif
 	}
 #endif
@@ -1331,7 +1331,7 @@
 
 		/* 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,
@@ -1593,28 +1593,14 @@
 /*********************************************************************
 *********************************************************************/
 /* 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 */
-
+#if XNU_TARGET_OS_WATCH
+	return false;
+#else //!XNU_TARGET_OS_WATCH
 	return true;
+#endif //XNU_TARGET_OS_WATCH
 }
 
 /*********************************************************************
@@ -1623,13 +1609,10 @@
 bool
 OSKext::iokitDaemonAvailable(void)
 {
-#if XNU_TARGET_OS_XR || XNU_TARGET_OS_BRIDGE
 	int notused;
 	if (PE_parse_boot_argn("-restore", &notused, sizeof(notused))) {
 		return false;
 	}
-#endif /* XNU_TARGET_OS_XR || XNU_TARGET_OS_BRIDGE */
-
 	return driverkitEnabled();
 }
 
@@ -1696,10 +1679,10 @@
 }
 
 void
-OSKext::setWillUserspaceReboot(void)
+OSKext::willUserspaceReboot(void)
 {
 	OSKext::willShutdown();
-	IOService::setWillUserspaceReboot();
+	IOService::userSpaceWillReboot();
 	gIOCatalogue->terminateDriversForUserspaceReboot();
 }
 
@@ -1719,12 +1702,6 @@
 	OSKext::setKernelRequestsEnabled(true);
 	sOSKextWasResetAfterUserspaceReboot = true;
 	IORecursiveLockUnlock(sKextLock);
-}
-
-extern "C" int
-OSKextIsInUserspaceReboot(void)
-{
-	return IOService::getWillUserspaceReboot();
 }
 
 extern "C" void
@@ -3846,7 +3823,7 @@
 
 	if (KERN_SUCCESS != kmem_alloc(kernel_map,
 	    (vm_offset_t*)&uncompressedDataBuffer, fullSize,
-	    KMA_DATA_SHARED, VM_KERN_MEMORY_OSKEXT)) {
+	    KMA_DATA, VM_KERN_MEMORY_OSKEXT)) {
 		/* How's this for cheesy? The kernel is only asked to extract
 		 * kext plists so we tailor the log messages.
 		 */
@@ -4243,7 +4220,7 @@
 			logInfoLength = serializer->getLength();
 
 			kmem_result = kmem_alloc(kernel_map, (vm_offset_t *)&buffer, round_page(logInfoLength),
-			    KMA_DATA_SHARED, VM_KERN_MEMORY_OSKEXT);
+			    KMA_DATA, VM_KERN_MEMORY_OSKEXT);
 			if (kmem_result != KERN_SUCCESS) {
 				OSKextLog(/* kext */ NULL,
 				    kOSKextLogErrorLevel |
@@ -4393,8 +4370,7 @@
 #endif /* defined (__arm64__) */
 		}
 	}
-
-	if (kernel_text_contains(address)) {
+	if ((address >= vm_kernel_stext) && (address < vm_kernel_etext)) {
 		foundKext.reset(sKernelKext, OSRetain);
 		goto finish;
 	}
@@ -7908,13 +7884,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 +7897,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 +7923,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 +7936,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 +7967,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 +8005,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 +8035,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 +8048,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 +8060,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 |
@@ -10751,7 +10721,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), KMA_DATA, VM_KERN_MEMORY_OSKEXT);
 		if (kmem_result != KERN_SUCCESS) {
 			OSKextLog(/* kext */ NULL,
 			    kOSKextLogErrorLevel |
@@ -11089,30 +11059,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 +11200,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 +11208,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 +11231,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) {
@@ -12932,9 +12886,6 @@
 	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);
@@ -12987,10 +12938,7 @@
 		result = kOSKextReturnNoMemory;
 		goto finish;
 	}
-	result = OSKext::pingIOKitDaemon();
-	if (result != kOSReturnSuccess) {
-		goto finish;
-	}
+	OSKext::pingIOKitDaemon();
 
 	result = kOSReturnSuccess;
 finish:
@@ -13945,7 +13893,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 +13900,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 +13912,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;
@@ -15826,9 +15772,8 @@
 		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) {
+				kext = active->account->kext;
+				if (kext && kext->kmod_info) {
 					lck_ticket_unlock(sKextAccountsLock);
 					return (void *)kext->kmod_info->address;
 				}
@@ -16364,23 +16309,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 +16333,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;
@@ -16445,7 +16382,7 @@
 			sLoadedKextSummariesAllocSize = 0;
 		}
 		result = kmem_alloc(kernel_map, (vm_offset_t *)&summaryHeaderAlloc, size,
-		    KMA_NONE, VM_KERN_MEMORY_OSKEXT);
+		    KMA_DATA, VM_KERN_MEMORY_OSKEXT);
 		if (result != KERN_SUCCESS) {
 			goto finish;
 		}
@@ -16456,11 +16393,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;
 		}
@@ -16514,8 +16452,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;
 	}
@@ -17010,13 +16949,13 @@
 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;
 }