]> git.kaiwu.me - nginx.git/commitdiff
Variables: avoid possible buffer overrun with some "$sent_http_*".
authorSergey Kandaurov <pluknet@nginx.com>
Mon, 1 May 2023 15:16:05 +0000 (19:16 +0400)
committerSergey Kandaurov <pluknet@nginx.com>
Mon, 1 May 2023 15:16:05 +0000 (19:16 +0400)
The existing logic to evaluate multi header "$sent_http_*" variables,
such as $sent_http_cache_control, as previously introduced in 1.23.0,
doesn't take into account that one or more elements can be cleared,
yet still present in a linked list, pointed to by the next field.
Such elements don't contribute to the resulting variable length, an
attempt to append a separator for them ends up in out of bounds write.

This is not possible with standard modules, though at least one third
party module is known to override multi header values this way, so it
makes sense to harden the logic.

The fix restores a generic boundary check.

src/http/ngx_http_variables.c

index 16ffda3fec9cbe6bbdfd62fde11affe0b2781c22..4f0bd0e4b0b8471502beb15941de91acee57d5a7 100644 (file)
@@ -828,7 +828,7 @@ ngx_http_variable_headers_internal(ngx_http_request_t *r,
     ngx_http_variable_value_t *v, uintptr_t data, u_char sep)
 {
     size_t            len;
-    u_char           *p;
+    u_char           *p, *end;
     ngx_table_elt_t  *h, *th;
 
     h = *(ngx_table_elt_t **) ((char *) r + data);
@@ -870,6 +870,8 @@ ngx_http_variable_headers_internal(ngx_http_request_t *r,
     v->len = len;
     v->data = p;
 
+    end = p + len;
+
     for (th = h; th; th = th->next) {
 
         if (th->hash == 0) {
@@ -878,7 +880,7 @@ ngx_http_variable_headers_internal(ngx_http_request_t *r,
 
         p = ngx_copy(p, th->value.data, th->value.len);
 
-        if (th->next == NULL) {
+        if (p == end) {
             break;
         }