From 10478431668390c5c50729d40b7862f640658090 Mon Sep 17 00:00:00 2001 From: claudio Date: Tue, 29 Jun 2021 07:55:29 +0000 Subject: [PATCH] Adjust unveil_find_cover() to return -1 if the root vnode is passed in. This helps unveil_add_vnode() to properly re-evaluate unveils when "/" is added to the list. Because of this adjust unveil_covered() to check for the root as well so that in that case the unveil uv is returned instead of NULL. Traversing up from the root returns the root. This check is not really needed since namei has its own root check and shortcuts for root vnodes. OK semarie@ --- sys/kern/kern_unveil.c | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/sys/kern/kern_unveil.c b/sys/kern/kern_unveil.c index 536208c6678..b541c9ca2f7 100644 --- a/sys/kern/kern_unveil.c +++ b/sys/kern/kern_unveil.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kern_unveil.c,v 1.44 2021/06/24 07:21:59 semarie Exp $ */ +/* $OpenBSD: kern_unveil.c,v 1.45 2021/06/29 07:55:29 claudio Exp $ */ /* * Copyright (c) 2017-2019 Bob Beck @@ -274,7 +274,7 @@ unveil_copy(struct process *parent, struct process *child) /* * Walk up from vnode dp, until we find a matching unveil, or the root vnode - * returns -1 if no unveil to be found above dp. + * returns -1 if no unveil to be found above dp or if dp is the root vnode. */ ssize_t unveil_find_cover(struct vnode *dp, struct proc *p) @@ -287,7 +287,7 @@ unveil_find_cover(struct vnode *dp, struct proc *p) root = p->p_fd->fd_rdir ? p->p_fd->fd_rdir : rootvnode; vp = dp; - do { + while (vp != root) { struct componentname cn = { .cn_nameiop = LOOKUP, .cn_flags = ISLASTCN | ISDOTDOT | RDONLY, @@ -343,7 +343,7 @@ unveil_find_cover(struct vnode *dp, struct proc *p) } vp = parent; parent = NULL; - } while (vp != root); + } return ret; } @@ -666,13 +666,20 @@ unveil_flagmatch(struct nameidata *ni, u_char flags) return 1; } - +/* + * When traversing up towards the root figure out the proper unveil for + * the parent directory. + */ struct unveil * -unveil_covered(struct unveil *uv, struct vnode *dvp, struct process *pr) { +unveil_covered(struct unveil *uv, struct vnode *dvp, struct proc *p) +{ if (uv && uv->uv_vp == dvp) { + /* if at the root, chrooted or not, return the current uv */ + if (dvp == (p->p_fd->fd_rdir ? p->p_fd->fd_rdir : rootvnode)) + return uv; if (uv->uv_cover >=0) { - KASSERT(uv->uv_cover < pr->ps_uvvcount); - return &pr->ps_uvpaths[uv->uv_cover]; + KASSERT(uv->uv_cover < p->p_p->ps_uvvcount); + return &p->p_p->ps_uvpaths[uv->uv_cover]; } return NULL; } @@ -758,7 +765,7 @@ unveil_check_component(struct proc *p, struct nameidata *ni, struct vnode *dp) /* * adjust unveil match as necessary */ - uv = unveil_covered(ni->ni_unveil_match, dp, pr); + uv = unveil_covered(ni->ni_unveil_match, dp, p); /* clear the match when we DOTDOT above it */ if (ni->ni_unveil_match && -- 2.20.1