Date: Mon, 28 Dec 2020 21:39:33 GMT From: Mateusz Guzik <mjg@FreeBSD.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org Subject: git: 0c09f4b0cc63 - main - cache: work around corner case of dvp == tvp in cache_fplookup_final_modifying Message-ID: <202012282139.0BSLdXRR083086@gitrepo.freebsd.org>
next in thread | raw e-mail | index | archive | help
The branch main has been updated by mjg: URL: https://cgit.FreeBSD.org/src/commit/?id=0c09f4b0cc633750a3cbf724e8590ed9d4ef92e1 commit 0c09f4b0cc633750a3cbf724e8590ed9d4ef92e1 Author: Mateusz Guzik <mjg@FreeBSD.org> AuthorDate: 2020-12-28 21:24:53 +0000 Commit: Mateusz Guzik <mjg@FreeBSD.org> CommitDate: 2020-12-28 21:38:20 +0000 cache: work around corner case of dvp == tvp in cache_fplookup_final_modifying Fixes a panic where the kernel would unlock an unheld lock coming from rename looking up "foo/." as the source. Reported by: markj (syzkaller) --- sys/kern/vfs_cache.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/sys/kern/vfs_cache.c b/sys/kern/vfs_cache.c index 4513e4dc970f..94d622867425 100644 --- a/sys/kern/vfs_cache.c +++ b/sys/kern/vfs_cache.c @@ -4063,6 +4063,19 @@ cache_fplookup_final_modifying(struct cache_fpl *fpl) return (cache_fpl_handled(fpl, 0)); } + /* + * There are very hairy corner cases concerning various flag combinations + * and locking state. In particular here we only hold one lock instead of + * two. + * + * Skip the complexity as it is of no significance for normal workloads. + */ + if (__predict_false(tvp == dvp)) { + vput(dvp); + vrele(tvp); + return (cache_fpl_aborted(fpl)); + } + /* * Check if the target is either a symlink or a mount point. * Since we expect this to be the terminal vnode it should
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202012282139.0BSLdXRR083086>