aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Johnston <markj@FreeBSD.org>2026-09-28 16:47:56 +0000
committerMark Johnston <markj@FreeBSD.org>2026-09-29 15:56:32 +0000
commit666f08d597436ad709fabc04e618e9228ec96e74 (patch)
treeaae4b1820a7c54a00789021603d51dee41aaef8c
parent5f9f2ac707d465984e237d86e718c05f102252f5 (diff)
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
-rw-r--r--lib/libc/sys/fcntl.29
-rw-r--r--sys/kern/vfs_syscalls.c9
2 files changed, 17 insertions, 1 deletions
diff --git a/lib/libc/sys/fcntl.2 b/lib/libc/sys/fcntl.2
index fdd29c9f5d78..427ae28dcfd6 100644
--- a/lib/libc/sys/fcntl.2
+++ b/lib/libc/sys/fcntl.2
@@ -27,7 +27,7 @@
.\"
.\" @(#)fcntl.2 8.2 (Berkeley) 1/12/94
.\"
-.Dd June 5, 2025
+.Dd September 22, 2026
.Dt FCNTL 2
.Os
.Sh NAME
@@ -150,6 +150,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 de2261256875..f261e3457122 100644
--- a/sys/kern/vfs_syscalls.c
+++ b/sys/kern/vfs_syscalls.c
@@ -3725,6 +3725,15 @@ again:
}
tdvp = tond.ni_dvp;
tvp = tond.ni_vp;
+ 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;
+ }
error = vn_start_write(fvp, &mp, V_NOWAIT);
if (error != 0) {
NDFREE_PNBUF(&fromnd);