git: f8fc6a086e55 - stable/15 - rename(2): do not allow to rename root vnode of the mounted filesystem

From: Konstantin Belousov <kib_at_FreeBSD.org>
Date: Sat, 13 Jun 2026 01:03:49 UTC
The branch stable/15 has been updated by kib:

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

commit f8fc6a086e559855243ef3d2ffda35e1ae0e7d71
Author:     Konstantin Belousov <kib@FreeBSD.org>
AuthorDate: 2026-06-04 19:56:36 +0000
Commit:     Konstantin Belousov <kib@FreeBSD.org>
CommitDate: 2026-06-13 00:58:34 +0000

    rename(2): do not allow to rename root vnode of the mounted filesystem
    
    PR:     295826
    
    (cherry picked from commit d53633bfcf24a3eb3711e24b597aa8301f92b958)
---
 sys/kern/vfs_lookup.c   | 2 +-
 sys/kern/vfs_syscalls.c | 9 +++++++++
 sys/sys/vnode.h         | 1 +
 3 files changed, 11 insertions(+), 1 deletion(-)

diff --git a/sys/kern/vfs_lookup.c b/sys/kern/vfs_lookup.c
index fb3e6a7a2534..addabb45e271 100644
--- a/sys/kern/vfs_lookup.c
+++ b/sys/kern/vfs_lookup.c
@@ -113,7 +113,7 @@ SDT_PROBE_DEFINE4(vfs, namei, lookup, return, "int", "struct vnode *", "bool",
 uma_zone_t namei_zone;
 
 /* Placeholder vnode for mp traversal. */
-static struct vnode *vp_crossmp;
+struct vnode *vp_crossmp;
 
 static int
 crossmp_vop_islocked(struct vop_islocked_args *ap)
diff --git a/sys/kern/vfs_syscalls.c b/sys/kern/vfs_syscalls.c
index 2516155cc1a3..ef3f7b3e8184 100644
--- a/sys/kern/vfs_syscalls.c
+++ b/sys/kern/vfs_syscalls.c
@@ -3823,6 +3823,15 @@ again:
 	}
 	tdvp = tond.ni_dvp;
 	tvp = tond.ni_vp;
+	if (tdvp == vp_crossmp) {
+		/*
+		 * Rename of the root vnode of the mounted
+		 * filesystem. It is possible to get there with the
+		 * nullfs mount over the regular file.
+		 */
+		error = EBUSY;
+		goto out;
+	}
 	if (tvp != NULL && (flags & AT_RENAME_NOREPLACE) != 0) {
 		/*
 		 * Often filesystems need to relock the vnodes in
diff --git a/sys/sys/vnode.h b/sys/sys/vnode.h
index bb1d3faf567e..0975b65799d6 100644
--- a/sys/sys/vnode.h
+++ b/sys/sys/vnode.h
@@ -470,6 +470,7 @@ extern	struct mount *rootdevmp;	/* "/dev" mount */
 extern	u_long desiredvnodes;		/* number of vnodes desired */
 extern	struct uma_zone *namei_zone;
 extern	struct vattr va_null;		/* predefined null vattr structure */
+extern	struct vnode *vp_crossmp;
 
 extern	u_int vn_lock_pair_pause_max;