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