From 4d0caa417ef788ae46f25708d7c20334cfb8c596 Mon Sep 17 00:00:00 2001 From: deraadt Date: Sat, 31 Aug 2024 15:52:09 +0000 Subject: [PATCH] jeremy observed that access() on unveiled space was returning errors for valid requests. This is because the nd.ni_unveil to namei() was always UNVEIL_READ, regardless of the request amode. Building a correct ni_unveil passes a new regression test, producing expected results. ok beck jeremy --- sys/kern/vfs_syscalls.c | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/sys/kern/vfs_syscalls.c b/sys/kern/vfs_syscalls.c index e131165b936..6e1eb2d0c6c 100644 --- a/sys/kern/vfs_syscalls.c +++ b/sys/kern/vfs_syscalls.c @@ -1,4 +1,4 @@ -/* $OpenBSD: vfs_syscalls.c,v 1.366 2024/07/10 09:12:11 krw Exp $ */ +/* $OpenBSD: vfs_syscalls.c,v 1.367 2024/08/31 15:52:09 deraadt Exp $ */ /* $NetBSD: vfs_syscalls.c,v 1.71 1996/04/23 10:29:02 mycroft Exp $ */ /* @@ -1971,7 +1971,7 @@ dofaccessat(struct proc *p, int fd, const char *path, int amode, int flag) struct vnode *vp; struct ucred *newcred, *oldcred; struct nameidata nd; - int error; + int vflags = 0, error; if (amode & ~(R_OK | W_OK | X_OK)) return (EINVAL); @@ -1996,21 +1996,22 @@ dofaccessat(struct proc *p, int fd, const char *path, int amode, int flag) NDINITAT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_USERSPACE, fd, path, p); nd.ni_pledge = PLEDGE_RPATH; nd.ni_unveil = UNVEIL_READ; + if (amode & R_OK) + vflags |= VREAD; + if (amode & W_OK) { + vflags |= VWRITE; + nd.ni_unveil |= UNVEIL_WRITE; + } + if (amode & X_OK) { + vflags |= VEXEC; + nd.ni_unveil |= UNVEIL_EXEC; + } if ((error = namei(&nd)) != 0) goto out; vp = nd.ni_vp; /* Flags == 0 means only check for existence. */ if (amode) { - int vflags = 0; - - if (amode & R_OK) - vflags |= VREAD; - if (amode & W_OK) - vflags |= VWRITE; - if (amode & X_OK) - vflags |= VEXEC; - error = VOP_ACCESS(vp, vflags, p->p_ucred, p); if (!error && (vflags & VWRITE)) error = vn_writechk(vp); -- 2.20.1