Mercurial > hg > nginx
changeset 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 | 9806bf07d119 |
files | src/core/ngx_open_file_cache.c src/os/unix/ngx_files.h |
diffstat | 2 files changed, 31 insertions(+), 30 deletions(-) [+] |
line wrap: on
line diff
--- a/src/core/ngx_open_file_cache.c Tue Feb 21 15:04:41 2012 +0000 +++ b/src/core/ngx_open_file_cache.c Tue Feb 21 15:10:13 2012 +0000 @@ -565,7 +565,6 @@ u_char *p, *cp, *end; ngx_fd_t at_fd; ngx_str_t at_name; - ngx_file_info_t fi; if (of->disable_symlinks == NGX_DISABLE_SYMLINKS_OFF) { fd = ngx_open_file(name->data, mode, create, access); @@ -586,7 +585,7 @@ if (*p == '/') { at_fd = ngx_open_file("/", - NGX_FILE_RDONLY|NGX_FILE_NONBLOCK, + NGX_FILE_SEARCH|NGX_FILE_NONBLOCK, NGX_FILE_OPEN, 0); if (at_fd == NGX_INVALID_FILE) { @@ -617,12 +616,12 @@ if (of->disable_symlinks == NGX_DISABLE_SYMLINKS_NOTOWNER) { fd = ngx_openat_file_owner(at_fd, p, - NGX_FILE_RDONLY|NGX_FILE_NONBLOCK, + NGX_FILE_SEARCH|NGX_FILE_NONBLOCK, NGX_FILE_OPEN, 0, log); } else { fd = ngx_openat_file(at_fd, p, - NGX_FILE_RDONLY|NGX_FILE_NONBLOCK|NGX_FILE_NOFOLLOW, + NGX_FILE_SEARCH|NGX_FILE_NONBLOCK|NGX_FILE_NOFOLLOW, NGX_FILE_OPEN, 0); } @@ -647,35 +646,18 @@ if (p == end) { /* - * If pathname ends with a trailing slash, check if last path - * component is a directory; if not, fail with ENOTDIR as per - * POSIX. + * If pathname ends with a trailing slash, assume the last path + * component is a directory and reopen it with requested flags; + * if not, fail with ENOTDIR as per POSIX. * - * We use separate check instead of O_DIRECTORY in the loop above, - * as O_DIRECTORY doesn't work on FreeBSD 8. - * - * Note this returns already opened file descriptor, with different - * mode/create/access. This is believed to be safe as we don't - * use this codepath to create directories. + * We cannot rely on O_DIRECTORY in the loop above to check + * that the last path component is a directory because + * O_DIRECTORY doesn't work on FreeBSD 8. Fortunately, by + * reopening a directory, we don't depend on it at all. */ - if (ngx_fd_info(at_fd, &fi) == NGX_FILE_ERROR) { - of->err = ngx_errno; - of->failed = ngx_fd_info_n; - fd = NGX_INVALID_FILE; - - goto failed; - } - - if (ngx_is_dir(&fi)) { - return at_fd; - } - - of->err = ENOTDIR; - of->failed = ngx_openat_file_n; - fd = NGX_INVALID_FILE; - - goto failed; + fd = ngx_openat_file(at_fd, ".", mode, create, access); + goto done; } if (of->disable_symlinks == NGX_DISABLE_SYMLINKS_NOTOWNER @@ -687,6 +669,8 @@ fd = ngx_openat_file(at_fd, p, mode|NGX_FILE_NOFOLLOW, create, access); } +done: + if (fd == NGX_INVALID_FILE) { of->err = ngx_errno; of->failed = ngx_openat_file_n;
--- a/src/os/unix/ngx_files.h Tue Feb 21 15:04:41 2012 +0000 +++ b/src/os/unix/ngx_files.h Tue Feb 21 15:10:13 2012 +0000 @@ -78,8 +78,25 @@ #if (NGX_HAVE_OPENAT) #define NGX_FILE_NOFOLLOW O_NOFOLLOW + +#if defined(O_DIRECTORY) +#define NGX_FILE_DIRECTORY O_DIRECTORY +#else +#define NGX_FILE_DIRECTORY 0 #endif +#if defined(O_SEARCH) +#define NGX_FILE_SEARCH O_SEARCH|NGX_FILE_DIRECTORY + +#elif defined(O_EXEC) +#define NGX_FILE_SEARCH O_EXEC|NGX_FILE_DIRECTORY + +#else +#define NGX_FILE_SEARCH O_RDONLY|NGX_FILE_DIRECTORY +#endif + +#endif /* NGX_HAVE_OPENAT */ + #define NGX_FILE_DEFAULT_ACCESS 0644 #define NGX_FILE_OWNER_ACCESS 0600