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