1 /*- 2 * Copyright (c) 2021 Mariusz Zaborski <oshogbo@FreeBSD.org> 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 13 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 14 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 15 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 17 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 19 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 20 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 21 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 22 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 23 * POSSIBILITY OF SUCH DAMAGE. 24 */ 25 26 #include <sys/cdefs.h> 27 #include <sys/param.h> 28 #include <sys/capsicum.h> 29 #include <sys/stat.h> 30 31 #include <errno.h> 32 #include <fcntl.h> 33 #include <stdio.h> 34 35 #include <atf-c.h> 36 37 #include <libcasper.h> 38 #include <casper/cap_fileargs.h> 39 40 #include "freebsd_test_suite/macros.h" 41 42 #define MAX_FILES 200 43 44 static char *files[MAX_FILES]; 45 static int fds[MAX_FILES]; 46 47 #define TEST_FILE "/etc/passwd" 48 49 static void 50 check_capsicum(void) 51 { 52 ATF_REQUIRE_FEATURE("security_capabilities"); 53 ATF_REQUIRE_FEATURE("security_capability_mode"); 54 } 55 56 static void 57 prepare_files(size_t num, bool create) 58 { 59 const char template[] = "testsfiles.XXXXXXXX"; 60 size_t i; 61 62 for (i = 0; i < num; i++) { 63 files[i] = calloc(1, sizeof(template)); 64 ATF_REQUIRE(files[i] != NULL); 65 strncpy(files[i], template, sizeof(template) - 1); 66 67 if (create) { 68 fds[i] = mkstemp(files[i]); 69 ATF_REQUIRE(fds[i] >= 0); 70 } else { 71 fds[i] = -1; 72 ATF_REQUIRE(mktemp(files[i]) != NULL); 73 } 74 } 75 } 76 77 static void 78 clear_files(void) 79 { 80 size_t i; 81 82 83 for (i = 0; files[i] != NULL; i++) { 84 unlink(files[i]); 85 free(files[i]); 86 if (fds[i] != -1) 87 close(fds[i]); 88 } 89 } 90 91 static int 92 test_file_open(fileargs_t *fa, const char *file, int *fdp) 93 { 94 int fd; 95 96 fd = fileargs_open(fa, file); 97 if (fd < 0) 98 return (errno); 99 100 if (fdp != NULL) { 101 *fdp = fd; 102 } 103 104 return (0); 105 } 106 107 static int 108 test_file_fopen(fileargs_t *fa, const char *file, const char *mode, 109 FILE **retfile) 110 { 111 FILE *pfile; 112 113 pfile = fileargs_fopen(fa, file, mode); 114 if (pfile == NULL) 115 return (errno); 116 117 if (retfile != NULL) { 118 *retfile = pfile; 119 } 120 121 return (0); 122 } 123 124 static int 125 test_file_lstat(fileargs_t *fa, const char *file) 126 { 127 struct stat fasb, origsb; 128 bool equals; 129 130 if (fileargs_lstat(fa, file, &fasb) < 0) 131 return (errno); 132 133 ATF_REQUIRE(lstat(file, &origsb) == 0); 134 135 equals = true; 136 equals &= (origsb.st_dev == fasb.st_dev); 137 equals &= (origsb.st_ino == fasb.st_ino); 138 equals &= (origsb.st_nlink == fasb.st_nlink); 139 equals &= (origsb.st_flags == fasb.st_flags); 140 equals &= (memcmp(&origsb.st_ctim, &fasb.st_ctim, 141 sizeof(fasb.st_ctim)) == 0); 142 equals &= (memcmp(&origsb.st_birthtim, &fasb.st_birthtim, 143 sizeof(fasb.st_birthtim)) == 0); 144 if (!equals) { 145 return (EINVAL); 146 } 147 148 return (0); 149 } 150 151 static int 152 test_file_realpath_static(fileargs_t *fa, const char *file) 153 { 154 char fapath[PATH_MAX], origpath[PATH_MAX]; 155 156 if (fileargs_realpath(fa, file, fapath) == NULL) 157 return (errno); 158 159 ATF_REQUIRE(realpath(file, origpath) != NULL); 160 161 if (strcmp(fapath, origpath) != 0) 162 return (EINVAL); 163 164 return (0); 165 } 166 167 static int 168 test_file_realpath_alloc(fileargs_t *fa, const char *file) 169 { 170 char *fapath, *origpath; 171 int serrno; 172 173 fapath = fileargs_realpath(fa, file, NULL); 174 if (fapath == NULL) 175 return (errno); 176 177 origpath = realpath(file, NULL); 178 ATF_REQUIRE(origpath != NULL); 179 180 serrno = 0; 181 if (strcmp(fapath, origpath) != 0) 182 serrno = EINVAL; 183 184 free(fapath); 185 free(origpath); 186 187 return (serrno); 188 } 189 190 static int 191 test_file_realpath(fileargs_t *fa, const char *file) 192 { 193 int serrno; 194 195 serrno = test_file_realpath_static(fa, file); 196 if (serrno != 0) 197 return serrno; 198 199 return (test_file_realpath_alloc(fa, file)); 200 } 201 202 static int 203 test_file_mode(int fd, int mode) 204 { 205 int flags; 206 207 flags = fcntl(fd, F_GETFL, 0); 208 if (flags < 0) 209 return (errno); 210 211 if ((flags & O_ACCMODE) != mode) 212 return (errno); 213 214 return (0); 215 } 216 217 static bool 218 test_file_cap(int fd, cap_rights_t *rights) 219 { 220 cap_rights_t fdrights; 221 222 ATF_REQUIRE(cap_rights_get(fd, &fdrights) == 0); 223 224 return (cap_rights_contains(&fdrights, rights)); 225 } 226 227 static int 228 test_file_write(int fd) 229 { 230 char buf; 231 232 buf = 't'; 233 if (write(fd, &buf, sizeof(buf)) != sizeof(buf)) { 234 return (errno); 235 } 236 237 return (0); 238 } 239 240 static int 241 test_file_read(int fd) 242 { 243 char buf; 244 245 if (read(fd, &buf, sizeof(buf)) < 0) { 246 return (errno); 247 } 248 249 return (0); 250 } 251 252 static int 253 test_file_fwrite(FILE *pfile) 254 { 255 char buf; 256 257 buf = 't'; 258 if (fwrite(&buf, sizeof(buf), 1, pfile) != sizeof(buf)) 259 return (errno); 260 261 return (0); 262 } 263 264 static int 265 test_file_fread(FILE *pfile) 266 { 267 char buf; 268 int ret, serrno; 269 270 errno = 0; 271 ret = fread(&buf, sizeof(buf), 1, pfile); 272 serrno = errno; 273 if (ret < 0) { 274 return (serrno); 275 } else if (ret == 0 && feof(pfile) == 0) { 276 return (serrno != 0 ? serrno : EINVAL); 277 } 278 279 return (0); 280 } 281 282 ATF_TC_WITH_CLEANUP(fileargs__open_read); 283 ATF_TC_HEAD(fileargs__open_read, tc) {} 284 ATF_TC_BODY(fileargs__open_read, tc) 285 { 286 cap_rights_t rights, norights; 287 fileargs_t *fa; 288 size_t i; 289 int fd; 290 291 check_capsicum(); 292 293 prepare_files(MAX_FILES, true); 294 295 cap_rights_init(&rights, CAP_READ | CAP_FCNTL); 296 cap_rights_init(&norights, CAP_WRITE); 297 fa = fileargs_init(MAX_FILES, files, O_RDONLY, 0, &rights, 298 FA_OPEN); 299 ATF_REQUIRE(fa != NULL); 300 301 for (i = 0; i < MAX_FILES; i++) { 302 /* ALLOWED */ 303 /* We open file twice to check if we can. */ 304 ATF_REQUIRE(test_file_open(fa, files[i], &fd) == 0); 305 ATF_REQUIRE(close(fd) == 0); 306 307 ATF_REQUIRE(test_file_open(fa, files[i], &fd) == 0); 308 ATF_REQUIRE(test_file_mode(fd, O_RDONLY) == 0); 309 ATF_REQUIRE(test_file_cap(fd, &rights) == true); 310 ATF_REQUIRE(test_file_read(fd) == 0); 311 312 /* DISALLOWED */ 313 ATF_REQUIRE(test_file_lstat(fa, files[i]) == ENOTCAPABLE); 314 ATF_REQUIRE(test_file_open(fa, TEST_FILE, NULL) == ENOTCAPABLE); 315 ATF_REQUIRE(test_file_cap(fd, &norights) == false); 316 ATF_REQUIRE(test_file_write(fd) == ENOTCAPABLE); 317 ATF_REQUIRE(test_file_realpath(fa, files[i]) == ENOTCAPABLE); 318 ATF_REQUIRE(test_file_realpath(fa, TEST_FILE) == ENOTCAPABLE); 319 320 /* CLOSE */ 321 ATF_REQUIRE(close(fd) == 0); 322 } 323 } 324 ATF_TC_CLEANUP(fileargs__open_read, tc) 325 { 326 clear_files(); 327 } 328 329 ATF_TC_WITH_CLEANUP(fileargs__open_write); 330 ATF_TC_HEAD(fileargs__open_write, tc) {} 331 ATF_TC_BODY(fileargs__open_write, tc) 332 { 333 cap_rights_t rights, norights; 334 fileargs_t *fa; 335 size_t i; 336 int fd; 337 338 check_capsicum(); 339 340 prepare_files(MAX_FILES, true); 341 342 cap_rights_init(&rights, CAP_WRITE | CAP_FCNTL); 343 cap_rights_init(&norights, CAP_READ); 344 fa = fileargs_init(MAX_FILES, files, O_WRONLY, 0, &rights, 345 FA_OPEN); 346 ATF_REQUIRE(fa != NULL); 347 348 for (i = 0; i < MAX_FILES; i++) { 349 /* ALLOWED */ 350 /* We open file twice to check if we can. */ 351 ATF_REQUIRE(test_file_open(fa, files[i], &fd) == 0); 352 ATF_REQUIRE(close(fd) == 0); 353 354 ATF_REQUIRE(test_file_open(fa, files[i], &fd) == 0); 355 ATF_REQUIRE(test_file_mode(fd, O_WRONLY) == 0); 356 ATF_REQUIRE(test_file_cap(fd, &rights) == true); 357 ATF_REQUIRE(test_file_write(fd) == 0); 358 359 /* DISALLOWED */ 360 ATF_REQUIRE(test_file_lstat(fa, files[i]) == ENOTCAPABLE); 361 ATF_REQUIRE(test_file_open(fa, TEST_FILE, NULL) == ENOTCAPABLE); 362 ATF_REQUIRE(test_file_cap(fd, &norights) == false); 363 ATF_REQUIRE(test_file_read(fd) == ENOTCAPABLE); 364 ATF_REQUIRE(test_file_realpath(fa, files[i]) == ENOTCAPABLE); 365 ATF_REQUIRE(test_file_realpath(fa, TEST_FILE) == ENOTCAPABLE); 366 367 /* CLOSE */ 368 ATF_REQUIRE(close(fd) == 0); 369 } 370 } 371 ATF_TC_CLEANUP(fileargs__open_write, tc) 372 { 373 clear_files(); 374 } 375 376 ATF_TC_WITH_CLEANUP(fileargs__open_create); 377 ATF_TC_HEAD(fileargs__open_create, tc) {} 378 ATF_TC_BODY(fileargs__open_create, tc) 379 { 380 cap_rights_t rights, norights; 381 fileargs_t *fa; 382 size_t i; 383 int fd; 384 385 check_capsicum(); 386 387 prepare_files(MAX_FILES, false); 388 389 cap_rights_init(&rights, CAP_WRITE | CAP_FCNTL | CAP_READ); 390 cap_rights_init(&norights, CAP_FCHMOD); 391 fa = fileargs_init(MAX_FILES, files, O_RDWR | O_CREAT, 666, 392 &rights, FA_OPEN); 393 ATF_REQUIRE(fa != NULL); 394 395 for (i = 0; i < MAX_FILES; i++) { 396 /* ALLOWED */ 397 ATF_REQUIRE(test_file_open(fa, files[i], &fd) == 0); 398 399 ATF_REQUIRE(test_file_mode(fd, O_RDWR) == 0); 400 ATF_REQUIRE(test_file_cap(fd, &rights) == true); 401 ATF_REQUIRE(test_file_write(fd) == 0); 402 ATF_REQUIRE(test_file_read(fd) == 0); 403 404 /* DISALLOWED */ 405 ATF_REQUIRE(test_file_lstat(fa, files[i]) == ENOTCAPABLE); 406 ATF_REQUIRE(test_file_open(fa, TEST_FILE, NULL) == ENOTCAPABLE); 407 ATF_REQUIRE(test_file_cap(fd, &norights) == false); 408 ATF_REQUIRE(test_file_realpath(fa, files[i]) == ENOTCAPABLE); 409 ATF_REQUIRE(test_file_realpath(fa, TEST_FILE) == ENOTCAPABLE); 410 411 /* CLOSE */ 412 ATF_REQUIRE(close(fd) == 0); 413 } 414 } 415 ATF_TC_CLEANUP(fileargs__open_create, tc) 416 { 417 clear_files(); 418 } 419 420 ATF_TC_WITH_CLEANUP(fileargs__open_with_casper); 421 ATF_TC_HEAD(fileargs__open_with_casper, tc) {} 422 ATF_TC_BODY(fileargs__open_with_casper, tc) 423 { 424 cap_channel_t *capcas; 425 cap_rights_t rights; 426 fileargs_t *fa; 427 size_t i; 428 int fd; 429 430 check_capsicum(); 431 432 prepare_files(MAX_FILES, true); 433 434 capcas = cap_init(); 435 ATF_REQUIRE(capcas != NULL); 436 437 cap_rights_init(&rights, CAP_READ); 438 fa = fileargs_cinit(capcas, MAX_FILES, files, O_RDONLY, 0, &rights, 439 FA_OPEN); 440 ATF_REQUIRE(fa != NULL); 441 442 for (i = 0; i < MAX_FILES; i++) { 443 /* ALLOWED */ 444 ATF_REQUIRE(test_file_open(fa, files[i], &fd) == 0); 445 ATF_REQUIRE(test_file_read(fd) == 0); 446 447 /* CLOSE */ 448 ATF_REQUIRE(close(fd) == 0); 449 } 450 } 451 ATF_TC_CLEANUP(fileargs__open_with_casper, tc) 452 { 453 clear_files(); 454 } 455 456 ATF_TC_WITH_CLEANUP(fileargs__fopen_read); 457 ATF_TC_HEAD(fileargs__fopen_read, tc) {} 458 ATF_TC_BODY(fileargs__fopen_read, tc) 459 { 460 cap_rights_t rights, norights; 461 fileargs_t *fa; 462 size_t i; 463 FILE *pfile; 464 int fd; 465 466 check_capsicum(); 467 468 prepare_files(MAX_FILES, true); 469 470 cap_rights_init(&rights, CAP_READ | CAP_FCNTL); 471 cap_rights_init(&norights, CAP_WRITE); 472 fa = fileargs_init(MAX_FILES, files, O_RDONLY, 0, &rights, 473 FA_OPEN); 474 ATF_REQUIRE(fa != NULL); 475 476 for (i = 0; i < MAX_FILES; i++) { 477 /* ALLOWED */ 478 /* We fopen file twice to check if we can. */ 479 ATF_REQUIRE(test_file_fopen(fa, files[i], "r", &pfile) == 0); 480 ATF_REQUIRE(fclose(pfile) == 0); 481 482 ATF_REQUIRE(test_file_fopen(fa, files[i], "r", &pfile) == 0); 483 fd = fileno(pfile); 484 ATF_REQUIRE(test_file_mode(fd, O_RDONLY) == 0); 485 ATF_REQUIRE(test_file_cap(fd, &rights) == true); 486 ATF_REQUIRE(test_file_fread(pfile) == 0); 487 488 /* DISALLOWED */ 489 ATF_REQUIRE(test_file_lstat(fa, files[i]) == ENOTCAPABLE); 490 ATF_REQUIRE(test_file_fopen(fa, TEST_FILE, "r", NULL) == 491 ENOTCAPABLE); 492 ATF_REQUIRE(test_file_cap(fd, &norights) == false); 493 ATF_REQUIRE(test_file_fwrite(pfile) == EBADF); 494 ATF_REQUIRE(test_file_realpath(fa, files[i]) == ENOTCAPABLE); 495 ATF_REQUIRE(test_file_realpath(fa, TEST_FILE) == ENOTCAPABLE); 496 497 /* CLOSE */ 498 ATF_REQUIRE(fclose(pfile) == 0); 499 } 500 } 501 ATF_TC_CLEANUP(fileargs__fopen_read, tc) 502 { 503 clear_files(); 504 } 505 506 ATF_TC_WITH_CLEANUP(fileargs__fopen_write); 507 ATF_TC_HEAD(fileargs__fopen_write, tc) {} 508 ATF_TC_BODY(fileargs__fopen_write, tc) 509 { 510 cap_rights_t rights, norights; 511 fileargs_t *fa; 512 size_t i; 513 FILE *pfile; 514 int fd; 515 516 check_capsicum(); 517 518 prepare_files(MAX_FILES, true); 519 520 cap_rights_init(&rights, CAP_WRITE | CAP_FCNTL); 521 cap_rights_init(&norights, CAP_READ); 522 fa = fileargs_init(MAX_FILES, files, O_WRONLY, 0, &rights, 523 FA_OPEN); 524 ATF_REQUIRE(fa != NULL); 525 526 for (i = 0; i < MAX_FILES; i++) { 527 /* ALLOWED */ 528 /* We fopen file twice to check if we can. */ 529 ATF_REQUIRE(test_file_fopen(fa, files[i], "w", &pfile) == 0); 530 ATF_REQUIRE(fclose(pfile) == 0); 531 532 ATF_REQUIRE(test_file_fopen(fa, files[i], "w", &pfile) == 0); 533 fd = fileno(pfile); 534 ATF_REQUIRE(test_file_mode(fd, O_WRONLY) == 0); 535 ATF_REQUIRE(test_file_cap(fd, &rights) == true); 536 ATF_REQUIRE(test_file_fwrite(pfile) == 0); 537 538 /* DISALLOWED */ 539 ATF_REQUIRE(test_file_lstat(fa, files[i]) == ENOTCAPABLE); 540 ATF_REQUIRE(test_file_fopen(fa, TEST_FILE, "w", NULL) == 541 ENOTCAPABLE); 542 ATF_REQUIRE(test_file_cap(fd, &norights) == false); 543 ATF_REQUIRE(test_file_fread(pfile) == EBADF); 544 ATF_REQUIRE(test_file_realpath(fa, files[i]) == ENOTCAPABLE); 545 ATF_REQUIRE(test_file_realpath(fa, TEST_FILE) == ENOTCAPABLE); 546 547 /* CLOSE */ 548 ATF_REQUIRE(fclose(pfile) == 0); 549 } 550 } 551 ATF_TC_CLEANUP(fileargs__fopen_write, tc) 552 { 553 clear_files(); 554 } 555 556 ATF_TC_WITH_CLEANUP(fileargs__fopen_create); 557 ATF_TC_HEAD(fileargs__fopen_create, tc) {} 558 ATF_TC_BODY(fileargs__fopen_create, tc) 559 { 560 cap_rights_t rights; 561 fileargs_t *fa; 562 size_t i; 563 FILE *pfile; 564 int fd; 565 566 check_capsicum(); 567 568 prepare_files(MAX_FILES, false); 569 570 cap_rights_init(&rights, CAP_READ | CAP_WRITE | CAP_FCNTL); 571 fa = fileargs_init(MAX_FILES, files, O_RDWR | O_CREAT, 0, &rights, 572 FA_OPEN); 573 ATF_REQUIRE(fa != NULL); 574 575 for (i = 0; i < MAX_FILES; i++) { 576 /* ALLOWED */ 577 /* We fopen file twice to check if we can. */ 578 ATF_REQUIRE(test_file_fopen(fa, files[i], "w+", &pfile) == 0); 579 fd = fileno(pfile); 580 ATF_REQUIRE(test_file_mode(fd, O_RDWR) == 0); 581 ATF_REQUIRE(test_file_cap(fd, &rights) == true); 582 ATF_REQUIRE(test_file_fwrite(pfile) == 0); 583 ATF_REQUIRE(test_file_fread(pfile) == 0); 584 585 /* DISALLOWED */ 586 ATF_REQUIRE(test_file_lstat(fa, files[i]) == ENOTCAPABLE); 587 ATF_REQUIRE(test_file_fopen(fa, TEST_FILE, "w+", NULL) == 588 ENOTCAPABLE); 589 ATF_REQUIRE(test_file_realpath(fa, files[i]) == ENOTCAPABLE); 590 ATF_REQUIRE(test_file_realpath(fa, TEST_FILE) == ENOTCAPABLE); 591 592 /* CLOSE */ 593 ATF_REQUIRE(fclose(pfile) == 0); 594 } 595 } 596 ATF_TC_CLEANUP(fileargs__fopen_create, tc) 597 { 598 clear_files(); 599 } 600 601 ATF_TC_WITH_CLEANUP(fileargs__lstat); 602 ATF_TC_HEAD(fileargs__lstat, tc) {} 603 ATF_TC_BODY(fileargs__lstat, tc) 604 { 605 fileargs_t *fa; 606 size_t i; 607 int fd; 608 609 check_capsicum(); 610 611 prepare_files(MAX_FILES, true); 612 613 fa = fileargs_init(MAX_FILES, files, 0, 0, NULL, FA_LSTAT); 614 ATF_REQUIRE(fa != NULL); 615 616 for (i = 0; i < MAX_FILES; i++) { 617 /* ALLOWED */ 618 ATF_REQUIRE(test_file_lstat(fa, files[i]) == 0); 619 620 /* DISALLOWED */ 621 ATF_REQUIRE(test_file_open(fa, files[i], &fd) == ENOTCAPABLE); 622 ATF_REQUIRE(test_file_lstat(fa, TEST_FILE) == ENOTCAPABLE); 623 ATF_REQUIRE(test_file_open(fa, TEST_FILE, &fd) == ENOTCAPABLE); 624 ATF_REQUIRE(test_file_realpath(fa, files[i]) == ENOTCAPABLE); 625 ATF_REQUIRE(test_file_realpath(fa, TEST_FILE) == ENOTCAPABLE); 626 } 627 } 628 ATF_TC_CLEANUP(fileargs__lstat, tc) 629 { 630 clear_files(); 631 } 632 633 ATF_TC_WITH_CLEANUP(fileargs__realpath); 634 ATF_TC_HEAD(fileargs__realpath, tc) {} 635 ATF_TC_BODY(fileargs__realpath, tc) 636 { 637 fileargs_t *fa; 638 size_t i; 639 int fd; 640 641 prepare_files(MAX_FILES, true); 642 643 fa = fileargs_init(MAX_FILES, files, 0, 0, NULL, FA_REALPATH); 644 ATF_REQUIRE(fa != NULL); 645 646 for (i = 0; i < MAX_FILES; i++) { 647 /* ALLOWED */ 648 ATF_REQUIRE(test_file_realpath(fa, files[i]) == 0); 649 650 /* DISALLOWED */ 651 ATF_REQUIRE(test_file_open(fa, files[i], &fd) == ENOTCAPABLE); 652 ATF_REQUIRE(test_file_lstat(fa, files[i]) == ENOTCAPABLE); 653 ATF_REQUIRE(test_file_lstat(fa, TEST_FILE) == ENOTCAPABLE); 654 ATF_REQUIRE(test_file_open(fa, TEST_FILE, &fd) == ENOTCAPABLE); 655 ATF_REQUIRE(test_file_realpath(fa, TEST_FILE) == ENOTCAPABLE); 656 } 657 } 658 ATF_TC_CLEANUP(fileargs__realpath, tc) 659 { 660 clear_files(); 661 } 662 663 ATF_TC_WITH_CLEANUP(fileargs__open_lstat); 664 ATF_TC_HEAD(fileargs__open_lstat, tc) {} 665 ATF_TC_BODY(fileargs__open_lstat, tc) 666 { 667 cap_rights_t rights, norights; 668 fileargs_t *fa; 669 size_t i; 670 int fd; 671 672 check_capsicum(); 673 674 prepare_files(MAX_FILES, true); 675 676 cap_rights_init(&rights, CAP_READ | CAP_FCNTL); 677 cap_rights_init(&norights, CAP_WRITE); 678 fa = fileargs_init(MAX_FILES, files, O_RDONLY, 0, &rights, 679 FA_OPEN | FA_LSTAT); 680 ATF_REQUIRE(fa != NULL); 681 682 for (i = 0; i < MAX_FILES; i++) { 683 /* ALLOWED */ 684 /* We open file twice to check if we can. */ 685 ATF_REQUIRE(test_file_lstat(fa, files[i]) == 0); 686 ATF_REQUIRE(test_file_open(fa, files[i], &fd) == 0); 687 ATF_REQUIRE(close(fd) == 0); 688 689 ATF_REQUIRE(test_file_open(fa, files[i], &fd) == 0); 690 ATF_REQUIRE(test_file_lstat(fa, files[i]) == 0); 691 ATF_REQUIRE(test_file_mode(fd, O_RDONLY) == 0); 692 ATF_REQUIRE(test_file_cap(fd, &rights) == true); 693 ATF_REQUIRE(test_file_read(fd) == 0); 694 695 /* DISALLOWED */ 696 ATF_REQUIRE(test_file_open(fa, TEST_FILE, NULL) == ENOTCAPABLE); 697 ATF_REQUIRE(test_file_cap(fd, &norights) == false); 698 ATF_REQUIRE(test_file_write(fd) == ENOTCAPABLE); 699 ATF_REQUIRE(test_file_realpath(fa, files[i]) == ENOTCAPABLE); 700 ATF_REQUIRE(test_file_realpath(fa, TEST_FILE) == ENOTCAPABLE); 701 702 /* CLOSE */ 703 ATF_REQUIRE(close(fd) == 0); 704 } 705 } 706 ATF_TC_CLEANUP(fileargs__open_lstat, tc) 707 { 708 clear_files(); 709 } 710 711 ATF_TC_WITH_CLEANUP(fileargs__open_realpath); 712 ATF_TC_HEAD(fileargs__open_realpath, tc) {} 713 ATF_TC_BODY(fileargs__open_realpath, tc) 714 { 715 cap_rights_t rights, norights; 716 fileargs_t *fa; 717 size_t i; 718 int fd; 719 720 check_capsicum(); 721 722 prepare_files(MAX_FILES, true); 723 724 cap_rights_init(&rights, CAP_READ | CAP_FCNTL); 725 cap_rights_init(&norights, CAP_WRITE); 726 fa = fileargs_init(MAX_FILES, files, O_RDONLY, 0, &rights, 727 FA_OPEN | FA_REALPATH); 728 ATF_REQUIRE(fa != NULL); 729 730 for (i = 0; i < MAX_FILES; i++) { 731 /* ALLOWED */ 732 /* We open file twice to check if we can. */ 733 ATF_REQUIRE(test_file_realpath(fa, files[i]) == 0); 734 ATF_REQUIRE(test_file_open(fa, files[i], &fd) == 0); 735 ATF_REQUIRE(close(fd) == 0); 736 737 ATF_REQUIRE(test_file_open(fa, files[i], &fd) == 0); 738 ATF_REQUIRE(test_file_realpath(fa, files[i]) == 0); 739 ATF_REQUIRE(test_file_mode(fd, O_RDONLY) == 0); 740 ATF_REQUIRE(test_file_cap(fd, &rights) == true); 741 ATF_REQUIRE(test_file_read(fd) == 0); 742 743 /* DISALLOWED */ 744 ATF_REQUIRE(test_file_open(fa, TEST_FILE, NULL) == ENOTCAPABLE); 745 ATF_REQUIRE(test_file_cap(fd, &norights) == false); 746 ATF_REQUIRE(test_file_write(fd) == ENOTCAPABLE); 747 ATF_REQUIRE(test_file_lstat(fa, files[i]) == ENOTCAPABLE); 748 749 /* CLOSE */ 750 ATF_REQUIRE(close(fd) == 0); 751 } 752 } 753 ATF_TC_CLEANUP(fileargs__open_realpath, tc) 754 { 755 clear_files(); 756 } 757 758 ATF_TP_ADD_TCS(tp) 759 { 760 761 ATF_TP_ADD_TC(tp, fileargs__open_create); 762 ATF_TP_ADD_TC(tp, fileargs__open_read); 763 ATF_TP_ADD_TC(tp, fileargs__open_write); 764 ATF_TP_ADD_TC(tp, fileargs__open_with_casper); 765 766 ATF_TP_ADD_TC(tp, fileargs__fopen_create); 767 ATF_TP_ADD_TC(tp, fileargs__fopen_read); 768 ATF_TP_ADD_TC(tp, fileargs__fopen_write); 769 770 ATF_TP_ADD_TC(tp, fileargs__lstat); 771 772 ATF_TP_ADD_TC(tp, fileargs__realpath); 773 774 ATF_TP_ADD_TC(tp, fileargs__open_lstat); 775 ATF_TP_ADD_TC(tp, fileargs__open_realpath); 776 777 return (atf_no_error()); 778 } 779