From fe520198e60de265c97be1762847d7db3a609960 Mon Sep 17 00:00:00 2001 From: beck Date: Fri, 20 Jul 2018 07:28:36 +0000 Subject: [PATCH] Correctly copy across unveil's from parent to child process on fork(). --- sys/kern/kern_fork.c | 17 +++--------- sys/kern/kern_unveil.c | 60 +++++++++++++++++++++++++----------------- 2 files changed, 40 insertions(+), 37 deletions(-) diff --git a/sys/kern/kern_fork.c b/sys/kern/kern_fork.c index 2e2349ea54c..94ac3ead4ac 100644 --- a/sys/kern/kern_fork.c +++ b/sys/kern/kern_fork.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kern_fork.c,v 1.204 2018/07/13 09:25:23 beck Exp $ */ +/* $OpenBSD: kern_fork.c,v 1.205 2018/07/20 07:28:36 beck Exp $ */ /* $NetBSD: kern_fork.c,v 1.29 1996/02/09 18:59:34 christos Exp $ */ /* @@ -75,7 +75,7 @@ pid_t alloctid(void); pid_t allocpid(void); int ispidtaken(pid_t); -struct unveil *unveil_copy(struct process *s, size_t *count); +void unveil_copy(struct process *parent, struct process *child); struct proc *thread_new(struct proc *_parent, vaddr_t _uaddr); struct process *process_new(struct proc *, struct process *, int); @@ -237,18 +237,9 @@ process_new(struct proc *p, struct process *parent, int flags) pr->ps_textvp = parent->ps_textvp; if (pr->ps_textvp) vref(pr->ps_textvp); -#if 0 /* XXX Fix this */ + /* copy unveil if unveil is active */ - if (parent->ps_uvvcount) { - pr->ps_uvpaths = unveil_copy(parent, &pr->ps_uvncount); - if (parent->ps_uvpcwd) - pr->ps_uvpcwd = pr->ps_uvpaths + - (parent->ps_uvpcwd - parent->ps_uvpaths); - pr->ps_uvpcwdgone = parent->ps_uvpcwdgone; - pr->ps_uvdone = parent->ps_uvdone; - pr->ps_uvshrink = 1; - } -#endif + unveil_copy(parent, pr); pr->ps_flags = parent->ps_flags & (PS_SUGID | PS_SUGIDEXEC | PS_PLEDGE | PS_EXECPLEDGE | PS_WXNEEDED); diff --git a/sys/kern/kern_unveil.c b/sys/kern/kern_unveil.c index e52f912c51a..e906505c54f 100644 --- a/sys/kern/kern_unveil.c +++ b/sys/kern/kern_unveil.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kern_unveil.c,v 1.3 2018/07/17 07:43:34 krw Exp $ */ +/* $OpenBSD: kern_unveil.c,v 1.4 2018/07/20 07:28:36 beck Exp $ */ /* * Copyright (c) 2017-2018 Bob Beck @@ -108,6 +108,9 @@ unveil_delete_names(struct unveil *uv) ret++; } rw_exit_write(&uv->uv_lock); +#ifdef DEBUG_UNVEIL + printf("deleted %d names\n", ret); +#endif return ret; } @@ -121,7 +124,7 @@ unveil_add_name(struct unveil *uv, char *name, uint64_t flags) RBT_INSERT(unvname_rbt, &uv->uv_names, unvn); rw_exit_write(&uv->uv_lock); #ifdef DEBUG_UNVEIL - printf("added name %s\n", name); + printf("added name %s underneath vnode %p\n", name, uv->uv_vp); #endif } @@ -188,40 +191,49 @@ unveil_destroy(struct process *ps) ps->ps_uvpaths = NULL; } -struct unveil * -unveil_copy(struct process *ps, size_t *count) +void +unveil_copy(struct process *parent, struct process *child) { - struct unveil *ret; size_t i; - ret = mallocarray(UNVEIL_MAX_VNODES, sizeof(struct unveil), + if (parent->ps_uvvcount == 0) + return; + + child->ps_uvpaths = mallocarray(UNVEIL_MAX_VNODES, sizeof(struct unveil), M_PROC, M_WAITOK|M_ZERO); - *count = 0; - for (i = 0; ps->ps_uvpaths != NULL && i < ps->ps_uvvcount; i++) { - struct unveil *uv = ps->ps_uvpaths + i; + child->ps_uvncount = 0; + for (i = 0; parent->ps_uvpaths != NULL && i < parent->ps_uvvcount; + i++) { + struct unveil *from = parent->ps_uvpaths + i; + struct unveil *to = child->ps_uvpaths + i; struct unvname *unvn, *next; - ret[i].uv_vp = uv->uv_vp; - if (ret[i].uv_vp != NULL) { - vref(ret[i].uv_vp); - ret[i].uv_vp->v_uvcount++; + to->uv_vp = from->uv_vp; + if (to->uv_vp != NULL) { + vref(to->uv_vp); + to->uv_vp->v_uvcount++; } - rw_init(&ret[i].uv_lock, "unveil"); - RBT_INIT(unvname_rbt, &ret[i].uv_names); - rw_enter_read(&uv->uv_lock); - RBT_FOREACH_SAFE(unvn, unvname_rbt, &uv->uv_names, next) { - unveil_add_name(&ret[i], unvn->un_name, unvn->un_flags); - (*count)++; + rw_init(&to->uv_lock, "unveil"); + RBT_INIT(unvname_rbt, &to->uv_names); + rw_enter_read(&from->uv_lock); + RBT_FOREACH_SAFE(unvn, unvname_rbt, &from->uv_names, next) { + unveil_add_name(&child->ps_uvpaths[i], unvn->un_name, + unvn->un_flags); + child->ps_uvncount++; } - printf("count now %ld\n", *count); - rw_exit_read(&uv->uv_lock); - ret[i].uv_flags = uv->uv_flags; + rw_exit_read(&from->uv_lock); + to->uv_flags = from->uv_flags; } - return(ret); + child->ps_uvvcount = parent->ps_uvvcount; + if (parent->ps_uvpcwd) + child->ps_uvpcwd = child->ps_uvpaths + + (parent->ps_uvpcwd - parent->ps_uvpaths); + child->ps_uvpcwdgone = parent->ps_uvpcwdgone; + child->ps_uvdone = parent->ps_uvdone; + child->ps_uvshrink = parent->ps_uvshrink; } - struct unveil * unveil_lookup(struct vnode *vp, struct proc *p) { -- 2.20.1