Klaus Demo nginx / 32b000b
Disable symlinks: fixed edge cases of path handling. This includes non-absolute pathnames, multiple slashes and trailing slashes. In collaboration with Valentin Bartenev. Maxim Dounin 10 years ago
1 changed file(s) with 62 addition(s) and 16 deletion(s). Raw diff Collapse all Expand all
561561
562562 #else
563563
564 u_char *p, *cp, *end;
565 ngx_fd_t at_fd;
566 ngx_str_t at_name;
564 u_char *p, *cp, *end;
565 ngx_fd_t at_fd;
566 ngx_str_t at_name;
567 ngx_file_info_t fi;
567568
568569 if (of->disable_symlinks == NGX_DISABLE_SYMLINKS_OFF) {
569570 fd = ngx_open_file(name->data, mode, create, access);
577578 return fd;
578579 }
579580
580 at_fd = ngx_openat_file(AT_FDCWD, "/", NGX_FILE_RDONLY|NGX_FILE_NONBLOCK,
581 NGX_FILE_OPEN, 0);
582
583 if (at_fd == NGX_INVALID_FILE) {
584 of->err = ngx_errno;
585 of->failed = ngx_openat_file_n;
586 return NGX_INVALID_FILE;
587 }
588
581 p = name->data;
582 end = p + name->len;
583
584 at_fd = AT_FDCWD;
589585 at_name = *name;
590 at_name.len = 1;
591
592 end = name->data + name->len;
593 p = name->data + 1;
586
587 if (p[0] == '/') {
588 at_fd = ngx_openat_file(at_fd, "/",
589 NGX_FILE_RDONLY|NGX_FILE_NONBLOCK,
590 NGX_FILE_OPEN, 0);
591
592 if (at_fd == NGX_FILE_ERROR) {
593 of->err = ngx_errno;
594 of->failed = ngx_openat_file_n;
595 return NGX_FILE_ERROR;
596 }
597
598 at_name.len = 1;
599 p++;
600 }
594601
595602 for ( ;; ) {
596603 cp = ngx_strlchr(p, end, '/');
598605 break;
599606 }
600607
608 if (cp == p) {
609 p++;
610 continue;
611 }
612
601613 *cp = '\0';
602614
603615 if (of->disable_symlinks == NGX_DISABLE_SYMLINKS_NOTOWNER) {
627639 p = cp + 1;
628640 at_fd = fd;
629641 at_name.len = cp - at_name.data;
642 }
643
644 if (p == end && at_fd != AT_FDCWD) {
645
646 /*
647 * If pathname ends with a trailing slash, check if last path
648 * component is a directory; if not, fail with ENOTDIR as per
649 * POSIX.
650 *
651 * We use separate check instead of O_DIRECTORY in the loop above,
652 * as O_DIRECTORY doesn't work on FreeBSD 8.
653 *
654 * Note this returns already opened file descriptor, with different
655 * mode/create/access. This is believed to be safe as we don't
656 * use this codepath to create directories.
657 */
658
659 if (ngx_fd_info(at_fd, &fi) == NGX_FILE_ERROR) {
660 of->err = ngx_errno;
661 of->failed = ngx_fd_info_n;
662 fd = NGX_INVALID_FILE;
663
664 goto failed;
665 }
666
667 if (ngx_is_dir(&fi)) {
668 return at_fd;
669 }
670
671 of->err = ENOTDIR;
672 of->failed = ngx_openat_file_n;
673 fd = NGX_INVALID_FILE;
674
675 goto failed;
630676 }
631677
632678 if (of->disable_symlinks == NGX_DISABLE_SYMLINKS_NOTOWNER) {