aboutsummaryrefslogtreecommitdiff
path: root/src/http/ngx_http_core_module.c
diff options
context:
space:
mode:
authorAndrey Belov <defan@nginx.com>2012-02-13 16:29:04 +0000
committerAndrey Belov <defan@nginx.com>2012-02-13 16:29:04 +0000
commitbd1e719bf9c4bc58076e7b52e87be645c9b803f5 (patch)
treef1c94ff9e91e2d2594ba9d1ae7f92120cca36722 /src/http/ngx_http_core_module.c
parent32c8df44d5f53026d92ec24bcf4c864359395e55 (diff)
downloadnginx-bd1e719bf9c4bc58076e7b52e87be645c9b803f5.tar.gz
nginx-bd1e719bf9c4bc58076e7b52e87be645c9b803f5.zip
Added disable_symlinks directive.
To completely disable symlinks (disable_symlinks on) we use openat(O_NOFOLLOW) for each path component to avoid races. To allow symlinks with the same owner (disable_symlinks if_not_owner), use openat() (followed by fstat()) and fstatat(AT_SYMLINK_NOFOLLOW), and then compare uids between fstat() and fstatat(). As there is a race between openat() and fstatat() we don't know if openat() in fact opened symlink or not. Therefore, we have to compare uids even if fstatat() reports the opened component isn't a symlink (as we don't know whether it was symlink during openat() or not). Default value is off, i.e. symlinks are allowed.
Diffstat (limited to 'src/http/ngx_http_core_module.c')
-rw-r--r--src/http/ngx_http_core_module.c35
1 files changed, 35 insertions, 0 deletions
diff --git a/src/http/ngx_http_core_module.c b/src/http/ngx_http_core_module.c
index f82897dd5..35b538b6e 100644
--- a/src/http/ngx_http_core_module.c
+++ b/src/http/ngx_http_core_module.c
@@ -187,6 +187,18 @@ static ngx_str_t ngx_http_gzip_private = ngx_string("private");
#endif
+#if (NGX_HAVE_OPENAT)
+
+static ngx_conf_enum_t ngx_http_core_disable_symlinks[] = {
+ { ngx_string("off"), NGX_DISABLE_SYMLINKS_OFF },
+ { ngx_string("if_not_owner"), NGX_DISABLE_SYMLINKS_NOTOWNER },
+ { ngx_string("on"), NGX_DISABLE_SYMLINKS_ON },
+ { ngx_null_string, 0 }
+};
+
+#endif
+
+
static ngx_command_t ngx_http_core_commands[] = {
{ ngx_string("variables_hash_max_size"),
@@ -764,6 +776,17 @@ static ngx_command_t ngx_http_core_commands[] = {
#endif
+#if (NGX_HAVE_OPENAT)
+
+ { ngx_string("disable_symlinks"),
+ NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
+ ngx_conf_set_enum_slot,
+ NGX_HTTP_LOC_CONF_OFFSET,
+ offsetof(ngx_http_core_loc_conf_t, disable_symlinks),
+ &ngx_http_core_disable_symlinks },
+
+#endif
+
ngx_null_command
};
@@ -1297,6 +1320,9 @@ ngx_http_core_try_files_phase(ngx_http_request_t *r,
of.test_only = 1;
of.errors = clcf->open_file_cache_errors;
of.events = clcf->open_file_cache_events;
+#if (NGX_HAVE_OPENAT)
+ of.disable_symlinks = clcf->disable_symlinks;
+#endif
if (ngx_open_cached_file(clcf->open_file_cache, &path, &of, r->pool)
!= NGX_OK)
@@ -3344,6 +3370,10 @@ ngx_http_core_create_loc_conf(ngx_conf_t *cf)
#endif
#endif
+#if (NGX_HAVE_OPENAT)
+ clcf->disable_symlinks = NGX_CONF_UNSET_UINT;
+#endif
+
return clcf;
}
@@ -3623,6 +3653,11 @@ ngx_http_core_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
#endif
#endif
+#if (NGX_HAVE_OPENAT)
+ ngx_conf_merge_uint_value(conf->disable_symlinks, prev->disable_symlinks,
+ NGX_DISABLE_SYMLINKS_OFF);
+#endif
+
return NGX_CONF_OK;
}