1CLOSE_RANGE(2) Linux Programmer's Manual CLOSE_RANGE(2)
2
3
4
6 close_range - close all file descriptors in a given range
7
9 #include <linux/close_range.h>
10
11 int close_range(unsigned int first, unsigned int last,
12 unsigned int flags);
13
15 The close_range() system call closes all open file descriptors from
16 first to last (included).
17
18 Errors closing a given file descriptor are currently ignored.
19
20 flags is a bit mask containing 0 or more of the following:
21
22 CLOSE_RANGE_CLOEXEC (since Linux 5.11)
23 Set the close-on-exec flag on the specified file descriptors,
24 rather than immediately closing them.
25
26 CLOSE_RANGE_UNSHARE
27 Unshare the specified file descriptors from any other processes
28 before closing them, avoiding races with other threads sharing
29 the file descriptor table.
30
32 On success, close_range() returns 0. On error, -1 is returned and er‐
33 rno is set to indicate the error.
34
36 EINVAL flags is not valid, or first is greater than last.
37
38 The following can occur with CLOSE_RANGE_UNSHARE (when constructing the
39 new descriptor table):
40
41 EMFILE The number of open file descriptors exceeds the limit specified
42 in /proc/sys/fs/nr_open (see proc(5)). This error can occur in
43 situations where that limit was lowered before a call to
44 close_range() where the CLOSE_RANGE_UNSHARE flag is specified.
45
46 ENOMEM Insufficient kernel memory was available.
47
49 close_range() first appeared in Linux 5.9. Library support was added
50 in glibc in version 2.34.
51
53 close_range() is a nonstandard function that is also present on Free‐
54 BSD.
55
57 Closing all open file descriptors
58 To avoid blindly closing file descriptors in the range of possible file
59 descriptors, this is sometimes implemented (on Linux) by listing open
60 file descriptors in /proc/self/fd/ and calling close(2) on each one.
61 close_range() can take care of this without requiring /proc and within
62 a single system call, which provides significant performance benefits.
63
64 Closing file descriptors before exec
65 File descriptors can be closed safely using
66
67 /* we don't want anything past stderr here */
68 close_range(3, ~0U, CLOSE_RANGE_UNSHARE);
69 execve(....);
70
71 CLOSE_RANGE_UNSHARE is conceptually equivalent to
72
73 unshare(CLONE_FILES);
74 close_range(first, last, 0);
75
76 but can be more efficient: if the unshared range extends past the cur‐
77 rent maximum number of file descriptors allocated in the caller's file
78 descriptor table (the common case when last is ~0U), the kernel will
79 unshare a new file descriptor table for the caller up to first, copying
80 as few file descriptors as possible. This avoids subsequent close(2)
81 calls entirely; the whole operation is complete once the table is un‐
82 shared.
83
84 Closing files on exec
85 This is particularly useful in cases where multiple pre-exec setup
86 steps risk conflicting with each other. For example, setting up a sec‐
87 comp(2) profile can conflict with a close_range() call: if the file de‐
88 scriptors are closed before the seccomp(2) profile is set up, the pro‐
89 file setup can't use them itself, or control their closure; if the file
90 descriptors are closed afterwards, the seccomp profile can't block the
91 close_range() call or any fallbacks. Using CLOSE_RANGE_CLOEXEC avoids
92 this: the descriptors can be marked before the seccomp(2) profile is
93 set up, and the profile can control access to close_range() without af‐
94 fecting the calling process.
95
97 The program shown below opens the files named in its command-line argu‐
98 ments, displays the list of files that it has opened (by iterating
99 through the entries in /proc/PID/fd), uses close_range() to close all
100 file descriptors greater than or equal to 3, and then once more dis‐
101 plays the process's list of open files. The following example demon‐
102 strates the use of the program:
103
104 $ touch /tmp/a /tmp/b /tmp/c
105 $ ./a.out /tmp/a /tmp/b /tmp/c
106 /tmp/a opened as FD 3
107 /tmp/b opened as FD 4
108 /tmp/c opened as FD 5
109 /proc/self/fd/0 ==> /dev/pts/1
110 /proc/self/fd/1 ==> /dev/pts/1
111 /proc/self/fd/2 ==> /dev/pts/1
112 /proc/self/fd/3 ==> /tmp/a
113 /proc/self/fd/4 ==> /tmp/b
114 /proc/self/fd/5 ==> /tmp/b
115 /proc/self/fd/6 ==> /proc/9005/fd
116 ========= About to call close_range() =======
117 /proc/self/fd/0 ==> /dev/pts/1
118 /proc/self/fd/1 ==> /dev/pts/1
119 /proc/self/fd/2 ==> /dev/pts/1
120 /proc/self/fd/3 ==> /proc/9005/fd
121
122 Note that the lines showing the pathname /proc/9005/fd result from the
123 calls to opendir(3).
124
125 Program source
126
127 #define _GNU_SOURCE
128 #include <fcntl.h>
129 #include <linux/close_range.h>
130 #include <stdio.h>
131 #include <stdlib.h>
132 #include <sys/syscall.h>
133 #include <string.h>
134 #include <unistd.h>
135 #include <dirent.h>
136
137 /* Show the contents of the symbolic links in /proc/self/fd */
138
139 static void
140 show_fds(void)
141 {
142 DIR *dirp = opendir("/proc/self/fd");
143 if (dirp == NULL) {
144 perror("opendir");
145 exit(EXIT_FAILURE);
146 }
147
148 for (;;) {
149 struct dirent *dp = readdir(dirp);
150 if (dp == NULL)
151 break;
152
153 if (dp->d_type == DT_LNK) {
154 char path[PATH_MAX], target[PATH_MAX];
155 snprintf(path, sizeof(path), "/proc/self/fd/%s",
156 dp->d_name);
157
158 ssize_t len = readlink(path, target, sizeof(target));
159 printf("%s ==> %.*s\n", path, (int) len, target);
160 }
161 }
162
163 closedir(dirp);
164 }
165
166 int
167 main(int argc, char *argv[])
168 {
169 for (int j = 1; j < argc; j++) {
170 int fd = open(argv[j], O_RDONLY);
171 if (fd == -1) {
172 perror(argv[j]);
173 exit(EXIT_FAILURE);
174 }
175 printf("%s opened as FD %d\n", argv[j], fd);
176 }
177
178 show_fds();
179
180 printf("========= About to call close_range() =======\n");
181
182 if (syscall(__NR_close_range, 3, ~0U, 0) == -1) {
183 perror("close_range");
184 exit(EXIT_FAILURE);
185 }
186
187 show_fds();
188 exit(EXIT_FAILURE);
189 }
190
192 close(2)
193
195 This page is part of release 5.13 of the Linux man-pages project. A
196 description of the project, information about reporting bugs, and the
197 latest version of this page, can be found at
198 https://www.kernel.org/doc/man-pages/.
199
200
201
202Linux 2021-08-27 CLOSE_RANGE(2)