]> git.ipfire.org Git - thirdparty/man-pages.git/blob - man2/close_range.2
man*/: srcfix (Use .P instead of .PP or .LP)
[thirdparty/man-pages.git] / man2 / close_range.2
1 .\" Copyright (c) 2020 Stephen Kitt <steve@sk2.org>
2 .\" and Copyright (c) 2021 Michael Kerrisk <mtk.manpages@gmail.com>
3 .\"
4 .\" SPDX-License-Identifier: Linux-man-pages-copyleft
5 .\"
6 .TH close_range 2 (date) "Linux man-pages (unreleased)"
7 .SH NAME
8 close_range \- close all file descriptors in a given range
9 .SH LIBRARY
10 Standard C library
11 .RI ( libc ", " \-lc )
12 .SH SYNOPSIS
13 .nf
14 .B #include <linux/close_range.h>
15 .P
16 .BI "int close_range(unsigned int " first ", unsigned int " last ,
17 .BI " unsigned int " flags );
18 .fi
19 .SH DESCRIPTION
20 The
21 .BR close_range ()
22 system call closes all open file descriptors from
23 .I first
24 to
25 .I last
26 (included).
27 .P
28 Errors closing a given file descriptor are currently ignored.
29 .P
30 .I flags
31 is a bit mask containing 0 or more of the following:
32 .TP
33 .BR CLOSE_RANGE_CLOEXEC " (since Linux 5.11)"
34 Set the close-on-exec flag on the specified file descriptors,
35 rather than immediately closing them.
36 .TP
37 .B CLOSE_RANGE_UNSHARE
38 Unshare the specified file descriptors from any other processes
39 before closing them,
40 avoiding races with other threads sharing the file descriptor table.
41 .SH RETURN VALUE
42 On success,
43 .BR close_range ()
44 returns 0.
45 On error, \-1 is returned and
46 .I errno
47 is set to indicate the error.
48 .SH ERRORS
49 .TP
50 .B EINVAL
51 .I flags
52 is not valid, or
53 .I first
54 is greater than
55 .IR last .
56 .P
57 The following can occur with
58 .B CLOSE_RANGE_UNSHARE
59 (when constructing the new descriptor table):
60 .TP
61 .B EMFILE
62 The number of open file descriptors exceeds the limit specified in
63 .I /proc/sys/fs/nr_open
64 (see
65 .BR proc (5)).
66 This error can occur in situations where that limit was lowered before
67 a call to
68 .BR close_range ()
69 where the
70 .B CLOSE_RANGE_UNSHARE
71 flag is specified.
72 .TP
73 .B ENOMEM
74 Insufficient kernel memory was available.
75 .SH STANDARDS
76 None.
77 .SH HISTORY
78 FreeBSD.
79 Linux 5.9,
80 glibc 2.34.
81 .SH NOTES
82 .SS Closing all open file descriptors
83 .\" 278a5fbaed89dacd04e9d052f4594ffd0e0585de
84 To avoid blindly closing file descriptors
85 in the range of possible file descriptors,
86 this is sometimes implemented (on Linux)
87 by listing open file descriptors in
88 .I /proc/self/fd/
89 and calling
90 .BR close (2)
91 on each one.
92 .BR close_range ()
93 can take care of this without requiring
94 .I /proc
95 and within a single system call,
96 which provides significant performance benefits.
97 .SS Closing file descriptors before exec
98 .\" 60997c3d45d9a67daf01c56d805ae4fec37e0bd8
99 File descriptors can be closed safely using
100 .P
101 .in +4n
102 .EX
103 /* we don't want anything past stderr here */
104 close_range(3, \[ti]0U, CLOSE_RANGE_UNSHARE);
105 execve(....);
106 .EE
107 .in
108 .P
109 .B CLOSE_RANGE_UNSHARE
110 is conceptually equivalent to
111 .P
112 .in +4n
113 .EX
114 unshare(CLONE_FILES);
115 close_range(first, last, 0);
116 .EE
117 .in
118 .P
119 but can be more efficient:
120 if the unshared range extends past
121 the current maximum number of file descriptors allocated
122 in the caller's file descriptor table
123 (the common case when
124 .I last
125 is \[ti]0U),
126 the kernel will unshare a new file descriptor table for the caller up to
127 .IR first ,
128 copying as few file descriptors as possible.
129 This avoids subsequent
130 .BR close (2)
131 calls entirely;
132 the whole operation is complete once the table is unshared.
133 .SS Closing files on \fBexec\fP
134 .\" 582f1fb6b721facf04848d2ca57f34468da1813e
135 This is particularly useful in cases where multiple
136 .RB pre- exec
137 setup steps risk conflicting with each other.
138 For example, setting up a
139 .BR seccomp (2)
140 profile can conflict with a
141 .BR close_range ()
142 call:
143 if the file descriptors are closed before the
144 .BR seccomp (2)
145 profile is set up,
146 the profile setup can't use them itself,
147 or control their closure;
148 if the file descriptors are closed afterwards,
149 the seccomp profile can't block the
150 .BR close_range ()
151 call or any fallbacks.
152 Using
153 .B CLOSE_RANGE_CLOEXEC
154 avoids this:
155 the descriptors can be marked before the
156 .BR seccomp (2)
157 profile is set up,
158 and the profile can control access to
159 .BR close_range ()
160 without affecting the calling process.
161 .SH EXAMPLES
162 The program shown below opens the files named in its command-line arguments,
163 displays the list of files that it has opened
164 (by iterating through the entries in
165 .IR /proc/PID/fd ),
166 uses
167 .BR close_range ()
168 to close all file descriptors greater than or equal to 3,
169 and then once more displays the process's list of open files.
170 The following example demonstrates the use of the program:
171 .P
172 .in +4n
173 .EX
174 $ \fBtouch /tmp/a /tmp/b /tmp/c\fP
175 $ \fB./a.out /tmp/a /tmp/b /tmp/c\fP
176 /tmp/a opened as FD 3
177 /tmp/b opened as FD 4
178 /tmp/c opened as FD 5
179 /proc/self/fd/0 ==> /dev/pts/1
180 /proc/self/fd/1 ==> /dev/pts/1
181 /proc/self/fd/2 ==> /dev/pts/1
182 /proc/self/fd/3 ==> /tmp/a
183 /proc/self/fd/4 ==> /tmp/b
184 /proc/self/fd/5 ==> /tmp/b
185 /proc/self/fd/6 ==> /proc/9005/fd
186 ========= About to call close_range() =======
187 /proc/self/fd/0 ==> /dev/pts/1
188 /proc/self/fd/1 ==> /dev/pts/1
189 /proc/self/fd/2 ==> /dev/pts/1
190 /proc/self/fd/3 ==> /proc/9005/fd
191 .EE
192 .in
193 .P
194 Note that the lines showing the pathname
195 .I /proc/9005/fd
196 result from the calls to
197 .BR opendir (3).
198 .SS Program source
199 \&
200 .\" SRC BEGIN (close_range.c)
201 .EX
202 #define _GNU_SOURCE
203 #include <dirent.h>
204 #include <fcntl.h>
205 #include <limits.h>
206 #include <stdio.h>
207 #include <stdlib.h>
208 #include <sys/syscall.h>
209 #include <unistd.h>
210 \&
211 /* Show the contents of the symbolic links in /proc/self/fd */
212 \&
213 static void
214 show_fds(void)
215 {
216 DIR *dirp;
217 char path[PATH_MAX], target[PATH_MAX];
218 ssize_t len;
219 struct dirent *dp;
220 \&
221 dirp = opendir("/proc/self/fd");
222 if (dirp == NULL) {
223 perror("opendir");
224 exit(EXIT_FAILURE);
225 }
226 \&
227 for (;;) {
228 dp = readdir(dirp);
229 if (dp == NULL)
230 break;
231 \&
232 if (dp\->d_type == DT_LNK) {
233 snprintf(path, sizeof(path), "/proc/self/fd/%s",
234 dp\->d_name);
235 \&
236 len = readlink(path, target, sizeof(target));
237 printf("%s ==> %.*s\en", path, (int) len, target);
238 }
239 }
240 \&
241 closedir(dirp);
242 }
243 \&
244 int
245 main(int argc, char *argv[])
246 {
247 int fd;
248 \&
249 for (size_t j = 1; j < argc; j++) {
250 fd = open(argv[j], O_RDONLY);
251 if (fd == \-1) {
252 perror(argv[j]);
253 exit(EXIT_FAILURE);
254 }
255 printf("%s opened as FD %d\en", argv[j], fd);
256 }
257 \&
258 show_fds();
259 \&
260 printf("========= About to call close_range() =======\en");
261 \&
262 if (syscall(SYS_close_range, 3, \[ti]0U, 0) == \-1) {
263 perror("close_range");
264 exit(EXIT_FAILURE);
265 }
266 \&
267 show_fds();
268 exit(EXIT_FAILURE);
269 }
270 .EE
271 .\" SRC END
272 .SH SEE ALSO
273 .BR close (2)