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