xref: /freebsd/tools/regression/capsicum/syscalls/cap_fcntls_limit.c (revision bc96366c864c07ef352edb92017357917c75b36c)
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 
161 	CHECK(cap_fcntls_limit(fd, CAP_FCNTL_GETFL) == 0);
162 	fcntlrights = 0;
163 	CHECK(cap_fcntls_get(fd, &fcntlrights) == 0);
164 	CHECK(fcntlrights == CAP_FCNTL_GETFL);
165 
166 	CHECK(cap_rights_limit(fd, CAP_ALL & ~CAP_FCNTL) == 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 
210 	CHECK(cap_rights_limit(fd, CAP_ALL & ~CAP_FCNTL) == 0);
211 
212 	fcntlrights = CAP_FCNTL_ALL;
213 	CHECK(cap_fcntls_get(fd, &fcntlrights) == 0);
214 	CHECK(fcntlrights == 0);
215 
216 	errno = 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);
222 	errno = 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);
228 
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);
234 
235 	errno = 0;
236 	CHECK(fcntl(fd, F_GETFL) == -1);
237 	CHECK(errno == ENOTCAPABLE);
238 	errno = 0;
239 	CHECK(fcntl(fd, F_SETFL, O_NONBLOCK) == -1);
240 	CHECK(errno == ENOTCAPABLE);
241 	errno = 0;
242 	CHECK(fcntl(fd, F_SETFL, 0) == -1);
243 	CHECK(errno == ENOTCAPABLE);
244 	errno = 0;
245 	CHECK(fcntl(fd, F_GETFL) == -1);
246 	CHECK(errno == ENOTCAPABLE);
247 }
248 
249 static void
250 fcntl_tests_send_0(int sock)
251 {
252 	int fd;
253 
254 	CHECK((fd = socket(AF_UNIX, SOCK_STREAM, 0)) >= 0);
255 	CHECK(descriptor_send(sock, fd) == 0);
256 	CHECK(close(fd) == 0);
257 
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);
262 
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);
267 
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);
272 }
273 
274 static void
275 fcntl_tests_recv_0(int sock)
276 {
277 	uint32_t fcntlrights;
278 	int fd;
279 
280 	CHECK(descriptor_recv(sock, &fd) == 0);
281 
282 	fcntlrights = 0;
283 	CHECK(cap_fcntls_get(fd, &fcntlrights) == 0);
284 	CHECK(fcntlrights == CAP_FCNTL_ALL);
285 
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);
291 
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);
297 
298 	CHECK(close(fd) == 0);
299 
300 	CHECK(descriptor_recv(sock, &fd) == 0);
301 
302 	fcntlrights = 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);
306 	fcntlrights = 0;
307 	CHECK(cap_fcntls_get(fd, &fcntlrights) == 0);
308 	CHECK(fcntlrights == (CAP_FCNTL_GETFL | CAP_FCNTL_SETFL));
309 
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);
315 
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);
321 
322 	CHECK(close(fd) == 0);
323 
324 	CHECK(descriptor_recv(sock, &fd) == 0);
325 
326 	fcntlrights = 0;
327 	CHECK(cap_fcntls_get(fd, &fcntlrights) == 0);
328 	CHECK(fcntlrights == CAP_FCNTL_GETFL);
329 	errno = 0;
330 	CHECK(cap_fcntls_limit(fd, CAP_FCNTL_GETFL | CAP_FCNTL_SETFL) == -1);
331 	CHECK(errno == ENOTCAPABLE);
332 	fcntlrights = 0;
333 	CHECK(cap_fcntls_get(fd, &fcntlrights) == 0);
334 	CHECK(fcntlrights == CAP_FCNTL_GETFL);
335 	CHECK(cap_fcntls_limit(fd, CAP_FCNTL_GETFL) == 0);
336 	fcntlrights = 0;
337 	CHECK(cap_fcntls_get(fd, &fcntlrights) == 0);
338 	CHECK(fcntlrights == CAP_FCNTL_GETFL);
339 
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);
345 
346 	CHECK(fcntl(fd, F_GETFL) == O_RDWR);
347 	errno = 0;
348 	CHECK(fcntl(fd, F_SETFL, O_NONBLOCK) == -1);
349 	CHECK(errno == ENOTCAPABLE);
350 	CHECK(fcntl(fd, F_GETFL) == O_RDWR);
351 	errno = 0;
352 	CHECK(fcntl(fd, F_SETFL, 0) == -1);
353 	CHECK(errno == ENOTCAPABLE);
354 	CHECK(fcntl(fd, F_GETFL) == O_RDWR);
355 
356 	CHECK(close(fd) == 0);
357 
358 	CHECK(descriptor_recv(sock, &fd) == 0);
359 
360 	fcntlrights = 0;
361 	CHECK(cap_fcntls_get(fd, &fcntlrights) == 0);
362 	CHECK(fcntlrights == 0);
363 	errno = 0;
364 	CHECK(cap_fcntls_limit(fd, CAP_FCNTL_GETFL | CAP_FCNTL_SETFL) == -1);
365 	CHECK(errno == ENOTCAPABLE);
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) == -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_SETFL) == -1);
377 	CHECK(errno == ENOTCAPABLE);
378 	fcntlrights = 0;
379 	CHECK(cap_fcntls_get(fd, &fcntlrights) == 0);
380 	CHECK(fcntlrights == 0);
381 
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);
387 
388 	errno = 0;
389 	CHECK(fcntl(fd, F_GETFL) == -1);
390 	CHECK(errno == ENOTCAPABLE);
391 	errno = 0;
392 	CHECK(fcntl(fd, F_SETFL, O_NONBLOCK) == -1);
393 	CHECK(errno == ENOTCAPABLE);
394 	errno = 0;
395 	CHECK(fcntl(fd, F_SETFL, 0) == -1);
396 	CHECK(errno == ENOTCAPABLE);
397 	errno = 0;
398 	CHECK(fcntl(fd, F_GETFL) == -1);
399 	CHECK(errno == ENOTCAPABLE);
400 
401 	CHECK(close(fd) == 0);
402 }
403 
404 int
405 main(void)
406 {
407 	int fd, pfd, sp[2];
408 	pid_t pid;
409 
410 	printf("1..870\n");
411 
412 	CHECK((fd = socket(AF_UNIX, SOCK_STREAM, 0)) >= 0);
413 	fcntl_tests_0(fd);
414 	CHECK(close(fd) == 0);
415 
416 	CHECK((fd = socket(AF_UNIX, SOCK_STREAM, 0)) >= 0);
417 	fcntl_tests_1(fd);
418 	CHECK(close(fd) == 0);
419 
420 	CHECK((fd = socket(AF_UNIX, SOCK_STREAM, 0)) >= 0);
421 	fcntl_tests_2(fd);
422 	CHECK(close(fd) == 0);
423 
424 	/* Child inherits descriptor and operates on it first. */
425 	CHECK((fd = socket(AF_UNIX, SOCK_STREAM, 0)) >= 0);
426 	CHECK((pid = fork()) >= 0);
427 	if (pid == 0) {
428 		fcntl_tests_0(fd);
429 		CHECK(close(fd) == 0);
430 		exit(0);
431 	} else {
432 		CHECK(waitpid(pid, NULL, 0) == pid);
433 		fcntl_tests_0(fd);
434 	}
435 	CHECK(close(fd) == 0);
436 
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);
440 	if (pid == 0) {
441 		sleep(1);
442 		fcntl_tests_0(fd);
443 		CHECK(close(fd) == 0);
444 		exit(0);
445 	} else {
446 		fcntl_tests_0(fd);
447 		CHECK(waitpid(pid, NULL, 0) == pid);
448 	}
449 	CHECK(close(fd) == 0);
450 
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);
454 	if (pid == 0) {
455 		fcntl_tests_1(fd);
456 		exit(0);
457 	} else {
458 		CHECK(pdwait(pfd) == 0);
459 /*
460 		It fails with EBADF, which I believe is a bug.
461 		CHECK(close(pfd) == 0);
462 */
463 		fcntl_tests_1(fd);
464 	}
465 	CHECK(close(fd) == 0);
466 
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);
470 	if (pid == 0) {
471 		sleep(1);
472 		fcntl_tests_1(fd);
473 		exit(0);
474 	} else {
475 		fcntl_tests_1(fd);
476 		CHECK(pdwait(pfd) == 0);
477 /*
478 		It fails with EBADF, which I believe is a bug.
479 		CHECK(close(pfd) == 0);
480 */
481 	}
482 	CHECK(close(fd) == 0);
483 
484 	/* Child inherits descriptor and operates on it first. */
485 	CHECK((fd = socket(AF_UNIX, SOCK_STREAM, 0)) >= 0);
486 	CHECK((pid = fork()) >= 0);
487 	if (pid == 0) {
488 		fcntl_tests_2(fd);
489 		exit(0);
490 	} else {
491 		CHECK(waitpid(pid, NULL, 0) == pid);
492 		fcntl_tests_2(fd);
493 	}
494 	CHECK(close(fd) == 0);
495 
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);
499 	if (pid == 0) {
500 		sleep(1);
501 		fcntl_tests_2(fd);
502 		exit(0);
503 	} else {
504 		fcntl_tests_2(fd);
505 		CHECK(waitpid(pid, NULL, 0) == pid);
506 	}
507 	CHECK(close(fd) == 0);
508 
509 	/* Send descriptors from parent to child. */
510 	CHECK(socketpair(AF_UNIX, SOCK_STREAM, 0, sp) == 0);
511 	CHECK((pid = fork()) >= 0);
512 	if (pid == 0) {
513 		CHECK(close(sp[0]) == 0);
514 		fcntl_tests_recv_0(sp[1]);
515 		CHECK(close(sp[1]) == 0);
516 		exit(0);
517 	} else {
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);
522 	}
523 
524 	/* Send descriptors from child to parent. */
525 	CHECK(socketpair(AF_UNIX, SOCK_STREAM, 0, sp) == 0);
526 	CHECK((pid = fork()) >= 0);
527 	if (pid == 0) {
528 		CHECK(close(sp[0]) == 0);
529 		fcntl_tests_send_0(sp[1]);
530 		CHECK(close(sp[1]) == 0);
531 		exit(0);
532 	} else {
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);
537 	}
538 
539 	exit(0);
540 }
541