2 * Copyright (c) 2012 The FreeBSD Foundation
5 * This software was developed by Pawel Jakub Dawidek under sponsorship from
6 * the FreeBSD Foundation.
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 #include <sys/cdefs.h>
31 __FBSDID("$FreeBSD$");
33 #include <sys/types.h>
34 #include <sys/capability.h>
35 #include <sys/procdesc.h>
36 #include <sys/socket.h>
53 CHECK(cap_fcntls_get(fd, &fcntlrights) == 0);
54 CHECK(fcntlrights == CAP_FCNTL_ALL);
56 CHECK(fcntl(fd, F_GETFD) == 0);
57 CHECK(fcntl(fd, F_SETFD, FD_CLOEXEC) == 0);
58 CHECK(fcntl(fd, F_GETFD) == FD_CLOEXEC);
59 CHECK(fcntl(fd, F_SETFD, 0) == 0);
60 CHECK(fcntl(fd, F_GETFD) == 0);
62 CHECK(fcntl(fd, F_GETFL) == O_RDWR);
63 CHECK(fcntl(fd, F_SETFL, O_NONBLOCK) == 0);
64 CHECK(fcntl(fd, F_GETFL) == (O_RDWR | O_NONBLOCK));
65 CHECK(fcntl(fd, F_SETFL, 0) == 0);
66 CHECK(fcntl(fd, F_GETFL) == O_RDWR);
69 CHECK(cap_fcntls_limit(fd, ~CAP_FCNTL_ALL) == -1);
70 CHECK(errno == EINVAL);
71 CHECK(cap_fcntls_limit(fd, CAP_FCNTL_GETFL | CAP_FCNTL_SETFL) == 0);
73 CHECK(cap_fcntls_get(fd, &fcntlrights) == 0);
74 CHECK(fcntlrights == (CAP_FCNTL_GETFL | CAP_FCNTL_SETFL));
75 CHECK(cap_fcntls_limit(fd, CAP_FCNTL_GETFL | CAP_FCNTL_SETFL) == 0);
77 CHECK(cap_fcntls_get(fd, &fcntlrights) == 0);
78 CHECK(fcntlrights == (CAP_FCNTL_GETFL | CAP_FCNTL_SETFL));
80 CHECK(fcntl(fd, F_GETFD) == 0);
81 CHECK(fcntl(fd, F_SETFD, FD_CLOEXEC) == 0);
82 CHECK(fcntl(fd, F_GETFD) == FD_CLOEXEC);
83 CHECK(fcntl(fd, F_SETFD, 0) == 0);
84 CHECK(fcntl(fd, F_GETFD) == 0);
86 CHECK(fcntl(fd, F_GETFL) == O_RDWR);
87 CHECK(fcntl(fd, F_SETFL, O_NONBLOCK) == 0);
88 CHECK(fcntl(fd, F_GETFL) == (O_RDWR | O_NONBLOCK));
89 CHECK(fcntl(fd, F_SETFL, 0) == 0);
90 CHECK(fcntl(fd, F_GETFL) == O_RDWR);
92 CHECK(cap_fcntls_limit(fd, CAP_FCNTL_GETFL) == 0);
94 CHECK(cap_fcntls_get(fd, &fcntlrights) == 0);
95 CHECK(fcntlrights == CAP_FCNTL_GETFL);
97 CHECK(cap_fcntls_limit(fd, CAP_FCNTL_GETFL | CAP_FCNTL_SETFL) == -1);
98 CHECK(errno == ENOTCAPABLE);
100 CHECK(cap_fcntls_get(fd, &fcntlrights) == 0);
101 CHECK(fcntlrights == CAP_FCNTL_GETFL);
103 CHECK(fcntl(fd, F_GETFD) == 0);
104 CHECK(fcntl(fd, F_SETFD, FD_CLOEXEC) == 0);
105 CHECK(fcntl(fd, F_GETFD) == FD_CLOEXEC);
106 CHECK(fcntl(fd, F_SETFD, 0) == 0);
107 CHECK(fcntl(fd, F_GETFD) == 0);
109 CHECK(fcntl(fd, F_GETFL) == O_RDWR);
111 CHECK(fcntl(fd, F_SETFL, O_NONBLOCK) == -1);
112 CHECK(errno == ENOTCAPABLE);
113 CHECK(fcntl(fd, F_GETFL) == O_RDWR);
115 CHECK(fcntl(fd, F_SETFL, 0) == -1);
116 CHECK(errno == ENOTCAPABLE);
117 CHECK(fcntl(fd, F_GETFL) == O_RDWR);
119 CHECK(cap_fcntls_limit(fd, 0) == 0);
120 fcntlrights = CAP_FCNTL_ALL;
121 CHECK(cap_fcntls_get(fd, &fcntlrights) == 0);
122 CHECK(fcntlrights == 0);
124 CHECK(cap_fcntls_limit(fd, CAP_FCNTL_GETFL | CAP_FCNTL_SETFL) == -1);
125 CHECK(errno == ENOTCAPABLE);
126 fcntlrights = CAP_FCNTL_ALL;
127 CHECK(cap_fcntls_get(fd, &fcntlrights) == 0);
128 CHECK(fcntlrights == 0);
130 CHECK(cap_fcntls_limit(fd, CAP_FCNTL_GETFL) == -1);
131 CHECK(errno == ENOTCAPABLE);
132 fcntlrights = CAP_FCNTL_ALL;
133 CHECK(cap_fcntls_get(fd, &fcntlrights) == 0);
134 CHECK(fcntlrights == 0);
136 CHECK(fcntl(fd, F_GETFD) == 0);
137 CHECK(fcntl(fd, F_SETFD, FD_CLOEXEC) == 0);
138 CHECK(fcntl(fd, F_GETFD) == FD_CLOEXEC);
139 CHECK(fcntl(fd, F_SETFD, 0) == 0);
140 CHECK(fcntl(fd, F_GETFD) == 0);
143 CHECK(fcntl(fd, F_GETFL) == -1);
144 CHECK(errno == ENOTCAPABLE);
146 CHECK(fcntl(fd, F_SETFL, O_NONBLOCK) == -1);
147 CHECK(errno == ENOTCAPABLE);
149 CHECK(fcntl(fd, F_SETFL, 0) == -1);
150 CHECK(errno == ENOTCAPABLE);
152 CHECK(fcntl(fd, F_GETFL) == -1);
153 CHECK(errno == ENOTCAPABLE);
157 fcntl_tests_1(int fd)
159 uint32_t fcntlrights;
161 CHECK(cap_fcntls_limit(fd, CAP_FCNTL_GETFL) == 0);
163 CHECK(cap_fcntls_get(fd, &fcntlrights) == 0);
164 CHECK(fcntlrights == CAP_FCNTL_GETFL);
166 CHECK(cap_rights_limit(fd, CAP_ALL & ~CAP_FCNTL) == 0);
168 fcntlrights = CAP_FCNTL_ALL;
169 CHECK(cap_fcntls_get(fd, &fcntlrights) == 0);
170 CHECK(fcntlrights == 0);
173 CHECK(cap_fcntls_limit(fd, CAP_FCNTL_GETFL | CAP_FCNTL_SETFL) == -1);
174 CHECK(errno == ENOTCAPABLE);
175 fcntlrights = CAP_FCNTL_ALL;
176 CHECK(cap_fcntls_get(fd, &fcntlrights) == 0);
177 CHECK(fcntlrights == 0);
179 CHECK(cap_fcntls_limit(fd, CAP_FCNTL_GETFL) == -1);
180 CHECK(errno == ENOTCAPABLE);
181 fcntlrights = CAP_FCNTL_ALL;
182 CHECK(cap_fcntls_get(fd, &fcntlrights) == 0);
183 CHECK(fcntlrights == 0);
185 CHECK(fcntl(fd, F_GETFD) == 0);
186 CHECK(fcntl(fd, F_SETFD, FD_CLOEXEC) == 0);
187 CHECK(fcntl(fd, F_GETFD) == FD_CLOEXEC);
188 CHECK(fcntl(fd, F_SETFD, 0) == 0);
189 CHECK(fcntl(fd, F_GETFD) == 0);
192 CHECK(fcntl(fd, F_GETFL) == -1);
193 CHECK(errno == ENOTCAPABLE);
195 CHECK(fcntl(fd, F_SETFL, O_NONBLOCK) == -1);
196 CHECK(errno == ENOTCAPABLE);
198 CHECK(fcntl(fd, F_SETFL, 0) == -1);
199 CHECK(errno == ENOTCAPABLE);
201 CHECK(fcntl(fd, F_GETFL) == -1);
202 CHECK(errno == ENOTCAPABLE);
206 fcntl_tests_2(int fd)
208 uint32_t fcntlrights;
210 CHECK(cap_rights_limit(fd, CAP_ALL & ~CAP_FCNTL) == 0);
212 fcntlrights = CAP_FCNTL_ALL;
213 CHECK(cap_fcntls_get(fd, &fcntlrights) == 0);
214 CHECK(fcntlrights == 0);
217 CHECK(cap_fcntls_limit(fd, CAP_FCNTL_GETFL | CAP_FCNTL_SETFL) == -1);
218 CHECK(errno == ENOTCAPABLE);
219 fcntlrights = CAP_FCNTL_ALL;
220 CHECK(cap_fcntls_get(fd, &fcntlrights) == 0);
221 CHECK(fcntlrights == 0);
223 CHECK(cap_fcntls_limit(fd, CAP_FCNTL_GETFL) == -1);
224 CHECK(errno == ENOTCAPABLE);
225 fcntlrights = CAP_FCNTL_ALL;
226 CHECK(cap_fcntls_get(fd, &fcntlrights) == 0);
227 CHECK(fcntlrights == 0);
229 CHECK(fcntl(fd, F_GETFD) == 0);
230 CHECK(fcntl(fd, F_SETFD, FD_CLOEXEC) == 0);
231 CHECK(fcntl(fd, F_GETFD) == FD_CLOEXEC);
232 CHECK(fcntl(fd, F_SETFD, 0) == 0);
233 CHECK(fcntl(fd, F_GETFD) == 0);
236 CHECK(fcntl(fd, F_GETFL) == -1);
237 CHECK(errno == ENOTCAPABLE);
239 CHECK(fcntl(fd, F_SETFL, O_NONBLOCK) == -1);
240 CHECK(errno == ENOTCAPABLE);
242 CHECK(fcntl(fd, F_SETFL, 0) == -1);
243 CHECK(errno == ENOTCAPABLE);
245 CHECK(fcntl(fd, F_GETFL) == -1);
246 CHECK(errno == ENOTCAPABLE);
250 fcntl_tests_send_0(int sock)
254 CHECK((fd = socket(AF_UNIX, SOCK_STREAM, 0)) >= 0);
255 CHECK(descriptor_send(sock, fd) == 0);
256 CHECK(close(fd) == 0);
258 CHECK((fd = socket(AF_UNIX, SOCK_STREAM, 0)) >= 0);
259 CHECK(cap_fcntls_limit(fd, CAP_FCNTL_GETFL | CAP_FCNTL_SETFL) == 0);
260 CHECK(descriptor_send(sock, fd) == 0);
261 CHECK(close(fd) == 0);
263 CHECK((fd = socket(AF_UNIX, SOCK_STREAM, 0)) >= 0);
264 CHECK(cap_fcntls_limit(fd, CAP_FCNTL_GETFL) == 0);
265 CHECK(descriptor_send(sock, fd) == 0);
266 CHECK(close(fd) == 0);
268 CHECK((fd = socket(AF_UNIX, SOCK_STREAM, 0)) >= 0);
269 CHECK(cap_fcntls_limit(fd, 0) == 0);
270 CHECK(descriptor_send(sock, fd) == 0);
271 CHECK(close(fd) == 0);
275 fcntl_tests_recv_0(int sock)
277 uint32_t fcntlrights;
280 CHECK(descriptor_recv(sock, &fd) == 0);
283 CHECK(cap_fcntls_get(fd, &fcntlrights) == 0);
284 CHECK(fcntlrights == CAP_FCNTL_ALL);
286 CHECK(fcntl(fd, F_GETFD) == 0);
287 CHECK(fcntl(fd, F_SETFD, FD_CLOEXEC) == 0);
288 CHECK(fcntl(fd, F_GETFD) == FD_CLOEXEC);
289 CHECK(fcntl(fd, F_SETFD, 0) == 0);
290 CHECK(fcntl(fd, F_GETFD) == 0);
292 CHECK(fcntl(fd, F_GETFL) == O_RDWR);
293 CHECK(fcntl(fd, F_SETFL, O_NONBLOCK) == 0);
294 CHECK(fcntl(fd, F_GETFL) == (O_RDWR | O_NONBLOCK));
295 CHECK(fcntl(fd, F_SETFL, 0) == 0);
296 CHECK(fcntl(fd, F_GETFL) == O_RDWR);
298 CHECK(close(fd) == 0);
300 CHECK(descriptor_recv(sock, &fd) == 0);
303 CHECK(cap_fcntls_get(fd, &fcntlrights) == 0);
304 CHECK(fcntlrights == (CAP_FCNTL_GETFL | CAP_FCNTL_SETFL));
305 CHECK(cap_fcntls_limit(fd, CAP_FCNTL_GETFL | CAP_FCNTL_SETFL) == 0);
307 CHECK(cap_fcntls_get(fd, &fcntlrights) == 0);
308 CHECK(fcntlrights == (CAP_FCNTL_GETFL | CAP_FCNTL_SETFL));
310 CHECK(fcntl(fd, F_GETFD) == 0);
311 CHECK(fcntl(fd, F_SETFD, FD_CLOEXEC) == 0);
312 CHECK(fcntl(fd, F_GETFD) == FD_CLOEXEC);
313 CHECK(fcntl(fd, F_SETFD, 0) == 0);
314 CHECK(fcntl(fd, F_GETFD) == 0);
316 CHECK(fcntl(fd, F_GETFL) == O_RDWR);
317 CHECK(fcntl(fd, F_SETFL, O_NONBLOCK) == 0);
318 CHECK(fcntl(fd, F_GETFL) == (O_RDWR | O_NONBLOCK));
319 CHECK(fcntl(fd, F_SETFL, 0) == 0);
320 CHECK(fcntl(fd, F_GETFL) == O_RDWR);
322 CHECK(close(fd) == 0);
324 CHECK(descriptor_recv(sock, &fd) == 0);
327 CHECK(cap_fcntls_get(fd, &fcntlrights) == 0);
328 CHECK(fcntlrights == CAP_FCNTL_GETFL);
330 CHECK(cap_fcntls_limit(fd, CAP_FCNTL_GETFL | CAP_FCNTL_SETFL) == -1);
331 CHECK(errno == ENOTCAPABLE);
333 CHECK(cap_fcntls_get(fd, &fcntlrights) == 0);
334 CHECK(fcntlrights == CAP_FCNTL_GETFL);
335 CHECK(cap_fcntls_limit(fd, CAP_FCNTL_GETFL) == 0);
337 CHECK(cap_fcntls_get(fd, &fcntlrights) == 0);
338 CHECK(fcntlrights == CAP_FCNTL_GETFL);
340 CHECK(fcntl(fd, F_GETFD) == 0);
341 CHECK(fcntl(fd, F_SETFD, FD_CLOEXEC) == 0);
342 CHECK(fcntl(fd, F_GETFD) == FD_CLOEXEC);
343 CHECK(fcntl(fd, F_SETFD, 0) == 0);
344 CHECK(fcntl(fd, F_GETFD) == 0);
346 CHECK(fcntl(fd, F_GETFL) == O_RDWR);
348 CHECK(fcntl(fd, F_SETFL, O_NONBLOCK) == -1);
349 CHECK(errno == ENOTCAPABLE);
350 CHECK(fcntl(fd, F_GETFL) == O_RDWR);
352 CHECK(fcntl(fd, F_SETFL, 0) == -1);
353 CHECK(errno == ENOTCAPABLE);
354 CHECK(fcntl(fd, F_GETFL) == O_RDWR);
356 CHECK(close(fd) == 0);
358 CHECK(descriptor_recv(sock, &fd) == 0);
361 CHECK(cap_fcntls_get(fd, &fcntlrights) == 0);
362 CHECK(fcntlrights == 0);
364 CHECK(cap_fcntls_limit(fd, CAP_FCNTL_GETFL | CAP_FCNTL_SETFL) == -1);
365 CHECK(errno == ENOTCAPABLE);
367 CHECK(cap_fcntls_get(fd, &fcntlrights) == 0);
368 CHECK(fcntlrights == 0);
370 CHECK(cap_fcntls_limit(fd, CAP_FCNTL_GETFL) == -1);
371 CHECK(errno == ENOTCAPABLE);
373 CHECK(cap_fcntls_get(fd, &fcntlrights) == 0);
374 CHECK(fcntlrights == 0);
376 CHECK(cap_fcntls_limit(fd, CAP_FCNTL_SETFL) == -1);
377 CHECK(errno == ENOTCAPABLE);
379 CHECK(cap_fcntls_get(fd, &fcntlrights) == 0);
380 CHECK(fcntlrights == 0);
382 CHECK(fcntl(fd, F_GETFD) == 0);
383 CHECK(fcntl(fd, F_SETFD, FD_CLOEXEC) == 0);
384 CHECK(fcntl(fd, F_GETFD) == FD_CLOEXEC);
385 CHECK(fcntl(fd, F_SETFD, 0) == 0);
386 CHECK(fcntl(fd, F_GETFD) == 0);
389 CHECK(fcntl(fd, F_GETFL) == -1);
390 CHECK(errno == ENOTCAPABLE);
392 CHECK(fcntl(fd, F_SETFL, O_NONBLOCK) == -1);
393 CHECK(errno == ENOTCAPABLE);
395 CHECK(fcntl(fd, F_SETFL, 0) == -1);
396 CHECK(errno == ENOTCAPABLE);
398 CHECK(fcntl(fd, F_GETFL) == -1);
399 CHECK(errno == ENOTCAPABLE);
401 CHECK(close(fd) == 0);
412 CHECK((fd = socket(AF_UNIX, SOCK_STREAM, 0)) >= 0);
414 CHECK(close(fd) == 0);
416 CHECK((fd = socket(AF_UNIX, SOCK_STREAM, 0)) >= 0);
418 CHECK(close(fd) == 0);
420 CHECK((fd = socket(AF_UNIX, SOCK_STREAM, 0)) >= 0);
422 CHECK(close(fd) == 0);
424 /* Child inherits descriptor and operates on it first. */
425 CHECK((fd = socket(AF_UNIX, SOCK_STREAM, 0)) >= 0);
426 CHECK((pid = fork()) >= 0);
429 CHECK(close(fd) == 0);
432 CHECK(waitpid(pid, NULL, 0) == pid);
435 CHECK(close(fd) == 0);
437 /* Child inherits descriptor, but operates on it after parent. */
438 CHECK((fd = socket(AF_UNIX, SOCK_STREAM, 0)) >= 0);
439 CHECK((pid = fork()) >= 0);
443 CHECK(close(fd) == 0);
447 CHECK(waitpid(pid, NULL, 0) == pid);
449 CHECK(close(fd) == 0);
451 /* Child inherits descriptor and operates on it first. */
452 CHECK((fd = socket(AF_UNIX, SOCK_STREAM, 0)) >= 0);
453 CHECK((pid = pdfork(&pfd, 0)) >= 0);
458 CHECK(pdwait(pfd) == 0);
460 It fails with EBADF, which I believe is a bug.
461 CHECK(close(pfd) == 0);
465 CHECK(close(fd) == 0);
467 /* Child inherits descriptor, but operates on it after parent. */
468 CHECK((fd = socket(AF_UNIX, SOCK_STREAM, 0)) >= 0);
469 CHECK((pid = pdfork(&pfd, 0)) >= 0);
476 CHECK(pdwait(pfd) == 0);
478 It fails with EBADF, which I believe is a bug.
479 CHECK(close(pfd) == 0);
482 CHECK(close(fd) == 0);
484 /* Child inherits descriptor and operates on it first. */
485 CHECK((fd = socket(AF_UNIX, SOCK_STREAM, 0)) >= 0);
486 CHECK((pid = fork()) >= 0);
491 CHECK(waitpid(pid, NULL, 0) == pid);
494 CHECK(close(fd) == 0);
496 /* Child inherits descriptor, but operates on it after parent. */
497 CHECK((fd = socket(AF_UNIX, SOCK_STREAM, 0)) >= 0);
498 CHECK((pid = fork()) >= 0);
505 CHECK(waitpid(pid, NULL, 0) == pid);
507 CHECK(close(fd) == 0);
509 /* Send descriptors from parent to child. */
510 CHECK(socketpair(AF_UNIX, SOCK_STREAM, 0, sp) == 0);
511 CHECK((pid = fork()) >= 0);
513 CHECK(close(sp[0]) == 0);
514 fcntl_tests_recv_0(sp[1]);
515 CHECK(close(sp[1]) == 0);
518 CHECK(close(sp[1]) == 0);
519 fcntl_tests_send_0(sp[0]);
520 CHECK(waitpid(pid, NULL, 0) == pid);
521 CHECK(close(sp[0]) == 0);
524 /* Send descriptors from child to parent. */
525 CHECK(socketpair(AF_UNIX, SOCK_STREAM, 0, sp) == 0);
526 CHECK((pid = fork()) >= 0);
528 CHECK(close(sp[0]) == 0);
529 fcntl_tests_send_0(sp[1]);
530 CHECK(close(sp[1]) == 0);
533 CHECK(close(sp[1]) == 0);
534 fcntl_tests_recv_0(sp[0]);
535 CHECK(waitpid(pid, NULL, 0) == pid);
536 CHECK(close(sp[0]) == 0);