summaryrefslogtreecommitdiff
path: root/include/uapi/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/uapi/linux
parent550a7e28d801d35dd23aa2cdd30b7a59e193e080 (diff)
parentc73c0e243836d5dfd1c617f73b6003b1ad40b2d1 (diff)
downloadlinux-next-4effd80841b3c26ab33e30409e810b35a0dc0385.tar.gz
linux-next-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/uapi/linux')
-rw-r--r--include/uapi/linux/close_range.h31
1 files changed, 27 insertions, 4 deletions
diff --git a/include/uapi/linux/close_range.h b/include/uapi/linux/close_range.h
index 2d804281554c..7da9ed95258a 100644
--- a/include/uapi/linux/close_range.h
+++ b/include/uapi/linux/close_range.h
@@ -2,11 +2,34 @@
#ifndef _UAPI_LINUX_CLOSE_RANGE_H
#define _UAPI_LINUX_CLOSE_RANGE_H
-/* Unshare the file descriptor table before closing file descriptors. */
-#define CLOSE_RANGE_UNSHARE (1U << 1)
+/*
+ * A macro of one of these names defined before this header is parsed, by
+ * a libc or by a program's own fallback, would replace the enumerator.
+ */
+#undef CLOSE_RANGE_UNSHARE
+#undef CLOSE_RANGE_CLOEXEC
+#undef CLOSE_RANGE_EXCEPT
+#undef CLOSE_RANGE_CLOEXEC_ONLY
-/* Set the FD_CLOEXEC bit instead of closing the file descriptor. */
-#define CLOSE_RANGE_CLOEXEC (1U << 2)
+enum close_range_flags {
+ /* Unshare the file descriptor table before closing file descriptors. */
+ CLOSE_RANGE_UNSHARE = (1U << 1),
+
+ /* Set the FD_CLOEXEC bit instead of closing the file descriptor. */
+ CLOSE_RANGE_CLOEXEC = (1U << 2),
+
+ /* Act on every file descriptor outside of the given range instead. */
+ CLOSE_RANGE_EXCEPT = (1U << 3),
+
+ /* Only close file descriptors that have the FD_CLOEXEC bit set. */
+ CLOSE_RANGE_CLOEXEC_ONLY = (1U << 4),
+};
+
+/* Keep #ifdef working and let glibc skip its own definitions. */
+#define CLOSE_RANGE_UNSHARE CLOSE_RANGE_UNSHARE
+#define CLOSE_RANGE_CLOEXEC CLOSE_RANGE_CLOEXEC
+#define CLOSE_RANGE_EXCEPT CLOSE_RANGE_EXCEPT
+#define CLOSE_RANGE_CLOEXEC_ONLY CLOSE_RANGE_CLOEXEC_ONLY
#endif /* _UAPI_LINUX_CLOSE_RANGE_H */