kern_return_t kr;
boolean_t task_has_watchport_boost = task_has_watchports(current_task());
boolean_t in_exec = (imgp->ip_flags & IMGPF_EXEC);
+ boolean_t suid_cred_specified = FALSE;
for (i = 0; i < pacts->pspa_count; i++) {
act = &pacts->pspa_actions[i];
goto done;
}
break;
+
+ case PSPA_SUID_CRED:
+ /* Only a single suid credential can be specified. */
+ if (suid_cred_specified) {
+ ret = EINVAL;
+ goto done;
+ }
+ suid_cred_specified = TRUE;
+ break;
+
default:
ret = EINVAL;
goto done;
/* hold on to this till end of spawn */
actions->registered_array[registered_i++] = port;
break;
+
+ case PSPA_SUID_CRED:
+ imgp->ip_sc_port = port;
+ break;
+
default:
ret = EINVAL;
break;
imgp->ip_cs_error = OS_REASON_NULL;
}
#endif
+ if (imgp->ip_sc_port != NULL) {
+ ipc_port_release_send(imgp->ip_sc_port);
+ imgp->ip_sc_port = NULL;
+ }
}
#if CONFIG_DTRACE
kauth_cred_getuid(cred) != imgp->ip_origvattr->va_uid) ||
((imgp->ip_origvattr->va_mode & VSGID) != 0 &&
((kauth_cred_ismember_gid(cred, imgp->ip_origvattr->va_gid, &leave_sugid_clear) || !leave_sugid_clear) ||
- (kauth_cred_getgid(cred) != imgp->ip_origvattr->va_gid)))) {
+ (kauth_cred_getgid(cred) != imgp->ip_origvattr->va_gid))) ||
+ (imgp->ip_sc_port != NULL)) {
#if CONFIG_MACF
/* label for MAC transition and neither VSUID nor VSGID */
handle_mac_transition:
* proc's ucred lock. This prevents others from accessing
* a garbage credential.
*/
+
+ if (imgp->ip_sc_port != NULL) {
+ extern int suid_cred_verify(ipc_port_t, vnode_t, uint32_t *);
+ int ret = -1;
+ uid_t uid = UINT32_MAX;
+
+ /*
+ * Check that the vnodes match. If a script is being
+ * executed check the script's vnode rather than the
+ * interpreter's.
+ */
+ struct vnode *vp = imgp->ip_scriptvp != NULL ? imgp->ip_scriptvp : imgp->ip_vp;
+
+ ret = suid_cred_verify(imgp->ip_sc_port, vp, &uid);
+ if (ret == 0) {
+ apply_kauth_cred_update(p, ^kauth_cred_t (kauth_cred_t my_cred) {
+ return kauth_cred_setresuid(my_cred,
+ KAUTH_UID_NONE,
+ uid,
+ uid,
+ KAUTH_UID_NONE);
+ });
+ } else {
+ error = EPERM;
+ }
+ }
+
if (imgp->ip_origvattr->va_mode & VSUID) {
apply_kauth_cred_update(p, ^kauth_cred_t (kauth_cred_t my_cred) {
return kauth_cred_setresuid(my_cred,