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