git: 6c9ee5f02548 - stable/15 - vfs: Disallow renameat() with FD_RESOLVE_BENEATH descriptors

From: Mark Johnston <markj_at_FreeBSD.org>
Date: Tue, 29 Sep 2026 15:56:24 UTC
The branch stable/15 has been updated by markj:

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

commit 6c9ee5f02548c1c742c38c69e7f2164eee128320
Author:     Mark Johnston <markj@FreeBSD.org>
AuthorDate: 2026-09-28 16:47:56 +0000
Commit:     Mark Johnston <markj@FreeBSD.org>
CommitDate: 2026-09-29 15:56:01 +0000

    vfs: Disallow renameat() with FD_RESOLVE_BENEATH descriptors
    
    The FD_RESOLVE_BENEATH flag was intended to try to resolve bugzilla PR
    262179 without entirely disallowing fd passing between jails.  However,
    one can use renameat() to bypass the restriction: upon receiving a
    directory fd with FD_RESOLVE_BENEATH set, a jailed process can still
    move its CWD or one of its ancestors to the directory, and just cd
    out of its jail root.
    
    So disallow renameat() when either the source or destination directory
    fds has FD_RESOLVE_BENEATH set, like we do with fchdir() and fchroot()
    to prevent similar escapes.
    
    Approved by:    so
    Security:       FreeBSD-SA-26:66.jail
    Security:       CVE-2026-101305
    PR:             262179
    Reported by:    firk@cantconnect.ru
    Reviewed by:    olce, kib
    Differential Revision:  https://reviews.freebsd.org/D59875
---
 lib/libsys/fcntl.2      | 9 ++++++++-
 sys/kern/vfs_syscalls.c | 9 +++++++++
 2 files changed, 17 insertions(+), 1 deletion(-)

diff --git a/lib/libsys/fcntl.2 b/lib/libsys/fcntl.2
index b919e1b8674b..123dd5543ab2 100644
--- a/lib/libsys/fcntl.2
+++ b/lib/libsys/fcntl.2
@@ -25,7 +25,7 @@
 .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 .\" SUCH DAMAGE.
 .\"
-.Dd June 24, 2025
+.Dd September 22, 2026
 .Dt FCNTL 2
 .Os
 .Sh NAME
@@ -173,6 +173,13 @@ and similar operations, and opening a directory with
 .Xr openat 2
 where the directory descriptor has the flag set causes the new directory
 descriptor to also have the flag set.
+A file descriptor with the
+.Dv FD_RESOLVE_BENEATH
+set cannot be used as either the source or target descriptor in
+.Xr renameat 2
+or
+.Xr renameat2 2
+system calls.
 .El
 .It Dv F_SETFD
 Set flags associated with
diff --git a/sys/kern/vfs_syscalls.c b/sys/kern/vfs_syscalls.c
index 8096ffc7be6c..5bc8dd5c5f91 100644
--- a/sys/kern/vfs_syscalls.c
+++ b/sys/kern/vfs_syscalls.c
@@ -3869,6 +3869,15 @@ again:
 		error = EEXIST;
 		goto out;
 	}
+	if (fvp->v_type == VDIR &&
+	    ((fromnd.ni_resflags | tond.ni_resflags) & NIRES_BENEATH) != 0) {
+		/*
+		 * We must not rename a directory relative to FD_RESOLVE_BENEATH
+		 * descriptors.
+		 */
+		error = ENOTCAPABLE;
+		goto out;
+	}
 	if (exchange) {
 		if (tvp == NULL) {
 			error = ENOENT;