Loading...
--- 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 *