mirror of
https://github.com/freebsd/freebsd-src.git
synced 2026-11-07 04:36:52 -10:00
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: [email protected] Reviewed by: olce, kib Differential Revision: https://reviews.freebsd.org/D59875
This commit is contained in:
1 parent
047562735b
commit
9c10f4c021
2 files changed
+17
-1
No files matched your search
+8
-1
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in new issue
Block a user