Skip to content

Commit

Permalink
xnu-4570.41.2
Browse files Browse the repository at this point in the history
  • Loading branch information
Darwin authored and das committed Dec 10, 2018
1 parent e7af56a commit b2785e9
Show file tree
Hide file tree
Showing 52 changed files with 506 additions and 209 deletions.
6 changes: 3 additions & 3 deletions bsd/kern/kern_credential.c
Original file line number Diff line number Diff line change
Expand Up @@ -593,7 +593,7 @@ identitysvc(__unused struct proc *p, struct identitysvc_args *uap, __unused int3
int opcode = uap->opcode;
user_addr_t message = uap->message;
struct kauth_resolver_work *workp;
struct kauth_cache_sizes sz_arg;
struct kauth_cache_sizes sz_arg = {};
int error;
pid_t new_id;

Expand Down Expand Up @@ -5657,7 +5657,7 @@ sysctl_dump_creds( __unused struct sysctl_oid *oidp, __unused void *arg1, __unus
return 0;
}

MALLOC( cred_listp, debug_ucred *, req->oldlen, M_TEMP, M_WAITOK );
MALLOC( cred_listp, debug_ucred *, req->oldlen, M_TEMP, M_WAITOK | M_ZERO);
if ( cred_listp == NULL ) {
return (ENOMEM);
}
Expand Down Expand Up @@ -5756,7 +5756,7 @@ sysctl_dump_cred_backtraces( __unused struct sysctl_oid *oidp, __unused void *ar
return (ENOMEM);
}

MALLOC( bt_bufp, cred_debug_buffer *, req->oldlen, M_TEMP, M_WAITOK );
MALLOC( bt_bufp, cred_debug_buffer *, req->oldlen, M_TEMP, M_WAITOK | M_ZERO);
if ( bt_bufp == NULL ) {
return (ENOMEM);
}
Expand Down
38 changes: 27 additions & 11 deletions bsd/kern/kern_cs.c
Original file line number Diff line number Diff line change
Expand Up @@ -325,7 +325,7 @@ cs_system_require_lv(void)
/*
* Function: csblob_get_base_offset
*
* Description: This function returns the base offset into the Mach-O binary
* Description: This function returns the base offset into the (possibly universal) binary
* for a given blob.
*/

Expand Down Expand Up @@ -413,11 +413,15 @@ csproc_get_blob(struct proc *p)
if (NULL == p->p_textvp)
return NULL;

if ((p->p_csflags & CS_SIGNED) == 0) {
return NULL;
}

return ubc_cs_blob_get(p->p_textvp, -1, p->p_textoff);
}

/*
* Function: csproc_get_blob
* Function: csvnode_get_blob
*
* Description: This function returns the cs_blob
* for the vnode vp
Expand Down Expand Up @@ -579,7 +583,9 @@ csproc_get_platform_binary(struct proc *p)
int
csproc_get_platform_path(struct proc *p)
{
struct cs_blob *csblob = csproc_get_blob(p);
struct cs_blob *csblob;

csblob = csproc_get_blob(p);

return (csblob == NULL) ? 0 : csblob->csb_platform_path;
}
Expand Down Expand Up @@ -858,6 +864,10 @@ cs_entitlements_blob_get(proc_t p, void **out_start, size_t *out_length)
*out_start = NULL;
*out_length = 0;

if ((p->p_csflags & CS_SIGNED) == 0) {
return 0;
}

if (NULL == p->p_textvp)
return EINVAL;

Expand All @@ -878,6 +888,10 @@ cs_identity_get(proc_t p)
{
struct cs_blob *csblob;

if ((p->p_csflags & CS_SIGNED) == 0) {
return NULL;
}

if (NULL == p->p_textvp)
return NULL;

Expand All @@ -887,15 +901,13 @@ cs_identity_get(proc_t p)
return csblob_get_identity(csblob);
}


/* Retrieve the codesign blob for a process.
* Returns:
* EINVAL no text vnode associated with the process
* 0 no error occurred
/*
* DO NOT USE THIS FUNCTION!
* Use the properly guarded csproc_get_blob instead.
*
* On success, out_start and out_length will point to the
* cms blob if found; or will be set to NULL/zero
* if there were no blob.
* This is currently here to allow detached signatures to work
* properly. The only user of this function is also checking
* for CS_VALID.
*/

int
Expand Down Expand Up @@ -927,6 +939,10 @@ cs_get_cdhash(struct proc *p)
{
struct cs_blob *csblob;

if ((p->p_csflags & CS_SIGNED) == 0) {
return NULL;
}

if (NULL == p->p_textvp)
return NULL;

Expand Down
120 changes: 46 additions & 74 deletions bsd/kern/kern_exec.c
Original file line number Diff line number Diff line change
Expand Up @@ -2082,15 +2082,15 @@ static int spawn_validate_persona(struct _posix_spawn_persona_info *px_persona)
}
}
if (px_persona->pspi_flags & POSIX_SPAWN_PERSONA_GROUPS) {
int ngroups = 0;
unsigned ngroups = 0;
gid_t groups[NGROUPS_MAX];

if (persona_get_groups(persona, &ngroups, groups,
px_persona->pspi_ngroups) != 0) {
error = EINVAL;
goto out;
}
if (ngroups != (int)px_persona->pspi_ngroups) {
if (ngroups != px_persona->pspi_ngroups) {
error = EINVAL;
goto out;
}
Expand Down Expand Up @@ -5469,67 +5469,6 @@ static void cdhash_to_string(char str[CS_CDHASH_STRING_SIZE], uint8_t const * co
str[CS_CDHASH_STRING_SIZE - 1] = 0;
}

/*
* If the process is not signed or if it contains entitlements, we
* need to communicate through the task_access_port to taskgated.
*
* taskgated will provide a detached code signature if present, and
* will enforce any restrictions on entitlements.
*/

static boolean_t
taskgated_required(proc_t p, boolean_t *require_success)
{
size_t length;
void *blob;
int error;

if (cs_debug > 2)
csvnode_print_debug(p->p_textvp);

#if !CONFIG_EMBEDDED
const int can_skip_taskgated = csproc_get_platform_binary(p) && !csproc_get_platform_path(p);
#else
const int can_skip_taskgated = csproc_get_platform_binary(p);
#endif
if (can_skip_taskgated) {
if (cs_debug) printf("taskgated not required for: %s\n", p->p_name);
*require_success = FALSE;
return FALSE;
}

if ((p->p_csflags & CS_VALID) == 0) {
*require_success = FALSE;
return TRUE;
}

error = cs_entitlements_blob_get(p, &blob, &length);
if (error == 0 && blob != NULL) {
#if !CONFIG_EMBEDDED
/*
* fatal on the desktop when entitlements are present,
* unless we started in single-user mode
*/
if ((boothowto & RB_SINGLE) == 0)
*require_success = TRUE;
/*
* Allow initproc to run without causing taskgated to launch
*/
if (p == initproc) {
*require_success = FALSE;
return FALSE;
}

#endif
if (cs_debug) printf("taskgated required for: %s\n", p->p_name);

return TRUE;
}

*require_success = FALSE;
return FALSE;
}

/*
* __EXEC_WAITING_ON_TASKGATED_CODE_SIGNATURE_UPCALL__
*
Expand All @@ -5550,7 +5489,7 @@ check_for_signature(proc_t p, struct image_params *imgp)
kern_return_t kr = KERN_FAILURE;
int error = EACCES;
boolean_t unexpected_failure = FALSE;
unsigned char hash[CS_CDHASH_LEN];
struct cs_blob *csb;
boolean_t require_success = FALSE;
int spawn = (imgp->ip_flags & IMGPF_SPAWN);
int vfexec = (imgp->ip_flags & IMGPF_VFORK_EXEC);
Expand Down Expand Up @@ -5592,12 +5531,17 @@ check_for_signature(proc_t p, struct image_params *imgp)
goto done;
}

/* check if callout to taskgated is needed */
if (!taskgated_required(p, &require_success)) {
/* If the code signature came through the image activation path, we skip the
* taskgated / externally attached path. */
if (imgp->ip_csflags & CS_SIGNED) {
error = 0;
goto done;
}

/* The rest of the code is for signatures that either already have been externally
* attached (likely, but not necessarily by a previous run through the taskgated
* path), or that will now be attached by taskgated. */

kr = task_get_task_access_port(p->task, &port);
if (KERN_SUCCESS != kr || !IPC_PORT_VALID(port)) {
error = 0;
Expand Down Expand Up @@ -5642,14 +5586,42 @@ check_for_signature(proc_t p, struct image_params *imgp)

/* Only do this if exec_resettextvp() did not fail */
if (p->p_textvp != NULLVP) {
/*
* If there's a new code directory, mark this process
* as signed.
*/
if (0 == ubc_cs_getcdhash(p->p_textvp, p->p_textoff, hash)) {
proc_lock(p);
p->p_csflags |= CS_VALID;
proc_unlock(p);
csb = ubc_cs_blob_get(p->p_textvp, -1, p->p_textoff);

if (csb != NULL) {
/* As the enforcement we can do here is very limited, we only allow things that
* are the only reason why this code path still exists:
* Adhoc signed non-platform binaries without special cs_flags and without any
* entitlements (unrestricted ones still pass AMFI). */
if (
/* Revalidate the blob if necessary through bumped generation count. */
(ubc_cs_generation_check(p->p_textvp) == 0 ||
ubc_cs_blob_revalidate(p->p_textvp, csb, imgp, 0) == 0) &&
/* Only CS_ADHOC, no CS_KILL, CS_HARD etc. */
(csb->csb_flags & CS_ALLOWED_MACHO) == CS_ADHOC &&
/* If it has a CMS blob, it's not adhoc. The CS_ADHOC flag can lie. */
csblob_find_blob_bytes((const uint8_t *)csb->csb_mem_kaddr, csb->csb_mem_size,
CSSLOT_SIGNATURESLOT,
CSMAGIC_BLOBWRAPPER) == NULL &&
/* It could still be in a trust cache (unlikely with CS_ADHOC), or a magic path. */
csb->csb_platform_binary == 0 &&
/* No entitlements, not even unrestricted ones. */
csb->csb_entitlements_blob == NULL) {

proc_lock(p);
p->p_csflags |= CS_SIGNED | CS_VALID;
proc_unlock(p);

} else {
uint8_t cdhash[CS_CDHASH_LEN];
char cdhash_string[CS_CDHASH_STRING_SIZE];
proc_getcdhash(p, cdhash);
cdhash_to_string(cdhash_string, cdhash);
printf("ignoring detached code signature on '%s' with cdhash '%s' "
"because it is invalid, or not a simple adhoc signature.\n",
p->p_name, cdhash_string);
}

}
}

Expand Down
4 changes: 2 additions & 2 deletions bsd/kern/kern_exit.c
Original file line number Diff line number Diff line change
Expand Up @@ -1791,14 +1791,14 @@ wait4_nocancel(proc_t q, struct wait4_nocancel_args *uap, int32_t *retval)
error = ENOMEM;
} else {
if (IS_64BIT_PROCESS(q)) {
struct user64_rusage my_rusage;
struct user64_rusage my_rusage = {};
munge_user64_rusage(&p->p_ru->ru, &my_rusage);
error = copyout((caddr_t)&my_rusage,
uap->rusage,
sizeof (my_rusage));
}
else {
struct user32_rusage my_rusage;
struct user32_rusage my_rusage = {};
munge_user32_rusage(&p->p_ru->ru, &my_rusage);
error = copyout((caddr_t)&my_rusage,
uap->rusage,
Expand Down
2 changes: 1 addition & 1 deletion bsd/kern/kern_mman.c
Original file line number Diff line number Diff line change
Expand Up @@ -1047,7 +1047,7 @@ mincore(__unused proc_t p, struct mincore_args *uap, __unused int32_t *retval)
req_vec_size_pages = (end - addr) >> PAGE_SHIFT;
cur_vec_size_pages = MIN(req_vec_size_pages, (int)(MAX_PAGE_RANGE_QUERY >> PAGE_SHIFT));

kernel_vec = (void*) _MALLOC(cur_vec_size_pages * sizeof(char), M_TEMP, M_WAITOK);
kernel_vec = (void*) _MALLOC(cur_vec_size_pages * sizeof(char), M_TEMP, M_WAITOK | M_ZERO);

if (kernel_vec == NULL) {
return (ENOMEM);
Expand Down
12 changes: 6 additions & 6 deletions bsd/kern/kern_ntptime.c
Original file line number Diff line number Diff line change
Expand Up @@ -267,7 +267,7 @@ ntp_gettime(struct proc *p, struct ntp_gettime_args *uap, __unused int32_t *retv
NTP_UNLOCK(enable);

if (IS_64BIT_PROCESS(p)) {
struct user64_ntptimeval user_ntv;
struct user64_ntptimeval user_ntv = {};
user_ntv.time.tv_sec = ntv.time.tv_sec;
user_ntv.time.tv_nsec = ntv.time.tv_nsec;
user_ntv.maxerror = ntv.maxerror;
Expand All @@ -276,7 +276,7 @@ ntp_gettime(struct proc *p, struct ntp_gettime_args *uap, __unused int32_t *retv
user_ntv.time_state = ntv.time_state;
error = copyout(&user_ntv, uap->ntvp, sizeof(user_ntv));
} else {
struct user32_ntptimeval user_ntv;
struct user32_ntptimeval user_ntv = {};
user_ntv.time.tv_sec = ntv.time.tv_sec;
user_ntv.time.tv_nsec = ntv.time.tv_nsec;
user_ntv.maxerror = ntv.maxerror;
Expand Down Expand Up @@ -439,7 +439,7 @@ ntp_adjtime(struct proc *p, struct ntp_adjtime_args *uap, __unused int32_t *retv
* returned only by ntp_gettime();
*/
if (IS_64BIT_PROCESS(p)) {
struct user64_timex user_ntv;
struct user64_timex user_ntv = {};

if (time_status & STA_NANO)
user_ntv.offset = L_GINT(time_offset);
Expand All @@ -463,7 +463,7 @@ ntp_adjtime(struct proc *p, struct ntp_adjtime_args *uap, __unused int32_t *retv

}
else{
struct user32_timex user_ntv;
struct user32_timex user_ntv = {};

if (time_status & STA_NANO)
user_ntv.offset = L_GINT(time_offset);
Expand Down Expand Up @@ -712,12 +712,12 @@ adjtime(struct proc *p, struct adjtime_args *uap, __unused int32_t *retval)

if (uap->olddelta) {
if (IS_64BIT_PROCESS(p)) {
struct user64_timeval user_atv;
struct user64_timeval user_atv = {};
user_atv.tv_sec = atv.tv_sec;
user_atv.tv_usec = atv.tv_usec;
error = copyout(&user_atv, uap->olddelta, sizeof(user_atv));
} else {
struct user32_timeval user_atv;
struct user32_timeval user_atv = {};
user_atv.tv_sec = atv.tv_sec;
user_atv.tv_usec = atv.tv_usec;
error = copyout(&user_atv, uap->olddelta, sizeof(user_atv));
Expand Down
Loading

0 comments on commit b2785e9

Please sign in to comment.