Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys sys_link: prevent hard links on directories (cross-mount...



details:   https://anonhg.NetBSD.org/src/rev/ba3b43b93342
branches:  trunk
changeset: 764470:ba3b43b93342
user:      rmind <rmind%NetBSD.org@localhost>
date:      Sun Apr 24 21:35:29 2011 +0000

description:
sys_link: prevent hard links on directories (cross-mount operations are
already prevented).  File systems are no longer responsible to check this.
Clean up and add asserts (note that dvp == vp cannot happen in vop_link).

OK dholland@

diffstat:

 sys/fs/nilfs/nilfs_vnops.c    |  16 ++++----------
 sys/fs/tmpfs/tmpfs_vnops.c    |  46 ++++++++++++++++--------------------------
 sys/fs/udf/udf_vnops.c        |  16 ++++----------
 sys/kern/vfs_syscalls.c       |  13 +++++++----
 sys/nfs/nfs_vnops.c           |  23 +++++++--------------
 sys/ufs/ext2fs/ext2fs_vnops.c |  26 +++++++++--------------
 sys/ufs/ufs/ufs_vnops.c       |  39 ++++++++++++++----------------------
 7 files changed, 69 insertions(+), 110 deletions(-)

diffs (truncated from 379 to 300 lines):

diff -r b7aaf696f9f1 -r ba3b43b93342 sys/fs/nilfs/nilfs_vnops.c
--- a/sys/fs/nilfs/nilfs_vnops.c        Sun Apr 24 21:18:24 2011 +0000
+++ b/sys/fs/nilfs/nilfs_vnops.c        Sun Apr 24 21:35:29 2011 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: nilfs_vnops.c,v 1.9 2010/11/30 10:43:03 dholland Exp $ */
+/* $NetBSD: nilfs_vnops.c,v 1.10 2011/04/24 21:35:29 rmind Exp $ */
 
 /*
  * Copyright (c) 2008, 2009 Reinoud Zandijk
@@ -28,7 +28,7 @@
 
 #include <sys/cdefs.h>
 #ifndef lint
-__KERNEL_RCSID(0, "$NetBSD: nilfs_vnops.c,v 1.9 2010/11/30 10:43:03 dholland Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nilfs_vnops.c,v 1.10 2011/04/24 21:35:29 rmind Exp $");
 #endif /* not lint */
 
 
@@ -1159,15 +1159,9 @@
        int error;
 
        DPRINTF(VFSCALL, ("nilfs_link called\n"));
-       error = 0;
-
-       /* some quick checks */
-       if (vp->v_type == VDIR)
-               return EPERM;           /* can't link a directory */
-       if (dvp->v_mount != vp->v_mount)
-               return EXDEV;           /* can't link across devices */
-       if (dvp == vp)
-               return EPERM;           /* can't be the same */
+       KASSERT(dvp != vp);
+       KASSERT(vp->v_type != VDIR);
+       KASSERT(dvp->v_mount == vp->v_mount);
 
        /* lock node */
        error = vn_lock(vp, LK_EXCLUSIVE);
diff -r b7aaf696f9f1 -r ba3b43b93342 sys/fs/tmpfs/tmpfs_vnops.c
--- a/sys/fs/tmpfs/tmpfs_vnops.c        Sun Apr 24 21:18:24 2011 +0000
+++ b/sys/fs/tmpfs/tmpfs_vnops.c        Sun Apr 24 21:35:29 2011 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: tmpfs_vnops.c,v 1.76 2011/01/13 13:35:12 pooka Exp $   */
+/*     $NetBSD: tmpfs_vnops.c,v 1.77 2011/04/24 21:35:29 rmind Exp $   */
 
 /*
  * Copyright (c) 2005, 2006, 2007 The NetBSD Foundation, Inc.
@@ -35,7 +35,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: tmpfs_vnops.c,v 1.76 2011/01/13 13:35:12 pooka Exp $");
+__KERNEL_RCSID(0, "$NetBSD: tmpfs_vnops.c,v 1.77 2011/04/24 21:35:29 rmind Exp $");
 
 #include <sys/param.h>
 #include <sys/dirent.h>
@@ -737,44 +737,34 @@
        return error;
 }
 
-/* --------------------------------------------------------------------- */
-
+/*
+ * tmpfs:link: create hard link.
+ */
 int
 tmpfs_link(void *v)
 {
-       struct vnode *dvp = ((struct vop_link_args *)v)->a_dvp;
-       struct vnode *vp = ((struct vop_link_args *)v)->a_vp;
-       struct componentname *cnp = ((struct vop_link_args *)v)->a_cnp;
-
-       int error;
+       struct vop_link_args /* {
+               struct vnode *a_dvp;
+               struct vnode *a_vp;
+               struct componentname *a_cnp;
+       } */ *ap = v;
+       struct vnode *dvp = ap->a_dvp;
+       struct vnode *vp = ap->a_vp;
+       struct componentname *cnp = ap->a_cnp;;
+       struct tmpfs_node *dnode, *node;
        struct tmpfs_dirent *de;
-       struct tmpfs_node *dnode;
-       struct tmpfs_node *node;
+       int error;
 
+       KASSERT(dvp != vp);
        KASSERT(VOP_ISLOCKED(dvp));
-       KASSERT(dvp != vp); /* XXX When can this be false? */
+       KASSERT(vp->v_type != VDIR);
+       KASSERT(dvp->v_mount == vp->v_mount);
 
        dnode = VP_TO_TMPFS_DIR(dvp);
        node = VP_TO_TMPFS_NODE(vp);
 
-       /* Lock vp because we will need to run tmpfs_update over it, which
-        * needs the vnode to be locked. */
        vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
 
-       /* XXX: Why aren't the following two tests done by the caller? */
-
-       /* Hard links of directories are forbidden. */
-       if (vp->v_type == VDIR) {
-               error = EPERM;
-               goto out;
-       }
-
-       /* Cannot create cross-device links. */
-       if (dvp->v_mount != vp->v_mount) {
-               error = EXDEV;
-               goto out;
-       }
-
        /* Ensure that we do not overflow the maximum number of links imposed
         * by the system. */
        KASSERT(node->tn_links <= LINK_MAX);
diff -r b7aaf696f9f1 -r ba3b43b93342 sys/fs/udf/udf_vnops.c
--- a/sys/fs/udf/udf_vnops.c    Sun Apr 24 21:18:24 2011 +0000
+++ b/sys/fs/udf/udf_vnops.c    Sun Apr 24 21:35:29 2011 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: udf_vnops.c,v 1.62 2011/01/02 05:09:30 dholland Exp $ */
+/* $NetBSD: udf_vnops.c,v 1.63 2011/04/24 21:35:30 rmind Exp $ */
 
 /*
  * Copyright (c) 2006, 2008 Reinoud Zandijk
@@ -32,7 +32,7 @@
 
 #include <sys/cdefs.h>
 #ifndef lint
-__KERNEL_RCSID(0, "$NetBSD: udf_vnops.c,v 1.62 2011/01/02 05:09:30 dholland Exp $");
+__KERNEL_RCSID(0, "$NetBSD: udf_vnops.c,v 1.63 2011/04/24 21:35:30 rmind Exp $");
 #endif /* not lint */
 
 
@@ -1481,15 +1481,9 @@
        int error;
 
        DPRINTF(CALL, ("udf_link called\n"));
-       error = 0;
-
-       /* some quick checks */
-       if (vp->v_type == VDIR)
-               return EPERM;           /* can't link a directory */
-       if (dvp->v_mount != vp->v_mount)
-               return EXDEV;           /* can't link across devices */
-       if (dvp == vp)
-               return EPERM;           /* can't be the same */
+       KASSERT(dvp != vp);
+       KASSERT(vp->v_type != VDIR);
+       KASSERT(dvp->v_mount == vp->v_mount);
 
        /* lock node */
        error = vn_lock(vp, LK_EXCLUSIVE);
diff -r b7aaf696f9f1 -r ba3b43b93342 sys/kern/vfs_syscalls.c
--- a/sys/kern/vfs_syscalls.c   Sun Apr 24 21:18:24 2011 +0000
+++ b/sys/kern/vfs_syscalls.c   Sun Apr 24 21:35:29 2011 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: vfs_syscalls.c,v 1.422 2011/04/10 15:45:33 christos Exp $      */
+/*     $NetBSD: vfs_syscalls.c,v 1.423 2011/04/24 21:35:29 rmind Exp $ */
 
 /*-
  * Copyright (c) 2008, 2009 The NetBSD Foundation, Inc.
@@ -70,7 +70,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: vfs_syscalls.c,v 1.422 2011/04/10 15:45:33 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: vfs_syscalls.c,v 1.423 2011/04/24 21:35:29 rmind Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_fileassoc.h"
@@ -1767,9 +1767,12 @@
                error = EEXIST;
                goto abortop;
        }
-       /*
-        * Prevent cross-mount operation.
-        */
+       /* Prevent hard links on directories. */
+       if (vp->v_type == VDIR) {
+               error = EPERM;
+               goto abortop;
+       }
+       /* Prevent cross-mount operation. */
        if (nd.ni_dvp->v_mount != vp->v_mount) {
                error = EXDEV;
                goto abortop;
diff -r b7aaf696f9f1 -r ba3b43b93342 sys/nfs/nfs_vnops.c
--- a/sys/nfs/nfs_vnops.c       Sun Apr 24 21:18:24 2011 +0000
+++ b/sys/nfs/nfs_vnops.c       Sun Apr 24 21:35:29 2011 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: nfs_vnops.c,v 1.289 2010/12/14 16:58:58 cegger Exp $   */
+/*     $NetBSD: nfs_vnops.c,v 1.290 2011/04/24 21:35:30 rmind Exp $    */
 
 /*
  * Copyright (c) 1989, 1993
@@ -39,7 +39,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: nfs_vnops.c,v 1.289 2010/12/14 16:58:58 cegger Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nfs_vnops.c,v 1.290 2011/04/24 21:35:30 rmind Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_nfs.h"
@@ -2050,18 +2050,11 @@
        struct componentname *cnp = ap->a_cnp;
        int error = 0;
 
-       if (dvp->v_mount != vp->v_mount) {
+       error = vn_lock(vp, LK_EXCLUSIVE);
+       if (error != 0) {
                VOP_ABORTOP(dvp, cnp);
                vput(dvp);
-               return (EXDEV);
-       }
-       if (dvp != vp) {
-               error = vn_lock(vp, LK_EXCLUSIVE);
-               if (error != 0) {
-                       VOP_ABORTOP(dvp, cnp);
-                       vput(dvp);
-                       return error;
-               }
+               return error;
        }
 
        /*
@@ -2074,10 +2067,10 @@
        error = nfs_linkrpc(dvp, vp, cnp->cn_nameptr, cnp->cn_namelen,
            cnp->cn_cred, curlwp);
 
-       if (error == 0)
+       if (error == 0) {
                cache_purge1(dvp, cnp, 0);
-       if (dvp != vp)
-               VOP_UNLOCK(vp);
+       }
+       VOP_UNLOCK(vp);
        VN_KNOTE(vp, NOTE_LINK);
        VN_KNOTE(dvp, NOTE_WRITE);
        vput(dvp);
diff -r b7aaf696f9f1 -r ba3b43b93342 sys/ufs/ext2fs/ext2fs_vnops.c
--- a/sys/ufs/ext2fs/ext2fs_vnops.c     Sun Apr 24 21:18:24 2011 +0000
+++ b/sys/ufs/ext2fs/ext2fs_vnops.c     Sun Apr 24 21:35:29 2011 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: ext2fs_vnops.c,v 1.97 2011/01/02 05:09:32 dholland Exp $       */
+/*     $NetBSD: ext2fs_vnops.c,v 1.98 2011/04/24 21:35:30 rmind Exp $  */
 
 /*
  * Copyright (c) 1982, 1986, 1989, 1993
@@ -65,7 +65,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ext2fs_vnops.c,v 1.97 2011/01/02 05:09:32 dholland Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ext2fs_vnops.c,v 1.98 2011/04/24 21:35:30 rmind Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -552,7 +552,7 @@
 }
 
 /*
- * link vnode call
+ * ext2fs_link: create hard link.
  */
 int
 ext2fs_link(void *v)
@@ -568,17 +568,12 @@
        struct inode *ip;
        int error;
 
-       if (vp->v_type == VDIR) {
-               VOP_ABORTOP(dvp, cnp);
-               error = EISDIR;
-               goto out2;
-       }
-       if (dvp->v_mount != vp->v_mount) {
-               VOP_ABORTOP(dvp, cnp);
-               error = EXDEV;
-               goto out2;
-       }
-       if (dvp != vp && (error = vn_lock(vp, LK_EXCLUSIVE))) {
+       KASSERT(dvp != vp);
+       KASSERT(vp->v_type != VDIR);
+       KASSERT(dvp->v_mount == vp->v_mount);
+
+       error = vn_lock(vp, LK_EXCLUSIVE);
+       if (error) {
                VOP_ABORTOP(dvp, cnp);
                goto out2;
        }
@@ -603,8 +598,7 @@
                ip->i_flag |= IN_CHANGE;
        }
 out1:
-       if (dvp != vp)
-               VOP_UNLOCK(vp);
+       VOP_UNLOCK(vp);
 out2:



Home | Main Index | Thread Index | Old Index