Mercurial > hg > nginx-quic
changeset 6986:0cdee26605f3
Cleaned up r->headers_out.headers allocation error handling.
If initialization of a header failed for some reason after ngx_list_push(),
leaving the header as is can result in uninitialized memory access by
the header filter or the log module. The fix is to clear partially
initialized headers in case of errors.
For the Cache-Control header, the fix is to postpone pushing
r->headers_out.cache_control until its value is completed.
author | Sergey Kandaurov <pluknet@nginx.com> |
---|---|
date | Thu, 20 Apr 2017 18:26:37 +0300 |
parents | 23ecffd5bcfe |
children | 5116cfea1e9a |
files | src/http/modules/ngx_http_auth_basic_module.c src/http/modules/ngx_http_dav_module.c src/http/modules/ngx_http_headers_filter_module.c src/http/modules/ngx_http_range_filter_module.c src/http/modules/ngx_http_static_module.c src/http/modules/perl/nginx.xs src/http/ngx_http_core_module.c src/http/ngx_http_upstream.c |
diffstat | 8 files changed, 28 insertions(+), 15 deletions(-) [+] |
line wrap: on
line diff
--- a/src/http/modules/ngx_http_auth_basic_module.c +++ b/src/http/modules/ngx_http_auth_basic_module.c @@ -361,6 +361,8 @@ ngx_http_auth_basic_set_realm(ngx_http_r basic = ngx_pnalloc(r->pool, len); if (basic == NULL) { + r->headers_out.www_authenticate->hash = 0; + r->headers_out.www_authenticate = NULL; return NGX_HTTP_INTERNAL_SERVER_ERROR; }
--- a/src/http/modules/ngx_http_dav_module.c +++ b/src/http/modules/ngx_http_dav_module.c @@ -1080,6 +1080,7 @@ ngx_http_dav_location(ngx_http_request_t } else { location = ngx_pnalloc(r->pool, r->uri.len); if (location == NULL) { + ngx_http_clear_location(r); return NGX_ERROR; }
--- a/src/http/modules/ngx_http_headers_filter_module.c +++ b/src/http/modules/ngx_http_headers_filter_module.c @@ -271,11 +271,6 @@ ngx_http_set_expires(ngx_http_request_t return NGX_ERROR; } - ccp = ngx_array_push(&r->headers_out.cache_control); - if (ccp == NULL) { - return NGX_ERROR; - } - cc = ngx_list_push(&r->headers_out.headers); if (cc == NULL) { return NGX_ERROR; @@ -283,6 +278,12 @@ ngx_http_set_expires(ngx_http_request_t cc->hash = 1; ngx_str_set(&cc->key, "Cache-Control"); + + ccp = ngx_array_push(&r->headers_out.cache_control); + if (ccp == NULL) { + return NGX_ERROR; + } + *ccp = cc; } else { @@ -470,11 +471,6 @@ ngx_http_add_cache_control(ngx_http_requ } } - ccp = ngx_array_push(&r->headers_out.cache_control); - if (ccp == NULL) { - return NGX_ERROR; - } - cc = ngx_list_push(&r->headers_out.headers); if (cc == NULL) { return NGX_ERROR; @@ -484,6 +480,11 @@ ngx_http_add_cache_control(ngx_http_requ ngx_str_set(&cc->key, "Cache-Control"); cc->value = *value; + ccp = ngx_array_push(&r->headers_out.cache_control); + if (ccp == NULL) { + return NGX_ERROR; + } + *ccp = cc; return NGX_OK;
--- a/src/http/modules/ngx_http_range_filter_module.c +++ b/src/http/modules/ngx_http_range_filter_module.c @@ -425,6 +425,8 @@ ngx_http_range_singlepart_header(ngx_htt content_range->value.data = ngx_pnalloc(r->pool, sizeof("bytes -/") - 1 + 3 * NGX_OFF_T_LEN); if (content_range->value.data == NULL) { + content_range->hash = 0; + r->headers_out.content_range = NULL; return NGX_ERROR; } @@ -594,6 +596,8 @@ ngx_http_range_not_satisfiable(ngx_http_ content_range->value.data = ngx_pnalloc(r->pool, sizeof("bytes */") - 1 + NGX_OFF_T_LEN); if (content_range->value.data == NULL) { + content_range->hash = 0; + r->headers_out.content_range = NULL; return NGX_ERROR; }
--- a/src/http/modules/ngx_http_static_module.c +++ b/src/http/modules/ngx_http_static_module.c @@ -169,6 +169,7 @@ ngx_http_static_handler(ngx_http_request location = ngx_pnalloc(r->pool, len); if (location == NULL) { + ngx_http_clear_location(r); return NGX_HTTP_INTERNAL_SERVER_ERROR; }
--- a/src/http/modules/perl/nginx.xs +++ b/src/http/modules/perl/nginx.xs @@ -510,10 +510,12 @@ header_out(r, key, value) header->hash = 1; if (ngx_http_perl_sv2str(aTHX_ r, &header->key, key) != NGX_OK) { + header->hash = 0; XSRETURN_EMPTY; } if (ngx_http_perl_sv2str(aTHX_ r, &header->value, value) != NGX_OK) { + header->hash = 0; XSRETURN_EMPTY; }
--- a/src/http/ngx_http_core_module.c +++ b/src/http/ngx_http_core_module.c @@ -1002,6 +1002,7 @@ ngx_http_core_find_config_phase(ngx_http p = ngx_pnalloc(r->pool, len); if (p == NULL) { + ngx_http_clear_location(r); ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); return NGX_OK; }
--- a/src/http/ngx_http_upstream.c +++ b/src/http/ngx_http_upstream.c @@ -4897,17 +4897,18 @@ ngx_http_upstream_copy_multi_header_line } } - ph = ngx_array_push(pa); - if (ph == NULL) { - return NGX_ERROR; - } - ho = ngx_list_push(&r->headers_out.headers); if (ho == NULL) { return NGX_ERROR; } *ho = *h; + + ph = ngx_array_push(pa); + if (ph == NULL) { + return NGX_ERROR; + } + *ph = ho; return NGX_OK;