Synopsis: noexec mount flag is not properly handled by non-root mount
NetBSD versions: NetBSD 1.3.3 and prior; NetBSD-current until 19990318
Thanks to: Manuel Bouyer
Reported in NetBSD Security Advisory: SA1999-007
This patch fixes the non-root mount problem described in the NetBSD-SA1999-007
security advisory. For it to apply, make sure you have NetBSD 1.3.3 kernel
sources unpacked in /usr/src, then do:
% cd /usr/src/sys
% patch <19990317-mount
% cd arch/`uname -m`/conf
% config GENERIC
% cd ../compile/GENERIC
% make depend && make
% su root
# mv /netbsd /netbsd.old
# cp netbsd /
# chmod 444 /netbsd
# sync; reboot
Index: kern/vfs_syscalls.c
===================================================================
RCS file: /archive/cvs/cvsroot/NetBSD/src/sys/kern/vfs_syscalls.c,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 vfs_syscalls.c
--- vfs_syscalls.c 1997/12/15 16:49:57 1.1.1.1
+++ vfs_syscalls.c 1999/03/17 16:29:35
@@ -163,8 +163,9 @@
return (error);
}
/*
- * Do not allow NFS export by non-root users. Silently
- * enforce MNT_NOSUID and MNT_NODEV for non-root users.
+ * Do not allow NFS export by non-root users. For non-root
+ * users, silently enforce MNT_NOSUID and MNT_NODEV, and
+ * MNT_NOEXEC if mount point is already MNT_NOEXEC.
*/
if (p->p_ucred->cr_uid != 0) {
if (SCARG(uap, flags) & MNT_EXPORTED) {
@@ -172,6 +173,8 @@
return (EPERM);
}
SCARG(uap, flags) |= MNT_NOSUID | MNT_NODEV;
+ if (flag & MNT_NOEXEC)
+ SCARG(uap, flags) |= MNT_NOEXEC;
}
VOP_UNLOCK(vp);
goto update;
@@ -187,8 +190,9 @@
return (error);
}
/*
- * Do not allow NFS export by non-root users. Silently
- * enforce MNT_NOSUID and MNT_NODEV for non-root users.
+ * Do not allow NFS export by non-root users. For non-root users,
+ * silently enforce MNT_NOSUID and MNT_NODEV, and MNT_NOEXEC if the
+ * mount point is already MNT_NOEXEC.
*/
if (p->p_ucred->cr_uid != 0) {
if (SCARG(uap, flags) & MNT_EXPORTED) {
@@ -196,6 +200,8 @@
return (EPERM);
}
SCARG(uap, flags) |= MNT_NOSUID | MNT_NODEV;
+ if (vp->v_mount->mnt_flag & MNT_NOEXEC)
+ SCARG(uap, flags) |= MNT_NOEXEC;
}
if ((error = vinvalbuf(vp, V_SAVE, p->p_ucred, p, 0, 0)) != 0)
return (error);