diff options
author | Olivier Certner <olce.freebsd@certner.fr> | 2023-09-22 20:57:20 +0000 |
---|---|---|
committer | Mateusz Guzik <mjg@FreeBSD.org> | 2023-09-24 10:44:11 +0000 |
commit | c76dfb929e70c80a2d0280a1371c07738d910c11 (patch) | |
tree | a64abaf17e0814b77fc72ed0667dd50398ea4b68 | |
parent | bb438c08b86a32f13da16b2e7801f2cbd45bc5c1 (diff) | |
download | src-c76dfb929e70c80a2d0280a1371c07738d910c11.tar.gz src-c76dfb929e70c80a2d0280a1371c07738d910c11.zip |
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)
-rw-r--r-- | sys/kern/vfs_lookup.c | 9 |
1 files changed, 8 insertions, 1 deletions
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; } |