Loading...
iokit/bsddev/IOKitBSDInit.cpp xnu-12377.101.15 xnu-8019.41.5
--- xnu/xnu-12377.101.15/iokit/bsddev/IOKitBSDInit.cpp
+++ xnu/xnu-8019.41.5/iokit/bsddev/IOKitBSDInit.cpp
@@ -39,7 +39,6 @@
 extern "C" {
 #include <libkern/amfi/amfi.h>
 #include <sys/codesign.h>
-#include <sys/code_signing.h>
 #include <vm/pmap.h>
 #include <vm/vm_map.h>
 #include <pexpert/pexpert.h>
@@ -51,10 +50,6 @@
 #include <uuid/uuid.h>
 #include <sys/vnode_internal.h>
 #include <sys/mount.h>
-#include <corecrypto/ccsha2.h>
-#include <kdp/sk_core.h>
-#include <pexpert/device_tree.h>
-#include <kern/startup.h>
 
 // how long to wait for matching root device, secs
 #if DEBUG
@@ -83,8 +78,6 @@
 #define kIOCoreDumpPath         "/private/var/vm/kernelcore"
 #endif
 
-#define kIOCoreDumpPrebootPath      "/private/preboot/kernelcore"
-
 #define SYSTEM_NVRAM_PREFIX     "40A0DDD2-77F8-4392-B4A3-1E7304206516:"
 
 #if CONFIG_KDP_INTERACTIVE_DEBUGGING
@@ -107,10 +100,8 @@
 
 #if IOPOLLED_COREFILE
 static void IOOpenPolledCoreFile(thread_call_param_t __unused, thread_call_param_t corefilename);
-static void IOResolveCoreFilePath();
 
 thread_call_t corefile_open_call = NULL;
-SECURITY_READ_ONLY_LATE(const char*) kdp_corefile_path = kIOCoreDumpPath;
 #endif
 
 kern_return_t
@@ -227,19 +218,7 @@
 OSDictionary *
 IOUUIDMatching( void )
 {
-	OSObject     * obj;
-	OSDictionary * result;
-
-	obj = OSUnserialize(
-		"{"
-		"'IOProviderClass' = 'IOResources';"
-		"'IOResourceMatch' = ('IOBSD', 'boot-uuid-media');"
-		"}",
-		NULL);
-	result = OSDynamicCast(OSDictionary, obj);
-	assert(result);
-
-	return result;
+	return IOService::resourceMatching( "boot-uuid-media" );
 }
 
 OSDictionary *
@@ -541,37 +520,6 @@
 	return result;
 }
 
-
-bool
-IOGetBootManifestHash(char *hash_data, size_t *hash_data_size)
-{
-	IORegistryEntry *entry = NULL;
-	OSData *manifest_hash_data = NULL;
-	bool result = false;
-
-	if ((entry = IORegistryEntry::fromPath("/chosen", gIODTPlane))) {
-		manifest_hash_data = (OSData *)entry->getProperty("boot-manifest-hash");
-		if (manifest_hash_data) {
-			unsigned int length = manifest_hash_data->getLength();
-			/* hashed with SHA2-384 or SHA1, the boot manifest hash should be 48 Bytes or less */
-			if ((length <= CCSHA384_OUTPUT_SIZE) && (*hash_data_size >= CCSHA384_OUTPUT_SIZE)) {
-				/* ensure caller's buffer is fully initialized: */
-				bzero(hash_data, CCSHA384_OUTPUT_SIZE);
-				/* copy the content of manifest_hash_data->getBytesNoCopy() into hash_data */
-				memcpy(hash_data, manifest_hash_data->getBytesNoCopy(), length);
-				*hash_data_size = length;
-				result = true;
-			} else {
-				hash_data = NULL;
-				*hash_data_size = 0;
-			}
-		}
-		OSSafeReleaseNULL(entry);
-	}
-
-	return result;
-}
-
 /*
  * Set NVRAM to boot into the right flavor of Recovery,
  * optionally passing a UUID of a volume that failed to boot.
@@ -664,15 +612,30 @@
 
 	if (reboot) {
 		IOLog("\nAbout to reboot into Recovery!\n");
-		// Mitigation for SEP hanging on kPERestartCPU (radar://164664790).
-		// We panic and on the next boot we should land into recovery.
-		// This should be reverted back to calling
-		// PEHaltRestart(kPERestartCPU) in rdar://169561102.
-		panic("Reboot into Recovery (this panic is expected)");
-		// (void)PEHaltRestart(kPERestartCPU);
+		(void)PEHaltRestart(kPERestartCPU);
 	}
 
 	return true;
+}
+
+int
+IOGetVMMPresent(void)
+{
+	int hv_vmm_present = 0;
+
+#if defined(__arm64__)
+	if (IODTGetDefault("vmm-present", &hv_vmm_present, sizeof(hv_vmm_present)) < 0) {
+		return 0;
+	}
+
+	if (hv_vmm_present != 0) {
+		hv_vmm_present = 1;
+	}
+#elif defined(__x86_64__)
+	hv_vmm_present = cpuid_vmm_present();
+#endif
+
+	return hv_vmm_present;
 }
 
 kern_return_t
@@ -694,7 +657,6 @@
 	OSDataAllocation<char> str;
 	const char *        look = NULL;
 	int                 len;
-	int                 wdt = 0;
 	bool                debugInfoPrintedOnce = false;
 	bool                needNetworkKexts = false;
 	const char *        uuidStr = NULL;
@@ -778,11 +740,7 @@
 			data = (OSData *)regEntry->getProperty("RAMDisk");      /* Find the ram disk, if there */
 			if (data) {                                                                                      /* We found one */
 				uintptr_t *ramdParms;
-				/* BEGIN IGNORE CODESTYLE */
-				__typed_allocators_ignore_push
 				ramdParms = (uintptr_t *)data->getBytesNoCopy();        /* Point to the ram disk base and size */
-				__typed_allocators_ignore_pop
-				/* END IGNORE CODESTYLE */
 #if __LP64__
 #define MAX_PHYS_RAM    (((uint64_t)UINT_MAX) << 12)
 				if (ramdParms[1] > MAX_PHYS_RAM) {
@@ -876,7 +834,6 @@
 		// Match any HFS media
 
 		matching = IOService::serviceMatching( "IOMedia" );
-		assert(matching);
 		astring = OSString::withCStringNoCopy("Apple_HFS");
 		if (astring) {
 			matching->setObject("Content", astring);
@@ -904,13 +861,12 @@
 		IOService::startDeferredMatches();
 	}
 
-	PE_parse_boot_argn("wdt", &wdt, sizeof(wdt));
 	do {
 		t.tv_sec = ROOTDEVICETIMEOUT;
 		t.tv_nsec = 0;
 		matching->retain();
 		service = IOService::waitForService( matching, &t );
-		if ((-1 != wdt) && (!service || (mountAttempts == 10))) {
+		if ((!service) || (mountAttempts == 10)) {
 #if !XNU_TARGET_OS_OSX || !defined(__arm64__)
 			PE_display_icon( 0, "noroot");
 			IOLog( "Still waiting for root device\n" );
@@ -934,8 +890,6 @@
 #if XNU_TARGET_OS_OSX && defined(__arm64__)
 			// The disk isn't found - have the user pick from System Recovery.
 			(void)IOSetRecoveryBoot(BSD_BOOTFAIL_MEDIA_MISSING, NULL, true);
-#elif XNU_TARGET_OS_IOS || XNU_TARGET_OS_XR
-			panic("Failed to mount root device");
 #endif
 		}
 	} while (!service);
@@ -1122,21 +1076,11 @@
 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
 
 #include <sys/conf.h>
-#include <sys/lock.h>
 #include <sys/vnode.h>
-#include <sys/vnode_if.h>
 #include <sys/vnode_internal.h>
 #include <sys/fcntl.h>
-#include <sys/fsctl.h>
-#include <sys/mount.h>
 #include <IOKit/IOPolledInterface.h>
 #include <IOKit/IOBufferMemoryDescriptor.h>
-
-// see HFSIOC_VOLUME_STATUS in APFS/HFS
-#define HFS_IOCTL_VOLUME_STATUS _IOR('h', 24, u_int32_t)
-
-LCK_GRP_DECLARE(gIOPolledCoreFileGrp, "polled_corefile");
-LCK_MTX_DECLARE(gIOPolledCoreFileMtx, &gIOPolledCoreFileGrp);
 
 IOPolledFileIOVars * gIOPolledCoreFileVars;
 kern_return_t gIOPolledCoreFileOpenRet = kIOReturnNotReady;
@@ -1144,44 +1088,31 @@
 
 #if IOPOLLED_COREFILE
 
-#define ONE_MB                  1024ULL * 1024ULL
-
 #if defined(XNU_TARGET_OS_BRIDGE)
 // On bridgeOS allocate a 150MB corefile and leave 150MB free
-#define kIOCoreDumpSize         150ULL * ONE_MB
-#define kIOCoreDumpFreeSize     150ULL * ONE_MB
-
-#elif defined(XNU_TARGET_OS_OSX)
-
+#define kIOCoreDumpSize         150ULL*1024ULL*1024ULL
+#define kIOCoreDumpFreeSize     150ULL*1024ULL*1024ULL
+
+#elif !defined(XNU_TARGET_OS_OSX) /* defined(XNU_TARGET_OS_BRIDGE) */
+// On embedded devices with >3GB DRAM we allocate a 500MB corefile
+// otherwise allocate a 350MB corefile. Leave 350 MB free
+
+#define kIOCoreDumpMinSize      350ULL*1024ULL*1024ULL
+#define kIOCoreDumpLargeSize    500ULL*1024ULL*1024ULL
+
+#define kIOCoreDumpFreeSize     350ULL*1024ULL*1024ULL
+
+#else /* defined(XNU_TARGET_OS_BRIDGE) */
 // on macOS devices allocate a corefile sized at 1GB / 32GB of DRAM,
 // fallback to a 1GB corefile and leave at least 1GB free
-#define kIOCoreDumpMinSize              1024ULL * ONE_MB
-#define kIOCoreDumpIncrementalSize      1024ULL * ONE_MB
-
-#define kIOCoreDumpFreeSize     1024ULL * ONE_MB
+#define kIOCoreDumpMinSize              1024ULL*1024ULL*1024ULL
+#define kIOCoreDumpIncrementalSize      1024ULL*1024ULL*1024ULL
+
+#define kIOCoreDumpFreeSize     1024ULL*1024ULL*1024ULL
 
 // on older macOS devices we allocate a 1MB file at boot
 // to store a panic time stackshot
-#define kIOStackshotFileSize    ONE_MB
-
-#elif defined(XNU_TARGET_OS_XR)
-
-// XR OS requries larger corefile storage because XNU core can take
-// up to ~500MB.
-
-#define kIOCoreDumpMinSize      350ULL * ONE_MB
-#define kIOCoreDumpLargeSize    750ULL * ONE_MB
-
-#define kIOCoreDumpFreeSize     350ULL * ONE_MB
-
-#else /* defined(XNU_TARGET_OS_BRIDGE) */
-
-// On embedded devices with >3GB DRAM we allocate a 500MB corefile
-// otherwise allocate a 350MB corefile. Leave 350 MB free
-#define kIOCoreDumpMinSize      350ULL * ONE_MB
-#define kIOCoreDumpLargeSize    500ULL * ONE_MB
-
-#define kIOCoreDumpFreeSize     350ULL * ONE_MB
+#define kIOStackshotFileSize    1024ULL*1024ULL
 
 #endif /* defined(XNU_TARGET_OS_BRIDGE) */
 
@@ -1198,65 +1129,11 @@
 }
 
 static void
-IOResolveCoreFilePath()
-{
-	DTEntry node;
-	const char *value = NULL;
-	unsigned int size = 0;
-
-	if (kSuccess != SecureDTLookupEntry(NULL, "/product", &node)) {
-		return;
-	}
-	if (kSuccess != SecureDTGetProperty(node, "kernel-core-dump-location", (void const **) &value, &size)) {
-		return;
-	}
-	if (size == 0) {
-		return;
-	}
-
-	// The kdp_corefile_path is allowed to be one of 2 options to working locations.
-	// This value is set on EARLY_BOOT since we need to know it before any volumes are mounted. The mount
-	// event triggers IOOpenPolledCoreFile() which opens the file. Once we commit to using the path from EDT
-	// we can't back out since a different path may reside in a different volume.
-	// In case the path from EDT can't be opened, there will not be a kernel core-dump
-	if (strlcmp(value, "preboot", size) == 0) {
-		kdp_corefile_path = kIOCoreDumpPrebootPath;
-	} else if (strlcmp(value, "default", size) != 0) {
-		IOLog("corefile path selection in device-tree is not one of the allowed values: %s, Using default %s\n", value, kdp_corefile_path);
-		return;
-	}
-
-	IOLog("corefile path selection in device-tree was set to: %s (value: %s)\n", kdp_corefile_path, value);
-}
-STARTUP(EARLY_BOOT, STARTUP_RANK_MIDDLE, IOResolveCoreFilePath);
-
-static void
 IOCoreFileGetSize(uint64_t *ideal_size, uint64_t *fallback_size, uint64_t *free_space_to_leave, IOPolledCoreFileMode_t mode)
 {
 	unsigned int requested_corefile_size = 0;
 
 	*ideal_size = *fallback_size = *free_space_to_leave = 0;
-
-	// If a custom size was requested, override the ideal and requested sizes
-	if (PE_parse_boot_argn("corefile_size_mb", &requested_corefile_size,
-	    sizeof(requested_corefile_size))) {
-		IOLog("Boot-args specify %d MB kernel corefile\n", requested_corefile_size);
-
-		*ideal_size = *fallback_size = (requested_corefile_size * ONE_MB);
-		return;
-	}
-
-	unsigned int status_flags = 0;
-	int error = VNOP_IOCTL(rootvnode, HFS_IOCTL_VOLUME_STATUS, (caddr_t)&status_flags, 0,
-	    vfs_context_kernel());
-	if (!error) {
-		if (status_flags & (VQ_VERYLOWDISK | VQ_LOWDISK | VQ_NEARLOWDISK)) {
-			IOLog("Volume is low on space. Not allocating kernel corefile.\n");
-			return;
-		}
-	} else {
-		IOLog("Couldn't retrieve volume status. Error %d\n", error);
-	}
 
 #if defined(XNU_TARGET_OS_BRIDGE)
 #pragma unused(mode)
@@ -1266,7 +1143,7 @@
 #pragma unused(mode)
 	*ideal_size = *fallback_size = kIOCoreDumpMinSize;
 
-	if (max_mem > (3 * 1024ULL * ONE_MB)) {
+	if (max_mem > (3 * 1024ULL * 1024ULL * 1024ULL)) {
 		*ideal_size = kIOCoreDumpLargeSize;
 	}
 
@@ -1274,18 +1151,20 @@
 #else /* defined(XNU_TARGET_OS_BRIDGE) */
 	if (mode == kIOPolledCoreFileModeCoredump) {
 		*ideal_size = *fallback_size = kIOCoreDumpMinSize;
-		if (kIOCoreDumpIncrementalSize != 0 && max_mem > (32 * 1024ULL * ONE_MB)) {
-			*ideal_size = ((ROUNDUP(max_mem, (32 * 1024ULL * ONE_MB)) / (32 * 1024ULL * ONE_MB)) * kIOCoreDumpIncrementalSize);
+		if (kIOCoreDumpIncrementalSize != 0 && max_mem > (32 * 1024ULL * 1024ULL * 1024ULL)) {
+			*ideal_size = ((ROUNDUP(max_mem, (32 * 1024ULL * 1024ULL * 1024ULL)) / (32 * 1024ULL * 1024ULL * 1024ULL)) * kIOCoreDumpIncrementalSize);
 		}
 		*free_space_to_leave = kIOCoreDumpFreeSize;
 	} else if (mode == kIOPolledCoreFileModeStackshot) {
 		*ideal_size = *fallback_size = *free_space_to_leave = kIOStackshotFileSize;
 	}
 #endif /* defined(XNU_TARGET_OS_BRIDGE) */
-
-#if EXCLAVES_COREDUMP
-	*ideal_size += sk_core_size();
-#endif /* EXCLAVES_COREDUMP */
+	// If a custom size was requested, override the ideal and requested sizes
+	if (PE_parse_boot_argn("corefile_size_mb", &requested_corefile_size, sizeof(requested_corefile_size))) {
+		IOLog("Boot-args specify %d MB kernel corefile\n", requested_corefile_size);
+
+		*ideal_size = *fallback_size = (requested_corefile_size * 1024ULL * 1024ULL);
+	}
 
 	return;
 }
@@ -1326,10 +1205,6 @@
 		return;
 	}
 
-	if (gIOPolledCoreFileMode == kIOPolledCoreFileModeUnlinked) {
-		return;
-	}
-
 	if (mode_to_init == kIOPolledCoreFileModeDisabled) {
 		gIOPolledCoreFileMode = kIOPolledCoreFileModeDisabled;
 		return;
@@ -1341,19 +1216,13 @@
 
 	IOCoreFileGetSize(&corefile_size_bytes, &corefile_fallback_size_bytes, &free_space_to_leave_bytes, mode_to_init);
 
-	if (corefile_size_bytes == 0 && corefile_fallback_size_bytes == 0) {
-		gIOPolledCoreFileMode = kIOPolledCoreFileModeUnlinked;
-		return;
-	}
-
 	do {
-		// This file reference remains open long-term in case we need to write a core-dump
-		err = IOPolledFileOpen(filename, kIOPolledFileCreate, 0 /*setFileSizeMin*/, corefile_size_bytes, free_space_to_leave_bytes,
+		err = IOPolledFileOpen(filename, kIOPolledFileCreate, corefile_size_bytes, free_space_to_leave_bytes,
 		    NULL, 0, &gIOPolledCoreFileVars, NULL, NULL, NULL);
 		if (kIOReturnSuccess == err) {
 			break;
 		} else if (kIOReturnNoSpace == err) {
-			IOLog("Failed to open corefile of size %llu MB (low disk space)\n",
+			IOLog("Failed to open corefile of size %llu MB (low disk space)",
 			    (corefile_size_bytes / (1024ULL * 1024ULL)));
 			if (corefile_size_bytes == corefile_fallback_size_bytes) {
 				gIOPolledCoreFileOpenRet = err;
@@ -1366,7 +1235,7 @@
 			return;
 		}
 
-		err = IOPolledFileOpen(filename, kIOPolledFileCreate, 0 /*setFileSizeMin*/, corefile_fallback_size_bytes, free_space_to_leave_bytes,
+		err = IOPolledFileOpen(filename, kIOPolledFileCreate, corefile_fallback_size_bytes, free_space_to_leave_bytes,
 		    NULL, 0, &gIOPolledCoreFileVars, NULL, NULL, NULL);
 		if (kIOReturnSuccess != err) {
 			IOLog("Failed to open corefile of size %llu MB (returned error 0x%x)\n",
@@ -1378,7 +1247,7 @@
 
 	gIOPolledCoreFileOpenRet = IOPolledFilePollersSetup(gIOPolledCoreFileVars, kIOPolledPreflightCoreDumpState);
 	if (kIOReturnSuccess != gIOPolledCoreFileOpenRet) {
-		IOPolledFileClose(&gIOPolledCoreFileVars, 0, NULL, 0, 0, 0, false);
+		IOPolledFileClose(&gIOPolledCoreFileVars, 0, NULL, 0, 0, 0);
 		IOLog("IOPolledFilePollersSetup for corefile failed with error: 0x%x\n", err);
 	} else {
 		IOLog("Opened corefile of size %llu MB\n", (corefile_size_bytes / (1024ULL * 1024ULL)));
@@ -1409,7 +1278,7 @@
 
 	// Open the kernel corefile
 	vfs_context = vfs_context_kernel();
-	vnode_error = vnode_open(kdp_corefile_path, (FREAD | FWRITE | O_NOFOLLOW), 0600, 0, &vnode_ptr, vfs_context);
+	vnode_error = vnode_open(kIOCoreDumpPath, (FREAD | FWRITE | O_NOFOLLOW), 0600, 0, &vnode_ptr, vfs_context);
 	if (vnode_error) {
 		IOLog("Failed to open the corefile. Error %d\n", vnode_error);
 		return kIOReturnError;
@@ -1433,19 +1302,7 @@
 	gIOPolledCoreFileOpenRet = kIOReturnNotOpen;
 	gIOPolledCoreFileMode = kIOPolledCoreFileModeClosed;
 	IOPolledFilePollersClose(gIOPolledCoreFileVars, kIOPolledPostflightCoreDumpState);
-	IOPolledFileClose(&gIOPolledCoreFileVars, 0, NULL, 0, 0, 0, false);
-}
-
-static void
-IOUnlinkPolledCoreFile(void)
-{
-	// Notify kdp core that the corefile is no longer available
-	(void) kdp_core_polled_io_polled_file_unavailable();
-
-	gIOPolledCoreFileOpenRet = kIOReturnNotOpen;
-	gIOPolledCoreFileMode = kIOPolledCoreFileModeUnlinked;
-	IOPolledFilePollersClose(gIOPolledCoreFileVars, kIOPolledPostflightCoreDumpState);
-	IOPolledFileClose(&gIOPolledCoreFileVars, 0, NULL, 0, 0, 0, true);
+	IOPolledFileClose(&gIOPolledCoreFileVars, 0, NULL, 0, 0, 0);
 }
 
 #endif /* IOPOLLED_COREFILE */
@@ -1460,8 +1317,6 @@
 	vnode_t vn;
 	int result;
 
-	lck_mtx_lock(&gIOPolledCoreFileMtx);
-
 	switch (op) {
 	case kIOMountChangeMount:
 	case kIOMountChangeDidResize:
@@ -1498,12 +1353,11 @@
 			break;
 		}
 #endif
-		// Does this mount point include the kernel core-file?
-		if (0 != strncmp(path, kdp_corefile_path, pathLen - 1)) {
+		if (0 != strncmp(path, kIOCoreDumpPath, pathLen - 1)) {
 			break;
 		}
 
-		thread_call_enter1(corefile_open_call, (void *) kdp_corefile_path);
+		thread_call_enter1(corefile_open_call, (void *) kIOCoreDumpPath);
 		break;
 
 	case kIOMountChangeUnmount:
@@ -1514,258 +1368,76 @@
 		}
 		break;
 	}
-
-	lck_mtx_unlock(&gIOPolledCoreFileMtx);
 #endif /* IOPOLLED_COREFILE */
 }
 
-extern "C" void
-IOBSDLowSpaceUnlinkKernelCore(void)
-{
-#if IOPOLLED_COREFILE
-	lck_mtx_lock(&gIOPolledCoreFileMtx);
-	if (gIOPolledCoreFileVars) {
-		thread_call_cancel_wait(corefile_open_call);
-		IOUnlinkPolledCoreFile();
-	}
-	lck_mtx_unlock(&gIOPolledCoreFileMtx);
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+
+extern "C"
+OS_ALWAYS_INLINE
+boolean_t
+IOCurrentTaskHasEntitlement(const char * entitlement)
+{
+	return IOTaskHasEntitlement(NULL, entitlement);
+}
+
+extern "C" boolean_t
+IOTaskHasEntitlement(task_t task, const char * entitlement)
+{
+	// Don't do this
+	if (task == kernel_task || entitlement == NULL) {
+		return false;
+	}
+	size_t entlen = strlen(entitlement);
+	CEQuery_t query = {
+		CESelectDictValueDynamic((const uint8_t*)entitlement, entlen),
+		CEMatchBool(true)
+	};
+
+#if PMAP_CS_ENABLE && !CONFIG_X86_64_COMPAT
+	if (pmap_cs_enabled()) {
+		if (task == NULL || task == current_task()) {
+			// NULL task means current task, which translated to the current pmap
+			return pmap_query_entitlements(NULL, query, 2, NULL);
+		}
+		vm_map_t task_map = get_task_map_reference(task);
+		if (task_map) {
+			pmap_t pmap = vm_map_get_pmap(task_map);
+			if (pmap && pmap_query_entitlements(pmap, query, 2, NULL)) {
+				vm_map_deallocate(task_map);
+				return true;
+			}
+			vm_map_deallocate(task_map);
+		}
+		return false;
+	}
 #endif
-}
-
-/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
-
-static char*
-copyOSStringAsCString(OSString *string)
-{
-	size_t string_length = 0;
-	char *c_string = NULL;
-
-	if (string == NULL) {
-		return NULL;
-	}
-	string_length = string->getLength() + 1;
-
-	/* Allocate kernel data memory for the string */
-	c_string = (char*)kalloc_data(string_length, (zalloc_flags_t)(Z_ZERO | Z_WAITOK | Z_NOFAIL));
-	assert(c_string != NULL);
-
-	/* Copy in the string */
-	strlcpy(c_string, string->getCStringNoCopy(), string_length);
-
-	return c_string;
-}
-
-extern "C" OS_ALWAYS_INLINE boolean_t
-IOCurrentTaskHasStringEntitlement(const char *entitlement, const char *value)
-{
-	return IOTaskHasStringEntitlement(NULL, entitlement, value);
-}
-
-extern "C" boolean_t
-IOTaskHasStringEntitlement(task_t task, const char *entitlement, const char *value)
-{
 	if (task == NULL) {
 		task = current_task();
 	}
 
-	/* Validate input arguments */
-	if (task == kernel_task || entitlement == NULL || value == NULL) {
+	proc_t p = (proc_t)get_bsdtask_info(task);
+
+	if (p == NULL) {
 		return false;
 	}
-	proc_t proc = (proc_t)get_bsdtask_info(task);
-
-	if (proc == NULL) {
+
+	struct cs_blob* csblob = csproc_get_blob(p);
+	if (csblob == NULL) {
 		return false;
 	}
 
-	kern_return_t ret = amfi->OSEntitlements.queryEntitlementStringWithProc(
-		proc,
-		entitlement,
-		value);
-
-	if (ret == KERN_SUCCESS) {
-		return true;
-	}
-
-	return false;
-}
-
-extern "C" OS_ALWAYS_INLINE boolean_t
-IOCurrentTaskHasEntitlement(const char *entitlement)
-{
-	return IOTaskHasEntitlement(NULL, entitlement);
-}
-
-/*
- * Reminder to reader: This only returns `true` if:
- *  - The entitlement is boolean-valued
- *  - The value is `true`
- * If you are looking to check whether an entitlement is present,
- * you likely want `IOVnodeIsEntitlementPresentWithAnyValue`
- * or `IOTaskHasEntitlementAsBooleanOrObject` (caveat emptor).
- */
-extern "C" boolean_t
-IOTaskHasEntitlement(task_t task, const char *entitlement)
-{
-	if (task == NULL) {
-		task = current_task();
-	}
-
-	/* Validate input arguments */
-	if (task == kernel_task || entitlement == NULL) {
+	void* osents = csblob_os_entitlements_get(csblob);
+	if (osents == NULL) {
 		return false;
 	}
-	proc_t proc = (proc_t)get_bsdtask_info(task);
-
-	if (proc == NULL) {
-		return false;
-	}
-
-	kern_return_t ret = amfi->OSEntitlements.queryEntitlementBooleanWithProc(
-		proc,
-		entitlement);
-
-	if (ret == KERN_SUCCESS) {
-		return true;
-	}
-
-	return false;
-}
-
-extern "C" boolean_t
-IOTaskGetIntegerEntitlement(task_t task, const char *entitlement, uint64_t *value)
-{
-	void *entitlement_object = NULL;
-
-	if (task == NULL) {
-		task = current_task();
-	}
-
-	/* Validate input arguments */
-	if (task == kernel_task || entitlement == NULL || value == NULL) {
-		return false;
-	}
-	proc_t proc = (proc_t)get_bsdtask_info(task);
-
-	if (proc == NULL) {
-		return false;
-	}
-
-	kern_return_t ret = amfi->OSEntitlements.copyEntitlementAsOSObjectWithProc(
-		proc,
-		entitlement,
-		&entitlement_object);
-
-	if (ret != KERN_SUCCESS) {
-		return false;
-	}
-	assert(entitlement_object != NULL);
-
-	OSObject *os_object = (OSObject*)entitlement_object;
-	OSNumber *os_number = OSDynamicCast(OSNumber, os_object);
-
-	boolean_t has_entitlement = os_number != NULL;
-	if (has_entitlement) {
-		*value = os_number->unsigned64BitValue();
-	}
-
-	/* Free the OSObject which was given to us */
-	OSSafeReleaseNULL(os_object);
-
-	return has_entitlement;
-}
-
-extern "C" OS_ALWAYS_INLINE char*
-IOCurrentTaskGetEntitlement(const char *entitlement)
-{
-	return IOTaskGetEntitlement(NULL, entitlement);
-}
-
-extern "C" char*
-IOTaskGetEntitlement(task_t task, const char *entitlement)
-{
-	void *entitlement_object = NULL;
-	char *return_value = NULL;
-
-	if (task == NULL) {
-		task = current_task();
-	}
-
-	/* Validate input arguments */
-	if (task == kernel_task || entitlement == NULL) {
-		return NULL;
-	}
-	proc_t proc = (proc_t)get_bsdtask_info(task);
-
-	if (proc == NULL) {
-		return NULL;
-	}
-
-	kern_return_t ret = amfi->OSEntitlements.copyEntitlementAsOSObjectWithProc(
-		proc,
-		entitlement,
-		&entitlement_object);
-
-	if (ret != KERN_SUCCESS) {
-		return NULL;
-	}
-	assert(entitlement_object != NULL);
-
-	OSObject *os_object = (OSObject*)entitlement_object;
-	OSString *os_string = OSDynamicCast(OSString, os_object);
-
-	/* Get a C string version of the OSString */
-	return_value = copyOSStringAsCString(os_string);
-
-	/* Free the OSObject which was given to us */
-	OSSafeReleaseNULL(os_object);
-
-	return return_value;
-}
-
-extern "C" boolean_t
-IOTaskHasEntitlementAsBooleanOrObject(task_t task, const char *entitlement)
-{
-	if (task == NULL) {
-		task = current_task();
-	}
-
-	/* Validate input arguments */
-	if (task == kernel_task || entitlement == NULL) {
-		return false;
-	}
-	proc_t proc = (proc_t)get_bsdtask_info(task);
-
-	if (proc == NULL) {
-		return false;
-	}
-
-	kern_return_t ret = amfi->OSEntitlements.queryEntitlementBooleanWithProc(
-		proc,
-		entitlement);
-	if (ret == KERN_SUCCESS) {
-		return true;
-	}
-
-	/* Check for the presence of an object */
-	void *entitlement_object = NULL;
-	ret = amfi->OSEntitlements.copyEntitlementAsOSObjectWithProc(
-		proc,
-		entitlement,
-		&entitlement_object);
-	if (ret != KERN_SUCCESS) {
-		return false;
-	}
-	assert(entitlement_object != NULL);
-
-	OSObject *os_object = (OSObject*)entitlement_object;
-
-	bool not_false_entitlement = (os_object != kOSBooleanFalse);
-
-	/* Free the OSObject which was given to us */
-	OSSafeReleaseNULL(os_object);
-
-	return not_false_entitlement;
+
+	if (!amfi) {
+		panic("CoreEntitlements: (IOTask): No AMFI\n");
+	}
+
+	return amfi->OSEntitlements_query(osents, (uint8_t*)csblob_get_cdhash(csblob), query, 2) == amfi->CoreEntitlements.kNoError;
 }
 
 extern "C" boolean_t
@@ -1780,83 +1452,6 @@
 	}
 	obj->release();
 	return obj != kOSBooleanFalse;
-}
-
-extern "C" boolean_t
-IOVnodeIsEntitlementPresentWithAnyValue(vnode_t vnode, int64_t off, const char *entitlement)
-{
-	OSObject * obj;
-	off_t offset = (off_t)off;
-
-	obj = IOUserClient::copyClientEntitlementVnode(vnode, offset, entitlement);
-	if (!obj) {
-		return false;
-	}
-	obj->release();
-	return true;
-}
-
-/*
- * Support querying an OSBoolean entitlement value,
- * while distinguishing between the following cases:
- *     - the entitlement does not exist.
- *     - the entitlement exists with a value of false.
- *     - the entitlement exists with a value of true.
- *
- * Return value:
- *     - false if the entitlement does not exist.
- *     - true if the entitlement exists.
- *
- * If the return value is true, the `value` argument will
- * hold the entitlement value, which has to be Boolean.
- */
-extern "C" boolean_t
-IOVnodeGetBooleanEntitlement(
-	vnode_t vnode,
-	int64_t off,
-	const char *entitlement,
-	bool *value)
-{
-	OSObject * obj;
-	off_t offset = (off_t)off;
-
-	obj = IOUserClient::copyClientEntitlementVnode(vnode, offset, entitlement);
-	if (!obj) {
-		return false;
-	}
-
-	if (obj == kOSBooleanTrue) {
-		*value = true;
-	} else if (obj == kOSBooleanFalse) {
-		*value = false;
-	} else {
-		panic("%s: entitlement is not OSBoolean", __func__);
-	}
-
-	obj->release();
-	return true;
-}
-
-extern boolean_t
-IOVnodeGetIntegerEntitlement(struct vnode *vnode, int64_t off, const char *entitlement, uint64_t *value)
-{
-	OSObject *obj;
-	boolean_t ret = false;
-	off_t offset = (off_t)off;
-
-	obj = IOUserClient::copyClientEntitlementVnode(vnode, offset, entitlement);
-	if (!obj) {
-		return ret;
-	}
-
-	OSNumber *num = OSDynamicCast(OSNumber, obj);
-	if (num) {
-		*value = num->unsigned64BitValue();
-		ret = true;
-	}
-
-	obj->release();
-	return ret;
 }
 
 extern "C" char *