]> git.kaiwu.me - nginx.git/commitdiff
Script: reserved memory overrun protection in ngx_http_script_run()
authorRoman Arutyunyan <arut@nginx.com>
Wed, 29 Jul 2026 12:57:59 +0000 (16:57 +0400)
committerSergey Kandaurov <pluknet@nginx.com>
Thu, 1 Oct 2026 17:19:27 +0000 (21:19 +0400)
In b76754049 buffer overrun protection in script was introduced.
However in ngx_http_script_run() data could still spill over to the
reserved area.  This had no visible effects except the return value
which could extend beyond the maximum formatted string size.  This
value is however currently unused in the nginx code.

Later in a8289aa69 string length recalculation was implemented to
protect against buffer underwrite.  Considering a possible spillover to
the reserved area, the final string size could become larger than the
allocated buffer size.  This could later result in writing beyond
the buffer boundaries.  Maximum buffer overflow is the size of the
reserved area.

This could affect calculating document root from variables in HTTP
or using access logging in HTTP or Stream.  In the case of access
logging a possible impact is limited by an off-by-one write of a null
byte.

Reported by Matt Suiche of Tolmo Inc.

src/http/ngx_http_script.c
src/stream/ngx_stream_script.c

index 6d41cc720b0c855b38f88f815d164fcfd5d5b1bb..2f14b350097543688f8bbe1329a667c017573436 100644 (file)
@@ -645,7 +645,7 @@ ngx_http_script_run(ngx_http_request_t *r, ngx_str_t *value,
     e.request = r;
     e.flushed = 1;
 
-    n = len;
+    n = 0;
 
     while (*(uintptr_t *) e.ip) {
         lcode = *(ngx_http_script_len_code_pt *) e.ip;
@@ -653,8 +653,8 @@ ngx_http_script_run(ngx_http_request_t *r, ngx_str_t *value,
     }
 
 
-    value->len = n;
-    value->data = ngx_pnalloc(r->pool, n);
+    value->len = n + len;
+    value->data = ngx_pnalloc(r->pool, n + len);
     if (value->data == NULL) {
         return NULL;
     }
index 54e5dd55918c9c63d3529e8dfba7d00f7511a030..4ae10d5ce1c89f306e9ec729739a20f6002cfb24 100644 (file)
@@ -521,7 +521,7 @@ ngx_stream_script_run(ngx_stream_session_t *s, ngx_str_t *value,
     e.session = s;
     e.flushed = 1;
 
-    n = len;
+    n = 0;
 
     while (*(uintptr_t *) e.ip) {
         lcode = *(ngx_stream_script_len_code_pt *) e.ip;
@@ -529,8 +529,8 @@ ngx_stream_script_run(ngx_stream_session_t *s, ngx_str_t *value,
     }
 
 
-    value->len = n;
-    value->data = ngx_pnalloc(s->connection->pool, n);
+    value->len = n + len;
+    value->data = ngx_pnalloc(s->connection->pool, n + len);
     if (value->data == NULL) {
         return NULL;
     }