Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 24 Sep 2023 21:47:02 GMT
From:      Mateusz Guzik <mjg@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org
Subject:   git: aaeaba324335 - releng/14.0 - vfs: fix reference counting/locking on LK_UPGRADE error
Message-ID:  <202309242147.38OLl2iv031000@gitrepo.freebsd.org>

next in thread | raw e-mail | index | archive | help
The branch releng/14.0 has been updated by mjg:

URL: https://cgit.FreeBSD.org/src/commit/?id=aaeaba3243354f02a7a7c4ff519efd88edc22572

commit aaeaba3243354f02a7a7c4ff519efd88edc22572
Author:     Olivier Certner <olce.freebsd@certner.fr>
AuthorDate: 2023-09-22 20:57:20 +0000
Commit:     Mateusz Guzik <mjg@FreeBSD.org>
CommitDate: 2023-09-24 21:46:25 +0000

    vfs: fix reference counting/locking on LK_UPGRADE error
    
    Factoring out this code unfortunately introduced reference and lock leaks in
    case of failure in the lock upgrade path under VV_CROSSLOCK. In terms of
    practical use, this impacts unionfs (and nullfs in a corner case).
    
    Fixes:          80bd5ef07025 ("vfs: factor out mount point traversal to a dedicated routine")
    MFC after:      3 days
    MFC to:         stable/14 releng/14.0
    Sponsored by:   The FreeBSD Foundation
    Reviewed by:    mjg
    [mjg: massaged the commit message a little bit]
    
    Differential Revision: https://reviews.freebsd.org/D41731
    Approved by:    re (gjb)
    (cherry picked from commit 02cbc029dac936b4ddbc38cef969c4b30c9a7d1f)
    (cherry picked from commit c76dfb929e70c80a2d0280a1371c07738d910c11)
---
 sys/kern/vfs_lookup.c | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/sys/kern/vfs_lookup.c b/sys/kern/vfs_lookup.c
index 151253ffa0f5..d75351c34314 100644
--- a/sys/kern/vfs_lookup.c
+++ b/sys/kern/vfs_lookup.c
@@ -905,8 +905,15 @@ vfs_lookup_cross_mount(struct nameidata *ndp)
 				crosslkflags |= LK_EXCLUSIVE | LK_CANRECURSE;
 			} else if ((crosslkflags & LK_EXCLUSIVE) != 0) {
 				error = vn_lock(dp, LK_UPGRADE);
-				if (error != 0)
+				if (error != 0) {
+					MPASS(error == ENOENT);
+					vrele(dp);
+					if (dp != ndp->ni_dvp)
+						vput(ndp->ni_dvp);
+					else
+						vrele(ndp->ni_dvp);
 					break;
+				}
 				if (dp->v_mountedhere != mp) {
 					continue;
 				}



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202309242147.38OLl2iv031000>