untrusted comment: verify with openbsd-64-base.pub
RWQq6XmS4eDAcTJGw5eTtgnJ0uto5wJGSjUU3mC36uh90lyJQouPGxxjxLq+VunFWrUYnGvU1+xwfzlqVJdnLSVVQXGqEVLP3wA=
OpenBSD 6.4 errata 013, January 27, 2019:
The unveil() system call can leak memory.
Apply by doing:
signify -Vep /etc/signify/openbsd-64-base.pub -x 013_unveil.patch.sig \
-m - | (cd /usr/src && patch -p0)
And then rebuild and install a new kernel:
KK=`sysctl -n kern.osversion | cut -d# -f1`
cd /usr/src/sys/arch/`machine`/compile/$KK
make obj
make config
make
make install
Index: sys/kern/kern_unveil.c
===================================================================
RCS file: /cvs/src/sys/kern/kern_unveil.c,v
retrieving revision 1.15
diff -u -p -r1.15 kern_unveil.c
--- sys/kern/kern_unveil.c 25 Sep 2018 19:24:17 -0000 1.15
+++ sys/kern/kern_unveil.c 22 Jan 2019 20:49:37 -0000
@@ -525,8 +525,6 @@ unveil_add(struct proc *p, struct nameid
done:
if (ret == 0)
unveil_add_traversed_vnodes(p, ndp);
- unveil_free_traversed_vnodes(ndp);
- pool_put(&namei_pool, ndp->ni_cnd.cn_pnbuf);
return ret;
}
Index: sys/kern/vfs_syscalls.c
===================================================================
RCS file: /cvs/src/sys/kern/vfs_syscalls.c,v
retrieving revision 1.307
diff -u -p -r1.307 vfs_syscalls.c
--- sys/kern/vfs_syscalls.c 26 Sep 2018 14:51:44 -0000 1.307
+++ sys/kern/vfs_syscalls.c 22 Jan 2019 20:49:37 -0000
@@ -92,6 +92,7 @@ int dofutimens(struct proc *, int, struc
int dounmount_leaf(struct mount *, int, struct proc *);
int unveil_add(struct proc *, struct nameidata *, const char *);
void unveil_removevnode(struct vnode *vp);
+void unveil_free_traversed_vnodes(struct nameidata *);
/*
* Virtual File System System Calls
@@ -912,7 +913,7 @@ sys_unveil(struct proc *p, void *v, regi
nd.ni_pledge = PLEDGE_UNVEIL;
if ((error = namei(&nd)) != 0)
- return (error);
+ goto end;
/*
* XXX Any access to the file or directory will allow us to
@@ -922,9 +923,10 @@ sys_unveil(struct proc *p, void *v, regi
(VOP_ACCESS(nd.ni_vp, VREAD, p->p_ucred, p) == 0 ||
VOP_ACCESS(nd.ni_vp, VWRITE, p->p_ucred, p) == 0 ||
VOP_ACCESS(nd.ni_vp, VEXEC, p->p_ucred, p) == 0)) ||
- VOP_ACCESS(nd.ni_dvp, VREAD, p->p_ucred, p) == 0 ||
+ (nd.ni_dvp &&
+ (VOP_ACCESS(nd.ni_dvp, VREAD, p->p_ucred, p) == 0 ||
VOP_ACCESS(nd.ni_dvp, VWRITE, p->p_ucred, p) == 0 ||
- VOP_ACCESS(nd.ni_dvp, VEXEC, p->p_ucred, p) == 0)
+ VOP_ACCESS(nd.ni_dvp, VEXEC, p->p_ucred, p) == 0)))
error = unveil_add(p, &nd, permissions);
else
error = EPERM;
@@ -934,6 +936,10 @@ sys_unveil(struct proc *p, void *v, regi
vput(nd.ni_vp);
if (nd.ni_dvp && nd.ni_dvp != nd.ni_vp)
vput(nd.ni_dvp);
+ pool_put(&namei_pool, nd.ni_cnd.cn_pnbuf);
+end:
+ unveil_free_traversed_vnodes(&nd);
+
return (error);
}