xref: /freebsd/tools/regression/capsicum/syscalls/cap_fcntls_limit.c (revision 59c8e88e72633afbc47a4ace0d2170d00d51f7dc)
1 /*-
2  * Copyright (c) 2012 The FreeBSD Foundation
3  * All rights reserved.
4  *
5  * This software was developed by Pawel Jakub Dawidek under sponsorship from
6  * the FreeBSD Foundation.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
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.
16  *
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
27  * SUCH DAMAGE.
28  */
29 
30 #include <sys/types.h>
31 #include <sys/capsicum.h>
32 #include <sys/procdesc.h>
33 #include <sys/socket.h>
34 #include <sys/wait.h>
35 
36 #include <err.h>
37 #include <errno.h>
38 #include <stdio.h>
39 #include <stdlib.h>
40 #include <unistd.h>
41 
42 #include "misc.h"
43 
44 static void
45 fcntl_tests_0(int fd)
46 {
47 	uint32_t fcntlrights;
48 
49 	fcntlrights = 0;
50 	CHECK(cap_fcntls_get(fd, &fcntlrights) == 0);
51 	CHECK(fcntlrights == CAP_FCNTL_ALL);
52 
53 	CHECK(fcntl(fd, F_GETFD) == 0);
54 	CHECK(fcntl(fd, F_SETFD, FD_CLOEXEC) == 0);
55 	CHECK(fcntl(fd, F_GETFD) == FD_CLOEXEC);
56 	CHECK(fcntl(fd, F_SETFD, 0) == 0);
57 	CHECK(fcntl(fd, F_GETFD) == 0);
58 
59 	CHECK(fcntl(fd, F_GETFL) == O_RDWR);
60 	CHECK(fcntl(fd, F_SETFL, O_NONBLOCK) == 0);
61 	CHECK(fcntl(fd, F_GETFL) == (O_RDWR | O_NONBLOCK));
62 	CHECK(fcntl(fd, F_SETFL, 0) == 0);
63 	CHECK(fcntl(fd, F_GETFL) == O_RDWR);
64 
65 	errno = 0;
66 	CHECK(cap_fcntls_limit(fd, ~CAP_FCNTL_ALL) == -1);
67 	CHECK(errno == EINVAL);
68 	CHECK(cap_fcntls_limit(fd, CAP_FCNTL_GETFL | CAP_FCNTL_SETFL) == 0);
69 	fcntlrights = 0;
70 	CHECK(cap_fcntls_get(fd, &fcntlrights) == 0);
71 	CHECK(fcntlrights == (CAP_FCNTL_GETFL | CAP_FCNTL_SETFL));
72 	CHECK(cap_fcntls_limit(fd, CAP_FCNTL_GETFL | CAP_FCNTL_SETFL) == 0);
73 	fcntlrights = 0;
74 	CHECK(cap_fcntls_get(fd, &fcntlrights) == 0);
75 	CHECK(fcntlrights == (CAP_FCNTL_GETFL | CAP_FCNTL_SETFL));
76 
77 	CHECK(fcntl(fd, F_GETFD) == 0);
78 	CHECK(fcntl(fd, F_SETFD, FD_CLOEXEC) == 0);
79 	CHECK(fcntl(fd, F_GETFD) == FD_CLOEXEC);
80 	CHECK(fcntl(fd, F_SETFD, 0) == 0);
81 	CHECK(fcntl(fd, F_GETFD) == 0);
82 
83 	CHECK(fcntl(fd, F_GETFL) == O_RDWR);
84 	CHECK(fcntl(fd, F_SETFL, O_NONBLOCK) == 0);
85 	CHECK(fcntl(fd, F_GETFL) == (O_RDWR | O_NONBLOCK));
86 	CHECK(fcntl(fd, F_SETFL, 0) == 0);
87 	CHECK(fcntl(fd, F_GETFL) == O_RDWR);
88 
89 	CHECK(cap_fcntls_limit(fd, CAP_FCNTL_GETFL) == 0);
90 	fcntlrights = 0;
91 	CHECK(cap_fcntls_get(fd, &fcntlrights) == 0);
92 	CHECK(fcntlrights == CAP_FCNTL_GETFL);
93 	errno = 0;
94 	CHECK(cap_fcntls_limit(fd, CAP_FCNTL_GETFL | CAP_FCNTL_SETFL) == -1);
95 	CHECK(errno == ENOTCAPABLE);
96 	fcntlrights = 0;
97 	CHECK(cap_fcntls_get(fd, &fcntlrights) == 0);
98 	CHECK(fcntlrights == CAP_FCNTL_GETFL);
99 
100 	CHECK(fcntl(fd, F_GETFD) == 0);
101 	CHECK(fcntl(fd, F_SETFD, FD_CLOEXEC) == 0);
102 	CHECK(fcntl(fd, F_GETFD) == FD_CLOEXEC);
103 	CHECK(fcntl(fd, F_SETFD, 0) == 0);
104 	CHECK(fcntl(fd, F_GETFD) == 0);
105 
106 	CHECK(fcntl(fd, F_GETFL) == O_RDWR);
107 	errno = 0;
108 	CHECK(fcntl(fd, F_SETFL, O_NONBLOCK) == -1);
109 	CHECK(errno == ENOTCAPABLE);
110 	CHECK(fcntl(fd, F_GETFL) == O_RDWR);
111 	errno = 0;
112 	CHECK(fcntl(fd, F_SETFL, 0) == -1);
113 	CHECK(errno == ENOTCAPABLE);
114 	CHECK(fcntl(fd, F_GETFL) == O_RDWR);
115 
116 	CHECK(cap_fcntls_limit(fd, 0) == 0);
117 	fcntlrights = CAP_FCNTL_ALL;
118 	CHECK(cap_fcntls_get(fd, &fcntlrights) == 0);
119 	CHECK(fcntlrights == 0);
120 	errno = 0;
121 	CHECK(cap_fcntls_limit(fd, CAP_FCNTL_GETFL | CAP_FCNTL_SETFL) == -1);
122 	CHECK(errno == ENOTCAPABLE);
123 	fcntlrights = CAP_FCNTL_ALL;
124 	CHECK(cap_fcntls_get(fd, &fcntlrights) == 0);
125 	CHECK(fcntlrights == 0);
126 	errno = 0;
127 	CHECK(cap_fcntls_limit(fd, CAP_FCNTL_GETFL) == -1);
128 	CHECK(errno == ENOTCAPABLE);
129 	fcntlrights = CAP_FCNTL_ALL;
130 	CHECK(cap_fcntls_get(fd, &fcntlrights) == 0);
131 	CHECK(fcntlrights == 0);
132 
133 	CHECK(fcntl(fd, F_GETFD) == 0);
134 	CHECK(fcntl(fd, F_SETFD, FD_CLOEXEC) == 0);
135 	CHECK(fcntl(fd, F_GETFD) == FD_CLOEXEC);
136 	CHECK(fcntl(fd, F_SETFD, 0) == 0);
137 	CHECK(fcntl(fd, F_GETFD) == 0);
138 
139 	errno = 0;
140 	CHECK(fcntl(fd, F_GETFL) == -1);
141 	CHECK(errno == ENOTCAPABLE);
142 	errno = 0;
143 	CHECK(fcntl(fd, F_SETFL, O_NONBLOCK) == -1);
144 	CHECK(errno == ENOTCAPABLE);
145 	errno = 0;
146 	CHECK(fcntl(fd, F_SETFL, 0) == -1);
147 	CHECK(errno == ENOTCAPABLE);
148 	errno = 0;
149 	CHECK(fcntl(fd, F_GETFL) == -1);
150 	CHECK(errno == ENOTCAPABLE);
151 }
152 
153 static void
154 fcntl_tests_1(int fd)
155 {
156 	uint32_t fcntlrights;
157 	cap_rights_t rights;
158 
159 	CHECK(cap_fcntls_limit(fd, CAP_FCNTL_GETFL) == 0);
160 	fcntlrights = 0;
161 	CHECK(cap_fcntls_get(fd, &fcntlrights) == 0);
162 	CHECK(fcntlrights == CAP_FCNTL_GETFL);
163 
164 	CAP_ALL(&rights);
165 	cap_rights_clear(&rights, CAP_FCNTL);
166 	CHECK(cap_rights_limit(fd, &rights) == 0);
167 
168 	fcntlrights = CAP_FCNTL_ALL;
169 	CHECK(cap_fcntls_get(fd, &fcntlrights) == 0);
170 	CHECK(fcntlrights == 0);
171 
172 	errno = 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);
178 	errno = 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);
184 
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);
190 
191 	errno = 0;
192 	CHECK(fcntl(fd, F_GETFL) == -1);
193 	CHECK(errno == ENOTCAPABLE);
194 	errno = 0;
195 	CHECK(fcntl(fd, F_SETFL, O_NONBLOCK) == -1);
196 	CHECK(errno == ENOTCAPABLE);
197 	errno = 0;
198 	CHECK(fcntl(fd, F_SETFL, 0) == -1);
199 	CHECK(errno == ENOTCAPABLE);
200 	errno = 0;
201 	CHECK(fcntl(fd, F_GETFL) == -1);
202 	CHECK(errno == ENOTCAPABLE);
203 }
204 
205 static void
206 fcntl_tests_2(int fd)
207 {
208 	uint32_t fcntlrights;
209 	cap_rights_t rights;
210 
211 	CAP_ALL(&rights);
212 	cap_rights_clear(&rights, CAP_FCNTL);
213 	CHECK(cap_rights_limit(fd, &rights) == 0);
214 
215 	fcntlrights = CAP_FCNTL_ALL;
216 	CHECK(cap_fcntls_get(fd, &fcntlrights) == 0);
217 	CHECK(fcntlrights == 0);
218 
219 	errno = 0;
220 	CHECK(cap_fcntls_limit(fd, CAP_FCNTL_GETFL | CAP_FCNTL_SETFL) == -1);
221 	CHECK(errno == ENOTCAPABLE);
222 	fcntlrights = CAP_FCNTL_ALL;
223 	CHECK(cap_fcntls_get(fd, &fcntlrights) == 0);
224 	CHECK(fcntlrights == 0);
225 	errno = 0;
226 	CHECK(cap_fcntls_limit(fd, CAP_FCNTL_GETFL) == -1);
227 	CHECK(errno == ENOTCAPABLE);
228 	fcntlrights = CAP_FCNTL_ALL;
229 	CHECK(cap_fcntls_get(fd, &fcntlrights) == 0);
230 	CHECK(fcntlrights == 0);
231 
232 	CHECK(fcntl(fd, F_GETFD) == 0);
233 	CHECK(fcntl(fd, F_SETFD, FD_CLOEXEC) == 0);
234 	CHECK(fcntl(fd, F_GETFD) == FD_CLOEXEC);
235 	CHECK(fcntl(fd, F_SETFD, 0) == 0);
236 	CHECK(fcntl(fd, F_GETFD) == 0);
237 
238 	errno = 0;
239 	CHECK(fcntl(fd, F_GETFL) == -1);
240 	CHECK(errno == ENOTCAPABLE);
241 	errno = 0;
242 	CHECK(fcntl(fd, F_SETFL, O_NONBLOCK) == -1);
243 	CHECK(errno == ENOTCAPABLE);
244 	errno = 0;
245 	CHECK(fcntl(fd, F_SETFL, 0) == -1);
246 	CHECK(errno == ENOTCAPABLE);
247 	errno = 0;
248 	CHECK(fcntl(fd, F_GETFL) == -1);
249 	CHECK(errno == ENOTCAPABLE);
250 }
251 
252 static void
253 fcntl_tests_send_0(int sock)
254 {
255 	int fd;
256 
257 	CHECK((fd = socket(AF_UNIX, SOCK_STREAM, 0)) >= 0);
258 	CHECK(descriptor_send(sock, fd) == 0);
259 	CHECK(close(fd) == 0);
260 
261 	CHECK((fd = socket(AF_UNIX, SOCK_STREAM, 0)) >= 0);
262 	CHECK(cap_fcntls_limit(fd, CAP_FCNTL_GETFL | CAP_FCNTL_SETFL) == 0);
263 	CHECK(descriptor_send(sock, fd) == 0);
264 	CHECK(close(fd) == 0);
265 
266 	CHECK((fd = socket(AF_UNIX, SOCK_STREAM, 0)) >= 0);
267 	CHECK(cap_fcntls_limit(fd, CAP_FCNTL_GETFL) == 0);
268 	CHECK(descriptor_send(sock, fd) == 0);
269 	CHECK(close(fd) == 0);
270 
271 	CHECK((fd = socket(AF_UNIX, SOCK_STREAM, 0)) >= 0);
272 	CHECK(cap_fcntls_limit(fd, 0) == 0);
273 	CHECK(descriptor_send(sock, fd) == 0);
274 	CHECK(close(fd) == 0);
275 }
276 
277 static void
278 fcntl_tests_recv_0(int sock)
279 {
280 	uint32_t fcntlrights;
281 	int fd;
282 
283 	CHECK(descriptor_recv(sock, &fd) == 0);
284 
285 	fcntlrights = 0;
286 	CHECK(cap_fcntls_get(fd, &fcntlrights) == 0);
287 	CHECK(fcntlrights == CAP_FCNTL_ALL);
288 
289 	CHECK(fcntl(fd, F_GETFD) == 0);
290 	CHECK(fcntl(fd, F_SETFD, FD_CLOEXEC) == 0);
291 	CHECK(fcntl(fd, F_GETFD) == FD_CLOEXEC);
292 	CHECK(fcntl(fd, F_SETFD, 0) == 0);
293 	CHECK(fcntl(fd, F_GETFD) == 0);
294 
295 	CHECK(fcntl(fd, F_GETFL) == O_RDWR);
296 	CHECK(fcntl(fd, F_SETFL, O_NONBLOCK) == 0);
297 	CHECK(fcntl(fd, F_GETFL) == (O_RDWR | O_NONBLOCK));
298 	CHECK(fcntl(fd, F_SETFL, 0) == 0);
299 	CHECK(fcntl(fd, F_GETFL) == O_RDWR);
300 
301 	CHECK(close(fd) == 0);
302 
303 	CHECK(descriptor_recv(sock, &fd) == 0);
304 
305 	fcntlrights = 0;
306 	CHECK(cap_fcntls_get(fd, &fcntlrights) == 0);
307 	CHECK(fcntlrights == (CAP_FCNTL_GETFL | CAP_FCNTL_SETFL));
308 	CHECK(cap_fcntls_limit(fd, CAP_FCNTL_GETFL | CAP_FCNTL_SETFL) == 0);
309 	fcntlrights = 0;
310 	CHECK(cap_fcntls_get(fd, &fcntlrights) == 0);
311 	CHECK(fcntlrights == (CAP_FCNTL_GETFL | CAP_FCNTL_SETFL));
312 
313 	CHECK(fcntl(fd, F_GETFD) == 0);
314 	CHECK(fcntl(fd, F_SETFD, FD_CLOEXEC) == 0);
315 	CHECK(fcntl(fd, F_GETFD) == FD_CLOEXEC);
316 	CHECK(fcntl(fd, F_SETFD, 0) == 0);
317 	CHECK(fcntl(fd, F_GETFD) == 0);
318 
319 	CHECK(fcntl(fd, F_GETFL) == O_RDWR);
320 	CHECK(fcntl(fd, F_SETFL, O_NONBLOCK) == 0);
321 	CHECK(fcntl(fd, F_GETFL) == (O_RDWR | O_NONBLOCK));
322 	CHECK(fcntl(fd, F_SETFL, 0) == 0);
323 	CHECK(fcntl(fd, F_GETFL) == O_RDWR);
324 
325 	CHECK(close(fd) == 0);
326 
327 	CHECK(descriptor_recv(sock, &fd) == 0);
328 
329 	fcntlrights = 0;
330 	CHECK(cap_fcntls_get(fd, &fcntlrights) == 0);
331 	CHECK(fcntlrights == CAP_FCNTL_GETFL);
332 	errno = 0;
333 	CHECK(cap_fcntls_limit(fd, CAP_FCNTL_GETFL | CAP_FCNTL_SETFL) == -1);
334 	CHECK(errno == ENOTCAPABLE);
335 	fcntlrights = 0;
336 	CHECK(cap_fcntls_get(fd, &fcntlrights) == 0);
337 	CHECK(fcntlrights == CAP_FCNTL_GETFL);
338 	CHECK(cap_fcntls_limit(fd, CAP_FCNTL_GETFL) == 0);
339 	fcntlrights = 0;
340 	CHECK(cap_fcntls_get(fd, &fcntlrights) == 0);
341 	CHECK(fcntlrights == CAP_FCNTL_GETFL);
342 
343 	CHECK(fcntl(fd, F_GETFD) == 0);
344 	CHECK(fcntl(fd, F_SETFD, FD_CLOEXEC) == 0);
345 	CHECK(fcntl(fd, F_GETFD) == FD_CLOEXEC);
346 	CHECK(fcntl(fd, F_SETFD, 0) == 0);
347 	CHECK(fcntl(fd, F_GETFD) == 0);
348 
349 	CHECK(fcntl(fd, F_GETFL) == O_RDWR);
350 	errno = 0;
351 	CHECK(fcntl(fd, F_SETFL, O_NONBLOCK) == -1);
352 	CHECK(errno == ENOTCAPABLE);
353 	CHECK(fcntl(fd, F_GETFL) == O_RDWR);
354 	errno = 0;
355 	CHECK(fcntl(fd, F_SETFL, 0) == -1);
356 	CHECK(errno == ENOTCAPABLE);
357 	CHECK(fcntl(fd, F_GETFL) == O_RDWR);
358 
359 	CHECK(close(fd) == 0);
360 
361 	CHECK(descriptor_recv(sock, &fd) == 0);
362 
363 	fcntlrights = 0;
364 	CHECK(cap_fcntls_get(fd, &fcntlrights) == 0);
365 	CHECK(fcntlrights == 0);
366 	errno = 0;
367 	CHECK(cap_fcntls_limit(fd, CAP_FCNTL_GETFL | CAP_FCNTL_SETFL) == -1);
368 	CHECK(errno == ENOTCAPABLE);
369 	fcntlrights = 0;
370 	CHECK(cap_fcntls_get(fd, &fcntlrights) == 0);
371 	CHECK(fcntlrights == 0);
372 	errno = 0;
373 	CHECK(cap_fcntls_limit(fd, CAP_FCNTL_GETFL) == -1);
374 	CHECK(errno == ENOTCAPABLE);
375 	fcntlrights = 0;
376 	CHECK(cap_fcntls_get(fd, &fcntlrights) == 0);
377 	CHECK(fcntlrights == 0);
378 	errno = 0;
379 	CHECK(cap_fcntls_limit(fd, CAP_FCNTL_SETFL) == -1);
380 	CHECK(errno == ENOTCAPABLE);
381 	fcntlrights = 0;
382 	CHECK(cap_fcntls_get(fd, &fcntlrights) == 0);
383 	CHECK(fcntlrights == 0);
384 
385 	CHECK(fcntl(fd, F_GETFD) == 0);
386 	CHECK(fcntl(fd, F_SETFD, FD_CLOEXEC) == 0);
387 	CHECK(fcntl(fd, F_GETFD) == FD_CLOEXEC);
388 	CHECK(fcntl(fd, F_SETFD, 0) == 0);
389 	CHECK(fcntl(fd, F_GETFD) == 0);
390 
391 	errno = 0;
392 	CHECK(fcntl(fd, F_GETFL) == -1);
393 	CHECK(errno == ENOTCAPABLE);
394 	errno = 0;
395 	CHECK(fcntl(fd, F_SETFL, O_NONBLOCK) == -1);
396 	CHECK(errno == ENOTCAPABLE);
397 	errno = 0;
398 	CHECK(fcntl(fd, F_SETFL, 0) == -1);
399 	CHECK(errno == ENOTCAPABLE);
400 	errno = 0;
401 	CHECK(fcntl(fd, F_GETFL) == -1);
402 	CHECK(errno == ENOTCAPABLE);
403 
404 	CHECK(close(fd) == 0);
405 }
406 
407 int
408 main(void)
409 {
410 	int fd, pfd, sp[2];
411 	pid_t pid;
412 
413 	printf("1..870\n");
414 
415 	CHECK((fd = socket(AF_UNIX, SOCK_STREAM, 0)) >= 0);
416 	fcntl_tests_0(fd);
417 	CHECK(close(fd) == 0);
418 
419 	CHECK((fd = socket(AF_UNIX, SOCK_STREAM, 0)) >= 0);
420 	fcntl_tests_1(fd);
421 	CHECK(close(fd) == 0);
422 
423 	CHECK((fd = socket(AF_UNIX, SOCK_STREAM, 0)) >= 0);
424 	fcntl_tests_2(fd);
425 	CHECK(close(fd) == 0);
426 
427 	/* Child inherits descriptor and operates on it first. */
428 	CHECK((fd = socket(AF_UNIX, SOCK_STREAM, 0)) >= 0);
429 	CHECK((pid = fork()) >= 0);
430 	if (pid == 0) {
431 		fcntl_tests_0(fd);
432 		CHECK(close(fd) == 0);
433 		exit(0);
434 	} else {
435 		CHECK(waitpid(pid, NULL, 0) == pid);
436 		fcntl_tests_0(fd);
437 	}
438 	CHECK(close(fd) == 0);
439 
440 	/* Child inherits descriptor, but operates on it after parent. */
441 	CHECK((fd = socket(AF_UNIX, SOCK_STREAM, 0)) >= 0);
442 	CHECK((pid = fork()) >= 0);
443 	if (pid == 0) {
444 		sleep(1);
445 		fcntl_tests_0(fd);
446 		CHECK(close(fd) == 0);
447 		exit(0);
448 	} else {
449 		fcntl_tests_0(fd);
450 		CHECK(waitpid(pid, NULL, 0) == pid);
451 	}
452 	CHECK(close(fd) == 0);
453 
454 	/* Child inherits descriptor and operates on it first. */
455 	CHECK((fd = socket(AF_UNIX, SOCK_STREAM, 0)) >= 0);
456 	CHECK((pid = pdfork(&pfd, 0)) >= 0);
457 	if (pid == 0) {
458 		fcntl_tests_1(fd);
459 		exit(0);
460 	} else {
461 		CHECK(pdwait(pfd) == 0);
462 /*
463 		It fails with EBADF, which I believe is a bug.
464 		CHECK(close(pfd) == 0);
465 */
466 		fcntl_tests_1(fd);
467 	}
468 	CHECK(close(fd) == 0);
469 
470 	/* Child inherits descriptor, but operates on it after parent. */
471 	CHECK((fd = socket(AF_UNIX, SOCK_STREAM, 0)) >= 0);
472 	CHECK((pid = pdfork(&pfd, 0)) >= 0);
473 	if (pid == 0) {
474 		sleep(1);
475 		fcntl_tests_1(fd);
476 		exit(0);
477 	} else {
478 		fcntl_tests_1(fd);
479 		CHECK(pdwait(pfd) == 0);
480 /*
481 		It fails with EBADF, which I believe is a bug.
482 		CHECK(close(pfd) == 0);
483 */
484 	}
485 	CHECK(close(fd) == 0);
486 
487 	/* Child inherits descriptor and operates on it first. */
488 	CHECK((fd = socket(AF_UNIX, SOCK_STREAM, 0)) >= 0);
489 	CHECK((pid = fork()) >= 0);
490 	if (pid == 0) {
491 		fcntl_tests_2(fd);
492 		exit(0);
493 	} else {
494 		CHECK(waitpid(pid, NULL, 0) == pid);
495 		fcntl_tests_2(fd);
496 	}
497 	CHECK(close(fd) == 0);
498 
499 	/* Child inherits descriptor, but operates on it after parent. */
500 	CHECK((fd = socket(AF_UNIX, SOCK_STREAM, 0)) >= 0);
501 	CHECK((pid = fork()) >= 0);
502 	if (pid == 0) {
503 		sleep(1);
504 		fcntl_tests_2(fd);
505 		exit(0);
506 	} else {
507 		fcntl_tests_2(fd);
508 		CHECK(waitpid(pid, NULL, 0) == pid);
509 	}
510 	CHECK(close(fd) == 0);
511 
512 	/* Send descriptors from parent to child. */
513 	CHECK(socketpair(AF_UNIX, SOCK_STREAM, 0, sp) == 0);
514 	CHECK((pid = fork()) >= 0);
515 	if (pid == 0) {
516 		CHECK(close(sp[0]) == 0);
517 		fcntl_tests_recv_0(sp[1]);
518 		CHECK(close(sp[1]) == 0);
519 		exit(0);
520 	} else {
521 		CHECK(close(sp[1]) == 0);
522 		fcntl_tests_send_0(sp[0]);
523 		CHECK(waitpid(pid, NULL, 0) == pid);
524 		CHECK(close(sp[0]) == 0);
525 	}
526 
527 	/* Send descriptors from child to parent. */
528 	CHECK(socketpair(AF_UNIX, SOCK_STREAM, 0, sp) == 0);
529 	CHECK((pid = fork()) >= 0);
530 	if (pid == 0) {
531 		CHECK(close(sp[0]) == 0);
532 		fcntl_tests_send_0(sp[1]);
533 		CHECK(close(sp[1]) == 0);
534 		exit(0);
535 	} else {
536 		CHECK(close(sp[1]) == 0);
537 		fcntl_tests_recv_0(sp[0]);
538 		CHECK(waitpid(pid, NULL, 0) == pid);
539 		CHECK(close(sp[0]) == 0);
540 	}
541 
542 	exit(0);
543 }
544