Mercurial > hg > nginx
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 } |