Skip to content

Commit

Permalink
xnu-6153.101.6
Browse files Browse the repository at this point in the history
  • Loading branch information
Darwin authored and das committed Jan 11, 2021
1 parent 62e8fb1 commit 7049016
Show file tree
Hide file tree
Showing 260 changed files with 14,712 additions and 2,541 deletions.
2 changes: 1 addition & 1 deletion bsd/bsm/audit_kevents.h
Original file line number Diff line number Diff line change
Expand Up @@ -447,7 +447,6 @@
#define AUE_PIDFORTASK 43049 /* Darwin-specific. */
#define AUE_SYSCTL_NONADMIN 43050
#define AUE_COPYFILE 43051 /* Darwin-specific. */
#define AUE_DBGPORTFORPID 43052 /* Darwin-specific. */
/*
* Events added to OpenBSM for FreeBSD and Linux; may also be used by Darwin
* in the future.
Expand Down Expand Up @@ -615,6 +614,7 @@
#define AUE_SETATTRLISTAT 43212 /* Darwin. */
#define AUE_FMOUNT 43213 /* Darwin. */
#define AUE_FSGETPATH_EXTENDED 43214 /* Darwin. */
#define AUE_DBGPORTFORPID 43215 /* Darwin-specific. */

#define AUE_SESSION_START 44901 /* Darwin. */
#define AUE_SESSION_UPDATE 44902 /* Darwin. */
Expand Down
8 changes: 7 additions & 1 deletion bsd/dev/dtrace/dtrace.c
Original file line number Diff line number Diff line change
Expand Up @@ -18660,7 +18660,7 @@ dtrace_ioctl(dev_t dev, u_long cmd, user_addr_t arg, int md, cred_t *cr, int *rv
* Range check the count. How much data can we pass around?
* FIX ME!
*/
if (dtmodsyms_count == 0 || (dtmodsyms_count > 100 * 1024)) {
if (dtmodsyms_count == 0) {
cmn_err(CE_WARN, "dtmodsyms_count is not valid");
return (EINVAL);
}
Expand All @@ -18669,6 +18669,12 @@ dtrace_ioctl(dev_t dev, u_long cmd, user_addr_t arg, int md, cred_t *cr, int *rv
* Allocate a correctly sized structure and copyin the data.
*/
module_symbols_size = DTRACE_MODULE_SYMBOLS_SIZE(dtmodsyms_count);
if (module_symbols_size > (size_t)dtrace_copy_maxsize()) {
size_t dtmodsyms_max = DTRACE_MODULE_SYMBOLS_COUNT(dtrace_copy_maxsize());
cmn_err(CE_WARN, "dtmodsyms_count %ld is too high, maximum is %ld", dtmodsyms_count, dtmodsyms_max);
return (ENOBUFS);
}

if ((module_symbols = kmem_alloc(module_symbols_size, KM_SLEEP)) == NULL)
return (ENOMEM);

Expand Down
4 changes: 2 additions & 2 deletions bsd/kern/kern_backtrace.c
Original file line number Diff line number Diff line change
Expand Up @@ -73,8 +73,8 @@ backtrace_sysctl SYSCTL_HANDLER_ARGS
return ENOBUFS;
}
memset(bt, 0, bt_size);
error = backtrace_user(bt, bt_len, &bt_filled, NULL, NULL);
if (error) {
bt_filled = backtrace_user(bt, bt_len, &error, NULL, NULL);
if (error != 0) {
goto out;
}
bt_filled = min(bt_filled, bt_len);
Expand Down
54 changes: 42 additions & 12 deletions bsd/kern/kern_control.c
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ struct ctl_cb {
struct sockaddr_ctl sac;
u_int32_t usecount;
u_int32_t kcb_usecount;
u_int32_t require_clearing_count;
#if DEVELOPMENT || DEBUG
enum ctl_status status;
#endif /* DEVELOPMENT || DEBUG */
Expand Down Expand Up @@ -370,24 +371,45 @@ ctl_sofreelastref(struct socket *so)
}

/*
* Use this function to serialize calls into the kctl subsystem
* Use this function and ctl_kcb_require_clearing to serialize
* critical calls into the kctl subsystem
*/
static void
ctl_kcb_increment_use_count(struct ctl_cb *kcb, lck_mtx_t *mutex_held)
{
LCK_MTX_ASSERT(mutex_held, LCK_MTX_ASSERT_OWNED);
while (kcb->kcb_usecount > 0) {
while (kcb->require_clearing_count > 0) {
msleep(&kcb->require_clearing_count, mutex_held, PSOCK | PCATCH, "kcb_require_clearing", NULL);
}
kcb->kcb_usecount++;
}

static void
ctl_kcb_require_clearing(struct ctl_cb *kcb, lck_mtx_t *mutex_held)
{
assert(kcb->kcb_usecount != 0);
kcb->require_clearing_count++;
kcb->kcb_usecount--;
while (kcb->kcb_usecount > 0) { // we need to wait until no one else is running
msleep(&kcb->kcb_usecount, mutex_held, PSOCK | PCATCH, "kcb_usecount", NULL);
}
kcb->kcb_usecount++;
}

static void
clt_kcb_decrement_use_count(struct ctl_cb *kcb)
ctl_kcb_done_clearing(struct ctl_cb *kcb)
{
assert(kcb->require_clearing_count != 0);
kcb->require_clearing_count--;
wakeup((caddr_t)&kcb->require_clearing_count);
}

static void
ctl_kcb_decrement_use_count(struct ctl_cb *kcb)
{
assert(kcb->kcb_usecount != 0);
kcb->kcb_usecount--;
wakeup_one((caddr_t)&kcb->kcb_usecount);
wakeup((caddr_t)&kcb->kcb_usecount);
}

static int
Expand All @@ -401,6 +423,7 @@ ctl_detach(struct socket *so)

lck_mtx_t *mtx_held = socket_getlock(so, PR_F_WILLUNLOCK);
ctl_kcb_increment_use_count(kcb, mtx_held);
ctl_kcb_require_clearing(kcb, mtx_held);

if (kcb->kctl != NULL && kcb->kctl->bind != NULL &&
kcb->userdata != NULL && !(so->so_state & SS_ISCONNECTED)) {
Expand All @@ -419,7 +442,8 @@ ctl_detach(struct socket *so)
kcb->status = KCTL_DISCONNECTED;
#endif /* DEVELOPMENT || DEBUG */
so->so_flags |= SOF_PCBCLEARING;
clt_kcb_decrement_use_count(kcb);
ctl_kcb_done_clearing(kcb);
ctl_kcb_decrement_use_count(kcb);
return 0;
}

Expand Down Expand Up @@ -573,6 +597,7 @@ ctl_bind(struct socket *so, struct sockaddr *nam, struct proc *p)

lck_mtx_t *mtx_held = socket_getlock(so, PR_F_WILLUNLOCK);
ctl_kcb_increment_use_count(kcb, mtx_held);
ctl_kcb_require_clearing(kcb, mtx_held);

error = ctl_setup_kctl(so, nam, p);
if (error) {
Expand All @@ -593,7 +618,8 @@ ctl_bind(struct socket *so, struct sockaddr *nam, struct proc *p)
socket_lock(so, 0);

out:
clt_kcb_decrement_use_count(kcb);
ctl_kcb_done_clearing(kcb);
ctl_kcb_decrement_use_count(kcb);
return error;
}

Expand All @@ -609,6 +635,7 @@ ctl_connect(struct socket *so, struct sockaddr *nam, struct proc *p)

lck_mtx_t *mtx_held = socket_getlock(so, PR_F_WILLUNLOCK);
ctl_kcb_increment_use_count(kcb, mtx_held);
ctl_kcb_require_clearing(kcb, mtx_held);

#if DEVELOPMENT || DEBUG
if (kcb->status != KCTL_DISCONNECTED && ctl_panic_debug) {
Expand Down Expand Up @@ -668,7 +695,8 @@ ctl_connect(struct socket *so, struct sockaddr *nam, struct proc *p)
lck_mtx_unlock(ctl_mtx);
}
out:
clt_kcb_decrement_use_count(kcb);
ctl_kcb_done_clearing(kcb);
ctl_kcb_decrement_use_count(kcb);
return error;
}

Expand All @@ -680,6 +708,7 @@ ctl_disconnect(struct socket *so)
if ((kcb = (struct ctl_cb *)so->so_pcb)) {
lck_mtx_t *mtx_held = socket_getlock(so, PR_F_WILLUNLOCK);
ctl_kcb_increment_use_count(kcb, mtx_held);
ctl_kcb_require_clearing(kcb, mtx_held);
struct kctl *kctl = kcb->kctl;

if (kctl && kctl->disconnect) {
Expand All @@ -706,7 +735,8 @@ ctl_disconnect(struct socket *so)
kctlstat.kcs_gencnt++;
lck_mtx_unlock(ctl_mtx);
socket_lock(so, 0);
clt_kcb_decrement_use_count(kcb);
ctl_kcb_done_clearing(kcb);
ctl_kcb_decrement_use_count(kcb);
}
return 0;
}
Expand Down Expand Up @@ -798,7 +828,7 @@ ctl_usr_rcvd(struct socket *so, int flags)
ctl_sbrcv_trim(so);

out:
clt_kcb_decrement_use_count(kcb);
ctl_kcb_decrement_use_count(kcb);
return error;
}

Expand Down Expand Up @@ -842,7 +872,7 @@ ctl_send(struct socket *so, int flags, struct mbuf *m,
if (error != 0) {
OSIncrementAtomic64((SInt64 *)&kctlstat.kcs_send_fail);
}
clt_kcb_decrement_use_count(kcb);
ctl_kcb_decrement_use_count(kcb);

return error;
}
Expand Down Expand Up @@ -906,7 +936,7 @@ ctl_send_list(struct socket *so, int flags, struct mbuf *m,
if (error != 0) {
OSIncrementAtomic64((SInt64 *)&kctlstat.kcs_send_list_fail);
}
clt_kcb_decrement_use_count(kcb);
ctl_kcb_decrement_use_count(kcb);

return error;
}
Expand Down Expand Up @@ -1415,7 +1445,7 @@ ctl_ctloutput(struct socket *so, struct sockopt *sopt)
}

out:
clt_kcb_decrement_use_count(kcb);
ctl_kcb_decrement_use_count(kcb);
return error;
}

Expand Down
17 changes: 0 additions & 17 deletions bsd/kern/kern_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -70,11 +70,6 @@
#include <security/mac_framework.h>
#endif /* CONFIG_MACF */

#if CONFIG_CSR
#include <sys/codesign.h>
#include <sys/csr.h>
#endif

typedef struct {
int flavor; /* the number for this flavor */
mach_msg_type_number_t count; /* count of ints in this flavor */
Expand Down Expand Up @@ -291,18 +286,6 @@ coredump(proc_t core_proc, uint32_t reserve_mb, int coredump_flags)
}
#endif

#if CONFIG_CSR
/* If the process is restricted, CSR isn't configured to allow
* restricted processes to be debugged, and CSR isn't configured in
* AppleInternal mode, then don't dump core. */
if (cs_restricted(core_proc) &&
csr_check(CSR_ALLOW_TASK_FOR_PID) &&
csr_check(CSR_ALLOW_APPLE_INTERNAL)) {
error = EPERM;
goto out2;
}
#endif

if (IS_64BIT_PROCESS(core_proc)) {
is_64 = 1;
mach_header_sz = sizeof(struct mach_header_64);
Expand Down
4 changes: 2 additions & 2 deletions bsd/kern/kern_descrip.c
Original file line number Diff line number Diff line change
Expand Up @@ -1972,7 +1972,7 @@ fcntl_nocancel(proc_t p, struct fcntl_nocancel_args *uap, int32_t *retval)

kernel_blob_size = CAST_DOWN(vm_size_t, fs.fs_blob_size);
kr = ubc_cs_blob_allocate(&kernel_blob_addr, &kernel_blob_size);
if (kr != KERN_SUCCESS) {
if (kr != KERN_SUCCESS || kernel_blob_size < fs.fs_blob_size) {
error = ENOMEM;
vnode_put(vp);
goto outdrop;
Expand All @@ -1981,7 +1981,7 @@ fcntl_nocancel(proc_t p, struct fcntl_nocancel_args *uap, int32_t *retval)
if (uap->cmd == F_ADDSIGS) {
error = copyin(fs.fs_blob_start,
(void *) kernel_blob_addr,
kernel_blob_size);
fs.fs_blob_size);
} else { /* F_ADDFILESIGS || F_ADDFILESIGS_RETURN || F_ADDFILESIGS_FOR_DYLD_SIM */
int resid;

Expand Down
50 changes: 49 additions & 1 deletion bsd/kern/kern_exec.c
Original file line number Diff line number Diff line change
Expand Up @@ -1863,6 +1863,7 @@ exec_handle_port_actions(struct image_params *imgp,
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];
Expand All @@ -1886,6 +1887,16 @@ exec_handle_port_actions(struct image_params *imgp,
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;
Expand Down Expand Up @@ -1973,6 +1984,11 @@ exec_handle_port_actions(struct image_params *imgp,
/* 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;
Expand Down Expand Up @@ -3748,6 +3764,10 @@ posix_spawn(proc_t ap, struct posix_spawn_args *uap, int32_t *retval)
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
Expand Down Expand Up @@ -5381,7 +5401,8 @@ exec_handle_sugid(struct image_params *imgp)
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:
Expand All @@ -5408,6 +5429,33 @@ exec_handle_sugid(struct image_params *imgp)
* 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,
Expand Down
Loading

0 comments on commit 7049016

Please sign in to comment.