summaryrefslogtreecommitdiff
path: root/include/linux
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2026-10-19 17:11:41 -1000
committerLinus Torvalds <torvalds@linux-foundation.org>2026-10-19 17:11:41 -1000
commit4effd80841b3c26ab33e30409e810b35a0dc0385 (patch)
tree9d6b0339b09fe4b578271424eb35aa5522faac5b /include/linux
parent550a7e28d801d35dd23aa2cdd30b7a59e193e080 (diff)
parentc73c0e243836d5dfd1c617f73b6003b1ad40b2d1 (diff)
downloadlinux-4effd80841b3c26ab33e30409e810b35a0dc0385.tar.gz
linux-4effd80841b3c26ab33e30409e810b35a0dc0385.zip
Merge tag 'vfs-7.4-rc1.close_range' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs
Pull close_range updates from Christian Brauner: "This adds two new close_range() flags. CLOSE_RANGE_EXCEPT makes close_range() operate on all file descriptors outside of [fd, max_fd] instead of the ones inside. Alone it closes everything but the range. With CLOSE_RANGE_CLOEXEC it marks everything but the range close-on-exec. With CLOSE_RANGE_UNSHARE dup_fd() never takes a reference on what is dropped. So a task between clone(CLONE_FILES | CLONE_VM | CLONE_VFORK) and execve() that has the descriptors for the child in one window can shed the rest of the shared table in one call and nothing outside of the window is referenced by the child at any point. CLOSE_RANGE_CLOEXEC_ONLY closes the close-on-exec descriptors in the range and leaves everything else alone. Whatever the caller deliberately passes down, stdio, LISTEN_FDS, an inherited pipe, stays where it is. Combined with CLOSE_RANGE_EXCEPT it names the handful of close-on-exec descriptors that have to survive, the executable or an error pipe, and closes every other close-on-exec descriptor. Along the way dup_fd() stops copying a range in the middle of the table only to close it again. close_range(CLOSE_RANGE_UNSHARE) only avoided the copy when the range sat at the end of the table. Descriptors in a skipped range are never copied and no reference is taken on them, so ->flush() isn't called anymore for files from a table they were never part of. The flags are turned into an enum and selftests cover the window positions, the shared and the private table and the unshare form" * tag 'vfs-7.4-rc1.close_range' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs: selftests/core: test CLOSE_RANGE_CLOEXEC_ONLY file: add CLOSE_RANGE_CLOEXEC_ONLY file: let dup_fd() drop only close-on-exec descriptors selftests/core: test CLOSE_RANGE_EXCEPT file: add CLOSE_RANGE_EXCEPT close_range: turn the flags into an enum file: let dup_fd() drop everything outside of the range file: rename dup_fd()'s punch_hole to range selftests/core: test the hole CLOSE_RANGE_UNSHARE leaves behind file: let dup_fd() leave the punched hole behind
Diffstat (limited to 'include/linux')
-rw-r--r--include/linux/fdtable.h9
1 files changed, 9 insertions, 0 deletions
diff --git a/include/linux/fdtable.h b/include/linux/fdtable.h
index c45306a9f007..afdfaad381df 100644
--- a/include/linux/fdtable.h
+++ b/include/linux/fdtable.h
@@ -101,8 +101,17 @@ struct task_struct;
void put_files_struct(struct files_struct *fs);
int unshare_files(void);
+enum fd_range_flags {
+ /* Leave behind all descriptors outside of the specified range. */
+ FD_RANGE_EXCEPT = (1U << 0),
+
+ /* Only select descriptors that have close-on-exec set. */
+ FD_RANGE_CLOEXEC_ONLY = (1U << 1),
+};
+
struct fd_range {
unsigned int from, to;
+ enum fd_range_flags flags;
};
struct files_struct *dup_fd(struct files_struct *, struct fd_range *) __latent_entropy;
void do_close_on_exec(struct files_struct *);