Upstream: disallow empty path in proxy_store and friends.

Renaming a temporary file to an empty path ("") returns NGX_ENOPATH
with a subsequent ngx_create_full_path() to create the full path.
This function skips initial bytes as part of path separator lookup,
which causes out of bounds access on short strings.

The fix is to avoid renaming a temporary file to an obviously invalid
path, as well as explicitly forbid such syntax for literal values.

Although Coverity reports about potential type underflow, it is not
actually possible because the terminating '\0' is always included.

Notably, the run-time check is sufficient enough for Win32 as well.
Other short invalid values result either in NGX_ENOENT or NGX_EEXIST
and "MoveFile() .. failed" critical log messages, which involves a
separate error handling.

Prodded by Coverity (CID 1605485).
This commit is contained in:
Sergey Kandaurov 2024-11-21 12:35:50 +04:00
parent cb1857407b
commit 8187e945a8
5 changed files with 24 additions and 0 deletions

View File

@ -3781,6 +3781,11 @@ ngx_http_fastcgi_store(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
return NGX_CONF_OK;
}
if (value[1].len == 0) {
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "empty path");
return NGX_CONF_ERROR;
}
#if (NGX_HTTP_CACHE)
if (flcf->upstream.cache > 0) {
return "is incompatible with \"fastcgi_cache\"";

View File

@ -4951,6 +4951,11 @@ ngx_http_proxy_store(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
return NGX_CONF_OK;
}
if (value[1].len == 0) {
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "empty path");
return NGX_CONF_ERROR;
}
#if (NGX_HTTP_CACHE)
if (plcf->upstream.cache > 0) {
return "is incompatible with \"proxy_cache\"";

View File

@ -1995,6 +1995,11 @@ ngx_http_scgi_store(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
return NGX_CONF_OK;
}
if (value[1].len == 0) {
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "empty path");
return NGX_CONF_ERROR;
}
#if (NGX_HTTP_CACHE)
if (scf->upstream.cache > 0) {
return "is incompatible with \"scgi_cache\"";

View File

@ -2330,6 +2330,11 @@ ngx_http_uwsgi_store(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
return NGX_CONF_OK;
}
if (value[1].len == 0) {
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "empty path");
return NGX_CONF_ERROR;
}
#if (NGX_HTTP_CACHE)
if (uwcf->upstream.cache > 0) {

View File

@ -4357,6 +4357,10 @@ ngx_http_upstream_store(ngx_http_request_t *r, ngx_http_upstream_t *u)
"upstream stores \"%s\" to \"%s\"",
tf->file.name.data, path.data);
if (path.len == 0) {
return;
}
(void) ngx_ext_rename_file(&tf->file.name, &path, &ext);
u->store = 0;