-/* $OpenBSD: kern_unveil.c,v 1.45 2021/06/29 07:55:29 claudio Exp $ */
+/* $OpenBSD: kern_unveil.c,v 1.46 2021/07/08 13:33:05 claudio Exp $ */
/*
* Copyright (c) 2017-2019 Bob Beck <beck@openbsd.org>
return ret;
}
-void
-unveil_free_traversed_vnodes(struct nameidata *ndp)
-{
- if (ndp->ni_tvpsize) {
- size_t i;
-
- for (i = 0; i < ndp->ni_tvpend; i++)
- vrele(ndp->ni_tvp[i]); /* ref for being in list */
- free(ndp->ni_tvp, M_PROC, ndp->ni_tvpsize *
- sizeof(struct vnode *));
- ndp->ni_tvpsize = 0;
- ndp->ni_tvpend = 0;
- }
-}
-
-void
-unveil_save_traversed_vnode(struct nameidata *ndp, struct vnode *vp)
-{
- if (ndp->ni_tvpsize == 0) {
- ndp->ni_tvp = mallocarray(MAXPATHLEN, sizeof(struct vnode *),
- M_PROC, M_WAITOK);
- ndp->ni_tvpsize = MAXPATHLEN;
- }
- /* This should be limited by MAXPATHLEN on a single lookup */
- KASSERT(ndp->ni_tvpsize > ndp->ni_tvpend);
- vref(vp); /* ref for being in the list */
- ndp->ni_tvp[ndp->ni_tvpend++] = vp;
-}
-
void
unvname_delete(struct unvname *name)
{
return (uv);
}
-void
-unveil_add_traversed_vnodes(struct proc *p, struct nameidata *ndp)
-{
- if (ndp->ni_tvpsize) {
- size_t i;
-
- for (i = 0; i < ndp->ni_tvpend; i++) {
- struct vnode *vp = ndp->ni_tvp[i];
- if (unveil_lookup(vp, p->p_p, NULL) == NULL) {
- vref(vp);
- vp->v_uvcount++;
- unveil_add_vnode(p, vp);
- }
- }
- }
-}
-
int
unveil_add(struct proc *p, struct nameidata *ndp, const char *permissions)
{
sizeof(struct unveil), M_PROC, M_WAITOK|M_ZERO);
}
- if ((pr->ps_uvvcount + ndp->ni_tvpend) >= UNVEIL_MAX_VNODES ||
+ if (pr->ps_uvvcount >= UNVEIL_MAX_VNODES ||
pr->ps_uvncount >= UNVEIL_MAX_NAMES) {
ret = E2BIG;
goto done;
#endif
done:
- if (ret == 0)
- unveil_add_traversed_vnodes(p, ndp);
-
pr->ps_uvpcwd = unveil_lookup(p->p_fd->fd_cdir, pr, NULL);
if (pr->ps_uvpcwd == NULL) {
ssize_t i;
struct process *pr = p->p_p;
struct unveil *uv = NULL;
- if (ni->ni_pledge == PLEDGE_UNVEIL) {
- unveil_save_traversed_vnode(ni, dp);
+ if (ni->ni_pledge == PLEDGE_UNVEIL || pr->ps_uvpaths == NULL)
return;
- }
if (ni->ni_cnd.cn_flags & BYPASSUNVEIL)
return;
-/* $OpenBSD: vfs_syscalls.c,v 1.350 2021/07/03 17:51:59 semarie Exp $ */
+/* $OpenBSD: vfs_syscalls.c,v 1.351 2021/07/08 13:33:05 claudio Exp $ */
/* $NetBSD: vfs_syscalls.c,v 1.71 1996/04/23 10:29:02 mycroft Exp $ */
/*
nd.ni_pledge = PLEDGE_UNVEIL;
if ((error = namei(&nd)) != 0)
- goto ndfree;
+ goto end;
/*
* XXX Any access to the file or directory will allow us to
vrele(nd.ni_dvp);
pool_put(&namei_pool, nd.ni_cnd.cn_pnbuf);
-ndfree:
- unveil_free_traversed_vnodes(&nd);
end:
pool_put(&namei_pool, pathname);
-/* $OpenBSD: namei.h,v 1.45 2020/03/19 13:55:20 anton Exp $ */
+/* $OpenBSD: namei.h,v 1.46 2021/07/08 13:33:05 claudio Exp $ */
/* $NetBSD: namei.h,v 1.11 1996/02/09 18:25:20 christos Exp $ */
/*
char *ni_next; /* next location in pathname */
u_long ni_loopcnt; /* count of symlinks encountered */
struct unveil *ni_unveil_match; /* last matching unveil component */
- struct vnode **ni_tvp; /* traversed vnodes */
- size_t ni_tvpend; /* end of traversed vnode list */
- size_t ni_tvpsize; /* size of traversed vnode list */
int ni_unveil_eacces; /* indicates unveil flag mismatch */
/*
int unveil_add(struct proc *, struct nameidata *, const char *);
void unveil_removevnode(struct vnode *);
-void unveil_free_traversed_vnodes(struct nameidata *);
ssize_t unveil_find_cover(struct vnode *, struct proc *);
struct unveil *unveil_lookup(struct vnode *, struct process *, ssize_t *);
void unveil_start_relative(struct proc *, struct nameidata *, struct vnode *);