git: c76dfb929e70 - stable/14 - vfs: fix reference counting/locking on LK_UPGRADE error

From: Mateusz Guzik <mjg_at_FreeBSD.org>
Date: Sun, 24 Sep 2023 10:44:20 UTC
The branch stable/14 has been updated by mjg:

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

commit c76dfb929e70c80a2d0280a1371c07738d910c11
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 10:44:11 +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
    
    (cherry picked from commit 02cbc029dac936b4ddbc38cef969c4b30c9a7d1f)
---
 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;
 				}