From 472fe5e4db46fa756bbe9f2640fdb362b6c851e6 Mon Sep 17 00:00:00 2001 From: Peter Wemm Date: Fri, 24 May 1996 16:19:23 +0000 Subject: [PATCH] Dont allow directories to be link()ed or unlink()ed, even for root (returns EPERM always, the errno is specified by POSIX). If you really have a desperate need to link or unlink a directory, you can use fsdb. :-) This should stop any chance of ftpd, rdist, "rm -rf", etc from bugging out and damaging the filesystem structure or loosing races with malicious users. Reviewed by: davidg, bde --- sys/kern/vfs_extattr.c | 16 +++++++++------- sys/kern/vfs_syscalls.c | 16 +++++++++------- 2 files changed, 18 insertions(+), 14 deletions(-) diff --git a/sys/kern/vfs_extattr.c b/sys/kern/vfs_extattr.c index ec728b3d57f3..95e9de03dfe0 100644 --- a/sys/kern/vfs_extattr.c +++ b/sys/kern/vfs_extattr.c @@ -36,7 +36,7 @@ * SUCH DAMAGE. * * @(#)vfs_syscalls.c 8.13 (Berkeley) 4/15/94 - * $Id: vfs_syscalls.c,v 1.46 1996/01/16 13:07:14 davidg Exp $ + * $Id: vfs_syscalls.c,v 1.47 1996/05/11 04:39:53 bde Exp $ */ /* @@ -886,11 +886,10 @@ link(p, uap, retval) if (error) return (error); vp = nd.ni_vp; - if (vp->v_type != VDIR || - (error = suser(p->p_ucred, &p->p_acflag)) == 0) { + if (vp->v_type == VDIR) + error = EPERM; /* POSIX */ + else { NDINIT(&nd, CREATE, LOCKPARENT, UIO_USERSPACE, uap->link, p); - if (vp->v_type == VDIR) - nd.ni_cnd.cn_flags |= WILLBEDIR; error = namei(&nd); if (!error) { if (nd.ni_vp != NULL) { @@ -990,10 +989,13 @@ unlink(p, uap, retval) LEASE_CHECK(vp, p, p->p_ucred, LEASE_WRITE); VOP_LOCK(vp); - if (vp->v_type != VDIR || - (error = suser(p->p_ucred, &p->p_acflag)) == 0) { + if (vp->v_type == VDIR) + error = EPERM; /* POSIX */ + else { /* * The root of a mounted filesystem cannot be deleted. + * + * XXX: can this only be a VDIR case? */ if (vp->v_flag & VROOT) error = EBUSY; diff --git a/sys/kern/vfs_syscalls.c b/sys/kern/vfs_syscalls.c index ec728b3d57f3..95e9de03dfe0 100644 --- a/sys/kern/vfs_syscalls.c +++ b/sys/kern/vfs_syscalls.c @@ -36,7 +36,7 @@ * SUCH DAMAGE. * * @(#)vfs_syscalls.c 8.13 (Berkeley) 4/15/94 - * $Id: vfs_syscalls.c,v 1.46 1996/01/16 13:07:14 davidg Exp $ + * $Id: vfs_syscalls.c,v 1.47 1996/05/11 04:39:53 bde Exp $ */ /* @@ -886,11 +886,10 @@ link(p, uap, retval) if (error) return (error); vp = nd.ni_vp; - if (vp->v_type != VDIR || - (error = suser(p->p_ucred, &p->p_acflag)) == 0) { + if (vp->v_type == VDIR) + error = EPERM; /* POSIX */ + else { NDINIT(&nd, CREATE, LOCKPARENT, UIO_USERSPACE, uap->link, p); - if (vp->v_type == VDIR) - nd.ni_cnd.cn_flags |= WILLBEDIR; error = namei(&nd); if (!error) { if (nd.ni_vp != NULL) { @@ -990,10 +989,13 @@ unlink(p, uap, retval) LEASE_CHECK(vp, p, p->p_ucred, LEASE_WRITE); VOP_LOCK(vp); - if (vp->v_type != VDIR || - (error = suser(p->p_ucred, &p->p_acflag)) == 0) { + if (vp->v_type == VDIR) + error = EPERM; /* POSIX */ + else { /* * The root of a mounted filesystem cannot be deleted. + * + * XXX: can this only be a VDIR case? */ if (vp->v_flag & VROOT) error = EBUSY;