comparison src/core/ngx_open_file_cache.c @ 4488:d33ce8cd0d70

Disable symlinks: use O_SEARCH|O_DIRECTORY to open path components.
author Valentin Bartenev <vbart@nginx.com>
date Tue, 21 Feb 2012 15:10:13 +0000
parents a786c85e8268
children 47ece8818978
comparison
equal deleted inserted replaced
4487:a786c85e8268 4488:d33ce8cd0d70
563 #else 563 #else
564 564
565 u_char *p, *cp, *end; 565 u_char *p, *cp, *end;
566 ngx_fd_t at_fd; 566 ngx_fd_t at_fd;
567 ngx_str_t at_name; 567 ngx_str_t at_name;
568 ngx_file_info_t fi;
569 568
570 if (of->disable_symlinks == NGX_DISABLE_SYMLINKS_OFF) { 569 if (of->disable_symlinks == NGX_DISABLE_SYMLINKS_OFF) {
571 fd = ngx_open_file(name->data, mode, create, access); 570 fd = ngx_open_file(name->data, mode, create, access);
572 571
573 if (fd == NGX_INVALID_FILE) { 572 if (fd == NGX_INVALID_FILE) {
584 583
585 at_name = *name; 584 at_name = *name;
586 585
587 if (*p == '/') { 586 if (*p == '/') {
588 at_fd = ngx_open_file("/", 587 at_fd = ngx_open_file("/",
589 NGX_FILE_RDONLY|NGX_FILE_NONBLOCK, 588 NGX_FILE_SEARCH|NGX_FILE_NONBLOCK,
590 NGX_FILE_OPEN, 0); 589 NGX_FILE_OPEN, 0);
591 590
592 if (at_fd == NGX_INVALID_FILE) { 591 if (at_fd == NGX_INVALID_FILE) {
593 of->err = ngx_errno; 592 of->err = ngx_errno;
594 of->failed = ngx_openat_file_n; 593 of->failed = ngx_openat_file_n;
615 614
616 *cp = '\0'; 615 *cp = '\0';
617 616
618 if (of->disable_symlinks == NGX_DISABLE_SYMLINKS_NOTOWNER) { 617 if (of->disable_symlinks == NGX_DISABLE_SYMLINKS_NOTOWNER) {
619 fd = ngx_openat_file_owner(at_fd, p, 618 fd = ngx_openat_file_owner(at_fd, p,
620 NGX_FILE_RDONLY|NGX_FILE_NONBLOCK, 619 NGX_FILE_SEARCH|NGX_FILE_NONBLOCK,
621 NGX_FILE_OPEN, 0, log); 620 NGX_FILE_OPEN, 0, log);
622 621
623 } else { 622 } else {
624 fd = ngx_openat_file(at_fd, p, 623 fd = ngx_openat_file(at_fd, p,
625 NGX_FILE_RDONLY|NGX_FILE_NONBLOCK|NGX_FILE_NOFOLLOW, 624 NGX_FILE_SEARCH|NGX_FILE_NONBLOCK|NGX_FILE_NOFOLLOW,
626 NGX_FILE_OPEN, 0); 625 NGX_FILE_OPEN, 0);
627 } 626 }
628 627
629 *cp = '/'; 628 *cp = '/';
630 629
645 } 644 }
646 645
647 if (p == end) { 646 if (p == end) {
648 647
649 /* 648 /*
650 * If pathname ends with a trailing slash, check if last path 649 * If pathname ends with a trailing slash, assume the last path
651 * component is a directory; if not, fail with ENOTDIR as per 650 * component is a directory and reopen it with requested flags;
652 * POSIX. 651 * if not, fail with ENOTDIR as per POSIX.
653 * 652 *
654 * We use separate check instead of O_DIRECTORY in the loop above, 653 * We cannot rely on O_DIRECTORY in the loop above to check
655 * as O_DIRECTORY doesn't work on FreeBSD 8. 654 * that the last path component is a directory because
656 * 655 * O_DIRECTORY doesn't work on FreeBSD 8. Fortunately, by
657 * Note this returns already opened file descriptor, with different 656 * reopening a directory, we don't depend on it at all.
658 * mode/create/access. This is believed to be safe as we don't
659 * use this codepath to create directories.
660 */ 657 */
661 658
662 if (ngx_fd_info(at_fd, &fi) == NGX_FILE_ERROR) { 659 fd = ngx_openat_file(at_fd, ".", mode, create, access);
663 of->err = ngx_errno; 660 goto done;
664 of->failed = ngx_fd_info_n;
665 fd = NGX_INVALID_FILE;
666
667 goto failed;
668 }
669
670 if (ngx_is_dir(&fi)) {
671 return at_fd;
672 }
673
674 of->err = ENOTDIR;
675 of->failed = ngx_openat_file_n;
676 fd = NGX_INVALID_FILE;
677
678 goto failed;
679 } 661 }
680 662
681 if (of->disable_symlinks == NGX_DISABLE_SYMLINKS_NOTOWNER 663 if (of->disable_symlinks == NGX_DISABLE_SYMLINKS_NOTOWNER
682 && !(create & (NGX_FILE_CREATE_OR_OPEN|NGX_FILE_TRUNCATE))) 664 && !(create & (NGX_FILE_CREATE_OR_OPEN|NGX_FILE_TRUNCATE)))
683 { 665 {
684 fd = ngx_openat_file_owner(at_fd, p, mode, create, access, log); 666 fd = ngx_openat_file_owner(at_fd, p, mode, create, access, log);
685 667
686 } else { 668 } else {
687 fd = ngx_openat_file(at_fd, p, mode|NGX_FILE_NOFOLLOW, create, access); 669 fd = ngx_openat_file(at_fd, p, mode|NGX_FILE_NOFOLLOW, create, access);
688 } 670 }
671
672 done:
689 673
690 if (fd == NGX_INVALID_FILE) { 674 if (fd == NGX_INVALID_FILE) {
691 of->err = ngx_errno; 675 of->err = ngx_errno;
692 of->failed = ngx_openat_file_n; 676 of->failed = ngx_openat_file_n;
693 } 677 }