diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2026-10-19 17:11:41 -1000 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2026-10-19 17:11:41 -1000 |
| commit | 4effd80841b3c26ab33e30409e810b35a0dc0385 (patch) | |
| tree | 9d6b0339b09fe4b578271424eb35aa5522faac5b /include/linux | |
| parent | 550a7e28d801d35dd23aa2cdd30b7a59e193e080 (diff) | |
| parent | c73c0e243836d5dfd1c617f73b6003b1ad40b2d1 (diff) | |
| download | linux-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.h | 9 |
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 *); |
