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