Source-Changes-HG archive

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

[src/trunk]: src/sys/fs/udf Fix locking in udf_link(). XXX: udf_symlink is pr...



details:   https://anonhg.NetBSD.org/src/rev/a87308285a1b
branches:  trunk
changeset: 364579:a87308285a1b
user:      christos <christos%NetBSD.org@localhost>
date:      Wed Mar 30 13:23:59 2022 +0000

description:
Fix locking in udf_link(). XXX: udf_symlink is prolly similarly broken.

diffstat:

 sys/fs/udf/udf_vnops.c |  79 +++++++++++++++++++++++--------------------------
 1 files changed, 37 insertions(+), 42 deletions(-)

diffs (110 lines):

diff -r 3882ffab6c23 -r a87308285a1b sys/fs/udf/udf_vnops.c
--- a/sys/fs/udf/udf_vnops.c    Wed Mar 30 12:45:58 2022 +0000
+++ b/sys/fs/udf/udf_vnops.c    Wed Mar 30 13:23:59 2022 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: udf_vnops.c,v 1.120 2022/03/27 16:24:58 christos Exp $ */
+/* $NetBSD: udf_vnops.c,v 1.121 2022/03/30 13:23:59 christos 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.120 2022/03/27 16:24:58 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: udf_vnops.c,v 1.121 2022/03/30 13:23:59 christos Exp $");
 #endif /* not lint */
 
 
@@ -1542,43 +1542,6 @@
 
 /* --------------------------------------------------------------------- */
 
-static int
-udf_do_link(struct vnode *dvp, struct vnode *vp, struct componentname *cnp)
-{
-       struct udf_node *udf_node, *dir_node;
-       struct vattr vap;
-       int error;
-
-       DPRINTF(CALL, ("udf_link called\n"));
-       KASSERT(dvp != vp);
-       KASSERT(vp->v_type != VDIR);
-       KASSERT(dvp->v_mount == vp->v_mount);
-
-       /* get attributes */
-       dir_node = VTOI(dvp);
-       udf_node = VTOI(vp);
-
-       error = VOP_GETATTR(vp, &vap, FSCRED);
-       if (error)
-               goto out;
-
-       /* check link count overflow */
-       if (vap.va_nlink >= (1<<16)-1) {        /* uint16_t */
-               error = EMLINK;
-               goto out;
-       }
-       error = kauth_authorize_vnode(cnp->cn_cred, KAUTH_VNODE_ADD_LINK, vp,
-           dvp, 0);
-       if (error)
-               goto out;
-
-       error = udf_dir_attach(dir_node->ump, dir_node, udf_node, &vap, cnp);
-out:
-       if (error)
-               VOP_UNLOCK(vp);
-       return error;
-}
-
 int
 udf_link(void *v)
 {
@@ -1590,12 +1553,44 @@
        struct vnode *dvp = ap->a_dvp;
        struct vnode *vp  = ap->a_vp;
        struct componentname *cnp = ap->a_cnp;
-       int error;
+       struct udf_node *udf_node, *dir_node;
+       struct vattr vap;
+       int error, abrt = 1;
+
+       DPRINTF(CALL, ("udf_link called\n"));
+       KASSERT(dvp != vp);
+       KASSERT(vp->v_type != VDIR);
+       KASSERT(dvp->v_mount == vp->v_mount);
+
+       /* get attributes */
+       dir_node = VTOI(dvp);
+       udf_node = VTOI(vp);
+
+       if ((error = vn_lock(vp, LK_EXCLUSIVE))) {
+               DPRINTF("lock failed. %p\n", vp);
+               goto out;
+       }
 
-       error = udf_do_link(dvp, vp, cnp);
+       error = VOP_GETATTR(vp, &vap, FSCRED);
        if (error)
+               goto out1;
+
+       /* check link count overflow */
+       if (vap.va_nlink >= (1<<16)-1) {        /* uint16_t */
+               error = EMLINK;
+               goto out1;
+       }
+       error = kauth_authorize_vnode(cnp->cn_cred, KAUTH_VNODE_ADD_LINK, vp,
+           dvp, 0);
+       if (error)
+               goto out1;
+       abrt = 0;
+       error = udf_dir_attach(dir_node->ump, dir_node, udf_node, &vap, cnp);
+out1:
+       VOP_UNLOCK(vp);
+out:
+       if (abrt)
                VOP_ABORTOP(dvp, cnp);
-
        return error;
 }
 



Home | Main Index | Thread Index | Old Index