- kr = kIOReturnNotPrivileged;
-
- if (p && (cred = kauth_cred_proc_ref(p)))
- {
- user = CopyUserOnConsole();
- if (user)
- {
- OSNumber * num;
- if ((num = OSDynamicCast(OSNumber, user->getObject(gIOConsoleSessionAuditIDKey)))
- && (cred->cr_audit.as_aia_p->ai_asid == (au_asid_t) num->unsigned32BitValue()))
- {
- kr = kIOReturnSuccess;
- }
- user->release();
- }
- kauth_cred_unref(&cred);
- }
- return (kr);
- }
-
- if ((secureConsole = !strncmp(privilegeName, kIOClientPrivilegeSecureConsoleProcess,
- sizeof(kIOClientPrivilegeSecureConsoleProcess))))
- task = (task_t)((IOUCProcessToken *)securityToken)->token;
- else
- task = (task_t)securityToken;
-
- count = TASK_SECURITY_TOKEN_COUNT;
- kr = task_info( task, TASK_SECURITY_TOKEN, (task_info_t) &token, &count );
-
- if (KERN_SUCCESS != kr)
- {}
- else if (!strncmp(privilegeName, kIOClientPrivilegeAdministrator,
- sizeof(kIOClientPrivilegeAdministrator))) {
- if (0 != token.val[0])
- kr = kIOReturnNotPrivileged;
- } else if (!strncmp(privilegeName, kIOClientPrivilegeLocalUser,
- sizeof(kIOClientPrivilegeLocalUser))) {
- user = CopyConsoleUser(token.val[0]);
- if ( user )
- user->release();
- else
- kr = kIOReturnNotPrivileged;
- } else if (secureConsole || !strncmp(privilegeName, kIOClientPrivilegeConsoleUser,
- sizeof(kIOClientPrivilegeConsoleUser))) {
- user = CopyConsoleUser(token.val[0]);
- if ( user ) {
- if (user->getObject(gIOConsoleSessionOnConsoleKey) != kOSBooleanTrue)
- kr = kIOReturnNotPrivileged;
- else if ( secureConsole ) {
- OSNumber * pid = OSDynamicCast(OSNumber, user->getObject(gIOConsoleSessionSecureInputPIDKey));
- if ( pid && pid->unsigned32BitValue() != ((IOUCProcessToken *)securityToken)->pid)
- kr = kIOReturnNotPrivileged;
- }
- user->release();
- }
- else
- kr = kIOReturnNotPrivileged;
- } else
- kr = kIOReturnUnsupported;
-
- return (kr);
-}
-
-bool IOUserClient::init()
-{
- if (getPropertyTable() || super::init())
+ if (p) {
+ uint64_t authorizationID;
+
+ authorizationID = proc_uniqueid(p);
+ if (authorizationID) {
+ if (service->getAuthorizationID() == authorizationID) {
+ return kIOReturnSuccess;
+ }
+ }
+ }
+
+ return kIOReturnNotPermitted;
+}
+
+IOReturn
+IOUserClient::clientHasPrivilege( void * securityToken,
+ const char * privilegeName )
+{
+ kern_return_t kr;
+ security_token_t token;
+ mach_msg_type_number_t count;
+ task_t task;
+ OSDictionary * user;
+ bool secureConsole;
+
+
+ if (!strncmp(privilegeName, kIOClientPrivilegeForeground,
+ sizeof(kIOClientPrivilegeForeground))) {
+ if (task_is_gpu_denied(current_task())) {
+ return kIOReturnNotPrivileged;
+ } else {
+ return kIOReturnSuccess;
+ }
+ }
+
+ if (!strncmp(privilegeName, kIOClientPrivilegeConsoleSession,
+ sizeof(kIOClientPrivilegeConsoleSession))) {
+ kauth_cred_t cred;
+ proc_t p;
+
+ task = (task_t) securityToken;
+ if (!task) {
+ task = current_task();
+ }
+ p = (proc_t) get_bsdtask_info(task);
+ kr = kIOReturnNotPrivileged;
+
+ if (p && (cred = kauth_cred_proc_ref(p))) {
+ user = CopyUserOnConsole();
+ if (user) {
+ OSNumber * num;
+ if ((num = OSDynamicCast(OSNumber, user->getObject(gIOConsoleSessionAuditIDKey)))
+ && (cred->cr_audit.as_aia_p->ai_asid == (au_asid_t) num->unsigned32BitValue())) {
+ kr = kIOReturnSuccess;
+ }
+ user->release();
+ }
+ kauth_cred_unref(&cred);
+ }
+ return kr;
+ }
+
+ if ((secureConsole = !strncmp(privilegeName, kIOClientPrivilegeSecureConsoleProcess,
+ sizeof(kIOClientPrivilegeSecureConsoleProcess)))) {
+ task = (task_t)((IOUCProcessToken *)securityToken)->token;
+ } else {
+ task = (task_t)securityToken;
+ }
+
+ count = TASK_SECURITY_TOKEN_COUNT;
+ kr = task_info( task, TASK_SECURITY_TOKEN, (task_info_t) &token, &count );
+
+ if (KERN_SUCCESS != kr) {
+ } else if (!strncmp(privilegeName, kIOClientPrivilegeAdministrator,
+ sizeof(kIOClientPrivilegeAdministrator))) {
+ if (0 != token.val[0]) {
+ kr = kIOReturnNotPrivileged;
+ }
+ } else if (!strncmp(privilegeName, kIOClientPrivilegeLocalUser,
+ sizeof(kIOClientPrivilegeLocalUser))) {
+ user = CopyConsoleUser(token.val[0]);
+ if (user) {
+ user->release();
+ } else {
+ kr = kIOReturnNotPrivileged;
+ }
+ } else if (secureConsole || !strncmp(privilegeName, kIOClientPrivilegeConsoleUser,
+ sizeof(kIOClientPrivilegeConsoleUser))) {
+ user = CopyConsoleUser(token.val[0]);
+ if (user) {
+ if (user->getObject(gIOConsoleSessionOnConsoleKey) != kOSBooleanTrue) {
+ kr = kIOReturnNotPrivileged;
+ } else if (secureConsole) {
+ OSNumber * pid = OSDynamicCast(OSNumber, user->getObject(gIOConsoleSessionSecureInputPIDKey));
+ if (pid && pid->unsigned32BitValue() != ((IOUCProcessToken *)securityToken)->pid) {
+ kr = kIOReturnNotPrivileged;
+ }
+ }
+ user->release();
+ } else {
+ kr = kIOReturnNotPrivileged;
+ }
+ } else {
+ kr = kIOReturnUnsupported;
+ }
+
+ return kr;
+}
+
+OSDictionary *
+IOUserClient::copyClientEntitlements(task_t task)
+{
+#define MAX_ENTITLEMENTS_LEN (128 * 1024)
+
+ proc_t p = NULL;
+ pid_t pid = 0;
+ size_t len = 0;
+ void *entitlements_blob = NULL;
+ char *entitlements_data = NULL;
+ OSObject *entitlements_obj = NULL;
+ OSDictionary *entitlements = NULL;
+ OSString *errorString = NULL;
+
+ p = (proc_t)get_bsdtask_info(task);
+ if (p == NULL) {
+ goto fail;
+ }
+ pid = proc_pid(p);
+
+ if (cs_entitlements_dictionary_copy(p, (void **)&entitlements) == 0) {
+ if (entitlements) {
+ return entitlements;
+ }
+ }
+
+ if (cs_entitlements_blob_get(p, &entitlements_blob, &len) != 0) {
+ goto fail;
+ }
+
+ if (len <= offsetof(CS_GenericBlob, data)) {
+ goto fail;
+ }
+
+ /*
+ * Per <rdar://problem/11593877>, enforce a limit on the amount of XML
+ * we'll try to parse in the kernel.
+ */
+ len -= offsetof(CS_GenericBlob, data);
+ if (len > MAX_ENTITLEMENTS_LEN) {
+ IOLog("failed to parse entitlements for %s[%u]: %lu bytes of entitlements exceeds maximum of %u\n",
+ proc_best_name(p), pid, len, MAX_ENTITLEMENTS_LEN);
+ goto fail;
+ }
+
+ /*
+ * OSUnserializeXML() expects a nul-terminated string, but that isn't
+ * what is stored in the entitlements blob. Copy the string and
+ * terminate it.
+ */
+ entitlements_data = (char *)IOMalloc(len + 1);
+ if (entitlements_data == NULL) {
+ goto fail;
+ }
+ memcpy(entitlements_data, ((CS_GenericBlob *)entitlements_blob)->data, len);
+ entitlements_data[len] = '\0';
+
+ entitlements_obj = OSUnserializeXML(entitlements_data, len + 1, &errorString);
+ if (errorString != NULL) {
+ IOLog("failed to parse entitlements for %s[%u]: %s\n",
+ proc_best_name(p), pid, errorString->getCStringNoCopy());
+ goto fail;
+ }
+ if (entitlements_obj == NULL) {
+ goto fail;
+ }
+
+ entitlements = OSDynamicCast(OSDictionary, entitlements_obj);
+ if (entitlements == NULL) {
+ goto fail;
+ }
+ entitlements_obj = NULL;
+
+fail:
+ if (entitlements_data != NULL) {
+ IOFree(entitlements_data, len + 1);
+ }
+ if (entitlements_obj != NULL) {
+ entitlements_obj->release();
+ }
+ if (errorString != NULL) {
+ errorString->release();
+ }
+ return entitlements;
+}
+
+OSObject *
+IOUserClient::copyClientEntitlement( task_t task,
+ const char * entitlement )
+{
+ OSDictionary *entitlements;
+ OSObject *value;
+
+ entitlements = copyClientEntitlements(task);
+ if (entitlements == NULL) {
+ return NULL;
+ }
+
+ /* Fetch the entitlement value from the dictionary. */
+ value = entitlements->getObject(entitlement);
+ if (value != NULL) {
+ value->retain();
+ }
+
+ entitlements->release();
+ return value;
+}
+
+bool
+IOUserClient::init()
+{
+ if (getPropertyTable() || super::init()) {