Loading...
--- xnu/xnu-12377.101.15/iokit/bsddev/IOKitBSDInit.cpp
+++ xnu/xnu-8792.81.2/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>
@@ -52,9 +51,6 @@
#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 +79,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 +101,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 +219,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 *
@@ -664,12 +644,7 @@
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;
@@ -694,7 +669,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 +752,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) {
@@ -904,13 +874,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,7 +903,7 @@
#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
+#elif XNU_TARGET_OS_IOS
panic("Failed to mount root device");
#endif
}
@@ -1144,44 +1113,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,39 +1154,6 @@
}
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;
@@ -1242,7 +1165,7 @@
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);
+ *ideal_size = *fallback_size = (requested_corefile_size * 1024ULL * 1024ULL);
return;
}
@@ -1266,7 +1189,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 +1197,14 @@
#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 */
return;
}
@@ -1347,13 +1266,12 @@
}
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 +1284,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",
@@ -1409,7 +1327,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;
@@ -1498,12 +1416,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:
@@ -1534,28 +1451,9 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
-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
+extern "C"
+OS_ALWAYS_INLINE
+boolean_t
IOCurrentTaskHasStringEntitlement(const char *entitlement, const char *value)
{
return IOTaskHasStringEntitlement(NULL, entitlement, value);
@@ -1564,208 +1462,162 @@
extern "C" boolean_t
IOTaskHasStringEntitlement(task_t task, const char *entitlement, const char *value)
{
+ if (task == kernel_task) {
+ return false;
+ } else if (!entitlement || !value) {
+ return false;
+ }
+
+ size_t name_length = strnlen(entitlement, CE_MAX_KEY_SIZE);
+ if (name_length >= CE_MAX_KEY_SIZE) {
+ printf("entitlement name length exceeds maximum allowed\n");
+ return false;
+ }
+
+ size_t value_length = strnlen(value, CE_MAX_KEY_SIZE);
+ if (value_length >= CE_MAX_KEY_SIZE) {
+ printf("entitlement value length exceeds maximum allowed\n");
+ return false;
+ }
+
+ CEQuery_t query = {
+ CESelectDictValueDynamic((const uint8_t*)entitlement, name_length),
+ CEIsDynamicStringAllowed((const uint8_t*)value, value_length)
+ };
+
+#if PMAP_CS_ENABLE && !CONFIG_X86_64_COMPAT
+
+ /*
+ * If we have PMAP_CS available and code signing is enabled, then we perform
+ * the entitlement check in the PPL.
+ *
+ * Note that the security benefits of doing so are questionable. The PPL has
+ * already locked down the entitlements blob, so we could simply have XNU go
+ * through the locked entitlements blob instead of switching into the PPL to
+ * perform the check. Afterall, the entitlement will be enforced by XNU and
+ * not the PPL, so trapping into the PPL for the check means little.
+ *
+ * Nevertheless, this is kept around to be consistent with how some of the
+ * other interfaces perform their entitlement checks.
+ */
+
+ if (pmap_cs_enabled()) {
+ if (task == NULL || task == current_task()) {
+ /* NULL task implies current_task */
+ 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
+
+ /* AMFI interface needs to be available */
+ if (amfi == NULL) {
+ panic("CoreEntitlements: (IOTask): AMFI interface not available");
+ }
+
+ if (task == NULL) {
+ /* NULL task implies current_task */
+ task = current_task();
+ }
+
+ proc_t p = (proc_t)get_bsdtask_info(task);
+ if (p == NULL) {
+ /* Cannot proceed if we don't have a proc structure */
+ return false;
+ }
+
+ struct cs_blob* csblob = csproc_get_blob(p);
+ if (csblob == NULL) {
+ /* Cannot proceed if process doesn't have a code signature */
+ return false;
+ }
+
+ void* osents = csblob_os_entitlements_get(csblob);
+ if (osents == NULL) {
+ return false;
+ }
+
+ CEError_t ce_err = amfi->CoreEntitlements.kQueryCannotBeSatisfied;
+ ce_err = amfi->OSEntitlements_query(osents, (uint8_t*)csblob_get_cdhash(csblob), query, 2);
+
+ return ce_err == amfi->CoreEntitlements.kNoError;
+}
+
+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
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 +1632,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 *
@@ -1880,3 +1655,43 @@
}
return value;
}
+
+extern "C"
+OS_ALWAYS_INLINE
+char *
+IOCurrentTaskGetEntitlement(const char * entitlement)
+{
+ return IOTaskGetEntitlement(current_task(), entitlement);
+}
+
+extern "C" char *
+IOTaskGetEntitlement(task_t task, const char * entitlement)
+{
+ OSObject * obj = NULL;
+ OSDictionary * entitlements = NULL;
+ OSString * str = NULL;
+ size_t len = 0;
+ char * value = NULL;
+
+ if (task == kernel_task || task == NULL || entitlement == NULL) {
+ goto finish;
+ }
+
+ entitlements = IOUserClient::copyClientEntitlements(task);
+ if (entitlements == NULL) {
+ goto finish;
+ }
+
+ obj = entitlements->getObject(entitlement);
+ str = OSDynamicCast(OSString, obj);
+ if (str != NULL) {
+ len = str->getLength() + 1;
+ value = (char *)kalloc_data(len, (zalloc_flags_t)(Z_ZERO | Z_WAITOK | Z_NOFAIL));
+ strlcpy(value, str->getCStringNoCopy(), len);
+ }
+
+finish:
+ OSSafeReleaseNULL(entitlements);
+
+ return value;
+}