1 .\" Copyright (c) 2020 Stephen Kitt <steve@sk2.org>
2 .\" and Copyright (c) 2021 Michael Kerrisk <mtk.manpages@gmail.com>
4 .\" %%%LICENSE_START(VERBATIM)
5 .\" Permission is granted to make and distribute verbatim copies of this
6 .\" manual provided the copyright notice and this permission notice are
7 .\" preserved on all copies.
9 .\" Permission is granted to copy and distribute modified versions of this
10 .\" manual under the conditions for verbatim copying, provided that the
11 .\" entire resulting derived work is distributed under the terms of a
12 .\" permission notice identical to this one.
14 .\" Since the Linux kernel and libraries are constantly changing, this
15 .\" manual page may be incorrect or out-of-date. The author(s) assume no
16 .\" responsibility for errors or omissions, or for damages resulting from
17 .\" the use of the information contained herein. The author(s) may not
18 .\" have taken the same level of care in the production of this manual,
19 .\" which is licensed free of charge, as they might when working
22 .\" Formatted or processed versions of this manual, if unaccompanied by
23 .\" the source, must acknowledge the copyright and authors of this work.
26 .TH CLOSE_RANGE 2 2021-08-27 "Linux" "Linux Programmer's Manual"
28 close_range \- close all file descriptors in a given range
31 .B #include <linux/close_range.h>
33 .BI "int close_range(unsigned int " first ", unsigned int " last ,
34 .BI " unsigned int " flags );
39 system call closes all open file descriptors from
45 Errors closing a given file descriptor are currently ignored.
48 is a bit mask containing 0 or more of the following:
50 .BR CLOSE_RANGE_CLOEXEC " (since Linux 5.11)"
51 Set the close-on-exec flag on the specified file descriptors,
52 rather than immediately closing them.
54 .B CLOSE_RANGE_UNSHARE
55 Unshare the specified file descriptors from any other processes
57 avoiding races with other threads sharing the file descriptor table.
62 On error, \-1 is returned and
64 is set to indicate the error.
74 The following can occur with
75 .B CLOSE_RANGE_UNSHARE
76 (when constructing the new descriptor table):
79 The number of open file descriptors exceeds the limit specified in
80 .IR /proc/sys/fs/nr_open
83 This error can occur in situations where that limit was lowered before
87 .B CLOSE_RANGE_UNSHARE
91 Insufficient kernel memory was available.
94 first appeared in Linux 5.9.
95 Library support was added in glibc in version 2.34.
98 is a nonstandard function that is also present on FreeBSD.
100 .SS Closing all open file descriptors
101 .\" 278a5fbaed89dacd04e9d052f4594ffd0e0585de
102 To avoid blindly closing file descriptors
103 in the range of possible file descriptors,
104 this is sometimes implemented (on Linux)
105 by listing open file descriptors in
111 can take care of this without requiring
113 and within a single system call,
114 which provides significant performance benefits.
115 .SS Closing file descriptors before exec
116 .\" 60997c3d45d9a67daf01c56d805ae4fec37e0bd8
117 File descriptors can be closed safely using
121 /* we don't want anything past stderr here */
122 close_range(3, ~0U, CLOSE_RANGE_UNSHARE);
127 .B CLOSE_RANGE_UNSHARE
128 is conceptually equivalent to
132 unshare(CLONE_FILES);
133 close_range(first, last, 0);
137 but can be more efficient:
138 if the unshared range extends past
139 the current maximum number of file descriptors allocated
140 in the caller's file descriptor table
141 (the common case when
144 the kernel will unshare a new file descriptor table for the caller up to
146 copying as few file descriptors as possible.
147 This avoids subsequent
150 the whole operation is complete once the table is unshared.
151 .SS Closing files on \fBexec\fP
152 .\" 582f1fb6b721facf04848d2ca57f34468da1813e
153 This is particularly useful in cases where multiple
155 setup steps risk conflicting with each other.
156 For example, setting up a
158 profile can conflict with a
161 if the file descriptors are closed before the
164 the profile setup can't use them itself,
165 or control their closure;
166 if the file descriptors are closed afterwards,
167 the seccomp profile can't block the
169 call or any fallbacks.
171 .B CLOSE_RANGE_CLOEXEC
173 the descriptors can be marked before the
176 and the profile can control access to
178 without affecting the calling process.
180 The program shown below opens the files named in its command-line arguments,
181 displays the list of files that it has opened
182 (by iterating through the entries in
186 to close all file descriptors greater than or equal to 3,
187 and then once more displays the process's list of open files.
188 The following example demonstrates the use of the program:
192 $ \fBtouch /tmp/a /tmp/b /tmp/c\fP
193 $ \fB./a.out /tmp/a /tmp/b /tmp/c\fP
194 /tmp/a opened as FD 3
195 /tmp/b opened as FD 4
196 /tmp/c opened as FD 5
197 /proc/self/fd/0 ==> /dev/pts/1
198 /proc/self/fd/1 ==> /dev/pts/1
199 /proc/self/fd/2 ==> /dev/pts/1
200 /proc/self/fd/3 ==> /tmp/a
201 /proc/self/fd/4 ==> /tmp/b
202 /proc/self/fd/5 ==> /tmp/b
203 /proc/self/fd/6 ==> /proc/9005/fd
204 ========= About to call close_range() =======
205 /proc/self/fd/0 ==> /dev/pts/1
206 /proc/self/fd/1 ==> /dev/pts/1
207 /proc/self/fd/2 ==> /dev/pts/1
208 /proc/self/fd/3 ==> /proc/9005/fd
212 Note that the lines showing the pathname
214 result from the calls to
221 #include <linux/close_range.h>
224 #include <sys/syscall.h>
229 /* Show the contents of the symbolic links in /proc/self/fd */
234 DIR *dirp = opendir("/proc/self/fd");
241 struct dirent *dp = readdir(dirp);
245 if (dp\->d_type == DT_LNK) {
246 char path[PATH_MAX], target[PATH_MAX];
247 snprintf(path, sizeof(path), "/proc/self/fd/%s",
250 ssize_t len = readlink(path, target, sizeof(target));
251 printf("%s ==> %.*s\en", path, (int) len, target);
259 main(int argc, char *argv[])
261 for (int j = 1; j < argc; j++) {
262 int fd = open(argv[j], O_RDONLY);
267 printf("%s opened as FD %d\en", argv[j], fd);
272 printf("========= About to call close_range() =======\en");
274 if (syscall(__NR_close_range, 3, \(ti0U, 0) == \-1) {
275 perror("close_range");