X-Git-Url: https://git.saurik.com/apple/security.git/blobdiff_plain/dbe775057b53a81d9983d810772462c3233fccd3..refs/heads/master:/sectask/SecTask.c diff --git a/sectask/SecTask.c b/sectask/SecTask.c index 57b635c0..4b38f13d 100644 --- a/sectask/SecTask.c +++ b/sectask/SecTask.c @@ -25,6 +25,7 @@ #include "SecTaskPriv.h" #include +#include #include #include @@ -35,14 +36,15 @@ #include #include #include +#include #include #if TARGET_OS_OSX /* These won't exist until we unify codesigning */ -#include "SecCode.h" -#include "SecCodePriv.h" -#include "SecRequirement.h" +#include +#include +#include #endif /* TARGET_OS_OSX */ struct __SecTask { @@ -132,6 +134,21 @@ SecTaskRef SecTaskCreateWithAuditToken(CFAllocatorRef allocator, audit_token_t t return task; } +_Nullable SecTaskRef +SecTaskCreateWithXPCMessage(xpc_object_t _Nonnull message) +{ + audit_token_t token; + + if (message == NULL || xpc_get_type(message) != XPC_TYPE_DICTIONARY) { + return NULL; + } + xpc_dictionary_get_audit_token(message, &token); + + return SecTaskCreateWithAuditToken(NULL, token); +} + + + struct csheader { uint32_t magic; uint32_t length; @@ -221,46 +238,44 @@ static bool SecTaskLoadEntitlements(SecTaskRef task, CFErrorRef *error) uint32_t bufferlen; int ret; - ret = csops_task(task, CS_OPS_ENTITLEMENTS_BLOB, &header, sizeof(header)); /* Any other combination means no entitlements */ - if (ret == -1) { - if (errno != ERANGE) { + if (ret == -1) { + if (errno != ERANGE) { int entitlementErrno = errno; - uint32_t cs_flags = -1; + uint32_t cs_flags = -1; if (-1 == csops_task(task, CS_OPS_STATUS, &cs_flags, sizeof(cs_flags))) { syslog(LOG_NOTICE, "Failed to get cs_flags, error=%d", errno); } - if (cs_flags != 0) { // was signed - - pid_t pid; - audit_token_to_au32(task->token, NULL, NULL, NULL, NULL, NULL, &pid, NULL, NULL); - syslog(LOG_NOTICE, "SecTaskLoadEntitlements failed error=%d cs_flags=%x, pid=%d", entitlementErrno, cs_flags, pid); // to ease diagnostics - - CFStringRef description = SecTaskCopyDebugDescription(task); - char *descriptionBuf = NULL; - CFIndex descriptionSize = CFStringGetLength(description) * 4; - descriptionBuf = (char *)malloc(descriptionSize); - if (!CFStringGetCString(description, descriptionBuf, descriptionSize, kCFStringEncodingUTF8)) { - descriptionBuf[0] = 0; - } - - syslog(LOG_NOTICE, "SecTaskCopyDebugDescription: %s", descriptionBuf); - CFReleaseNull(description); - free(descriptionBuf); - } - task->lastFailure = entitlementErrno; // was overwritten by csops_task(CS_OPS_STATUS) above - - // EINVAL is what the kernel says for unsigned code, so we'll have to let that pass - if (entitlementErrno == EINVAL) { - task->entitlementsLoaded = true; - return true; - } - ret = entitlementErrno; // what really went wrong - goto out; // bail out - } + if (cs_flags != 0) { // was signed + pid_t pid; + audit_token_to_au32(task->token, NULL, NULL, NULL, NULL, NULL, &pid, NULL, NULL); + syslog(LOG_NOTICE, "SecTaskLoadEntitlements failed error=%d cs_flags=%x, pid=%d", entitlementErrno, cs_flags, pid); // to ease diagnostics + + CFStringRef description = SecTaskCopyDebugDescription(task); + char *descriptionBuf = NULL; + CFIndex descriptionSize = CFStringGetLength(description) * 4; + descriptionBuf = (char *)malloc(descriptionSize); + if (!CFStringGetCString(description, descriptionBuf, descriptionSize, kCFStringEncodingUTF8)) { + descriptionBuf[0] = 0; + } + + syslog(LOG_NOTICE, "SecTaskCopyDebugDescription: %s", descriptionBuf); + CFReleaseNull(description); + free(descriptionBuf); + } + task->lastFailure = entitlementErrno; // was overwritten by csops_task(CS_OPS_STATUS) above + + // EINVAL is what the kernel says for unsigned code, so we'll have to let that pass + if (entitlementErrno == EINVAL) { + task->entitlementsLoaded = true; + return true; + } + ret = entitlementErrno; // what really went wrong + goto out; // bail out + } bufferlen = ntohl(header.length); /* check for insane values */ if (bufferlen > 1024 * 1024 || bufferlen < 8) { @@ -282,10 +297,17 @@ static bool SecTaskLoadEntitlements(SecTaskRef task, CFErrorRef *error) entitlements = (CFMutableDictionaryRef) CFPropertyListCreateWithData(kCFAllocatorDefault, data, kCFPropertyListMutableContainers, NULL, error); CFReleaseNull(data); - if((entitlements==NULL) || (CFGetTypeID(entitlements)!=CFDictionaryGetTypeID())){ + if ((entitlements==NULL) || (CFGetTypeID(entitlements)!=CFDictionaryGetTypeID())){ ret = EDOM; // don't use EINVAL here; it conflates problems with syscall error returns goto out; } + + bool entitlementsModified = updateCatalystEntitlements(entitlements); + if (entitlementsModified) { + pid_t pid; + audit_token_to_au32(task->token, NULL, NULL, NULL, NULL, NULL, &pid, NULL, NULL); + secinfo("SecTask", "Fixed catalyst entitlements for process %d", pid); + } } task->entitlements = entitlements ? CFRetain(entitlements) : NULL; @@ -354,7 +376,7 @@ out: return values; } -#if TARGET_OS_OSX +#if SEC_OS_OSX /* * Determine if the given task meets a specified requirement. */ @@ -385,7 +407,7 @@ SecTaskValidateForRequirement(SecTaskRef task, CFStringRef requirement) return status; } -#endif /* TARGET_OS_OSX */ +#endif /* SEC_OS_OSX */ Boolean SecTaskEntitlementsValidated(SecTaskRef task) { // TODO: Cache the result