]> git.kaiwu.me - nginx.git/commitdiff
Cleaned up r->headers_out.headers allocation error handling.
authorSergey Kandaurov <pluknet@nginx.com>
Thu, 20 Apr 2017 15:26:37 +0000 (18:26 +0300)
committerSergey Kandaurov <pluknet@nginx.com>
Thu, 20 Apr 2017 15:26:37 +0000 (18:26 +0300)
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.

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

index 1e7a0c2df8d9d07ebb1d8504cb17d34a006acf87..4aa684f8af9f1b8fccc39b24bc75cbf0be5ba588 100644 (file)
@@ -361,6 +361,8 @@ ngx_http_auth_basic_set_realm(ngx_http_request_t *r, ngx_str_t *realm)
 
     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;
     }
 
index 895a52dca6615e13b7042dbe48d4de965a37b326..566b08ba19bd3121c13112f67d9ec64e98c73116 100644 (file)
@@ -1080,6 +1080,7 @@ ngx_http_dav_location(ngx_http_request_t *r, u_char *path)
     } else {
         location = ngx_pnalloc(r->pool, r->uri.len);
         if (location == NULL) {
+            ngx_http_clear_location(r);
             return NGX_ERROR;
         }
 
index b5aac33a712cb0d22d5cf14daa4f07f9b005c61c..94dc51e7763b8efea86f7bbf3a219a43dc4bcceb 100644 (file)
@@ -271,11 +271,6 @@ ngx_http_set_expires(ngx_http_request_t *r, ngx_http_headers_conf_t *conf)
             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 *r, ngx_http_headers_conf_t *conf)
 
         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_request_t *r, ngx_http_header_val_t *hv,
         }
     }
 
-    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_request_t *r, ngx_http_header_val_t *hv,
     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;
index 951a00de1ea90e0d5282c5a7909f09e641813a38..8ffca82e64f8378f743bf425f4a74bab76b8b166 100644 (file)
@@ -425,6 +425,8 @@ ngx_http_range_singlepart_header(ngx_http_request_t *r,
     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_request_t *r)
     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;
     }
 
index b0513be1cad2f67023b00c50e58a0f013a35edf9..0e16c05a56288226e5506684a77146538bab7d94 100644 (file)
@@ -169,6 +169,7 @@ ngx_http_static_handler(ngx_http_request_t *r)
 
             location = ngx_pnalloc(r->pool, len);
             if (location == NULL) {
+                ngx_http_clear_location(r);
                 return NGX_HTTP_INTERNAL_SERVER_ERROR;
             }
 
index cca64da37dc378fe7baa4fd165a3425fb8216626..ad1263287221c08d0c56037cf56375bdb2e3d381 100644 (file)
@@ -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;
     }
 
index f357ee4b688a6080fc15e862b96d7c7efdae7579..af67b7f8537c9e8bace4ecb058a1af636af719a1 100644 (file)
@@ -1002,6 +1002,7 @@ ngx_http_core_find_config_phase(ngx_http_request_t *r,
             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;
             }
index 36952860ccd06abf8dc2a1ecd7a136134f9ed638..fcfa2ad943fe383becc42937b5174d3d228fde33 100644 (file)
@@ -4897,17 +4897,18 @@ ngx_http_upstream_copy_multi_header_lines(ngx_http_request_t *r,
         }
     }
 
-    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;