# HG changeset patch # User Sergey Kandaurov # Date 1492701997 -10800 # Node ID 0cdee26605f3c862b5a6a386b9fbefb610601f21 # Parent 23ecffd5bcfe2802c9621a96934a8b23e76ca721 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. diff -r 23ecffd5bcfe -r 0cdee26605f3 src/http/modules/ngx_http_auth_basic_module.c --- a/src/http/modules/ngx_http_auth_basic_module.c Thu Apr 20 13:58:16 2017 +0300 +++ b/src/http/modules/ngx_http_auth_basic_module.c Thu Apr 20 18:26:37 2017 +0300 @@ -361,6 +361,8 @@ 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; } diff -r 23ecffd5bcfe -r 0cdee26605f3 src/http/modules/ngx_http_dav_module.c --- a/src/http/modules/ngx_http_dav_module.c Thu Apr 20 13:58:16 2017 +0300 +++ b/src/http/modules/ngx_http_dav_module.c Thu Apr 20 18:26:37 2017 +0300 @@ -1080,6 +1080,7 @@ } else { location = ngx_pnalloc(r->pool, r->uri.len); if (location == NULL) { + ngx_http_clear_location(r); return NGX_ERROR; } diff -r 23ecffd5bcfe -r 0cdee26605f3 src/http/modules/ngx_http_headers_filter_module.c --- a/src/http/modules/ngx_http_headers_filter_module.c Thu Apr 20 13:58:16 2017 +0300 +++ b/src/http/modules/ngx_http_headers_filter_module.c Thu Apr 20 18:26:37 2017 +0300 @@ -271,11 +271,6 @@ 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 @@ 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 @@ } } - 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_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; diff -r 23ecffd5bcfe -r 0cdee26605f3 src/http/modules/ngx_http_range_filter_module.c --- a/src/http/modules/ngx_http_range_filter_module.c Thu Apr 20 13:58:16 2017 +0300 +++ b/src/http/modules/ngx_http_range_filter_module.c Thu Apr 20 18:26:37 2017 +0300 @@ -425,6 +425,8 @@ 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 @@ 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; } diff -r 23ecffd5bcfe -r 0cdee26605f3 src/http/modules/ngx_http_static_module.c --- a/src/http/modules/ngx_http_static_module.c Thu Apr 20 13:58:16 2017 +0300 +++ b/src/http/modules/ngx_http_static_module.c Thu Apr 20 18:26:37 2017 +0300 @@ -169,6 +169,7 @@ location = ngx_pnalloc(r->pool, len); if (location == NULL) { + ngx_http_clear_location(r); return NGX_HTTP_INTERNAL_SERVER_ERROR; } diff -r 23ecffd5bcfe -r 0cdee26605f3 src/http/modules/perl/nginx.xs --- a/src/http/modules/perl/nginx.xs Thu Apr 20 13:58:16 2017 +0300 +++ b/src/http/modules/perl/nginx.xs Thu Apr 20 18:26:37 2017 +0300 @@ -510,10 +510,12 @@ 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; } diff -r 23ecffd5bcfe -r 0cdee26605f3 src/http/ngx_http_core_module.c --- a/src/http/ngx_http_core_module.c Thu Apr 20 13:58:16 2017 +0300 +++ b/src/http/ngx_http_core_module.c Thu Apr 20 18:26:37 2017 +0300 @@ -1002,6 +1002,7 @@ 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; } diff -r 23ecffd5bcfe -r 0cdee26605f3 src/http/ngx_http_upstream.c --- a/src/http/ngx_http_upstream.c Thu Apr 20 13:58:16 2017 +0300 +++ b/src/http/ngx_http_upstream.c Thu Apr 20 18:26:37 2017 +0300 @@ -4897,17 +4897,18 @@ } } - 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;