]> git.kaiwu.me - nginx.git/commitdiff
Script: buffer overrun protection in direct script usage.
authorMaxim Dounin <mdounin@mdounin.ru>
Fri, 19 Jun 2026 19:54:46 +0000 (22:54 +0300)
committerRoman Arutyunyan <arutyunyan.roman@gmail.com>
Wed, 15 Jul 2026 17:20:38 +0000 (21:20 +0400)
Following the previous change, this change adds script overrun
protection to direct script evaluation in the proxy, fastcgi, scgi,
uwsgi, grpc proxy, index, and try_files modules.

This change is a modified version of a patch by Maxim Dounin.  The
modifications include ngx_http_proxy_v2_module and hardened size checks.

Signed-off-by: Roman Arutyunyan <arut@nginx.com>
Origin: <https://freenginx.org/hg/nginx/rev/7e4d7feb4c77>

src/http/modules/ngx_http_fastcgi_module.c
src/http/modules/ngx_http_grpc_module.c
src/http/modules/ngx_http_index_module.c
src/http/modules/ngx_http_proxy_module.c
src/http/modules/ngx_http_proxy_v2_module.c
src/http/modules/ngx_http_scgi_module.c
src/http/modules/ngx_http_try_files_module.c
src/http/modules/ngx_http_uwsgi_module.c

index f7f0696a8f848b773eff0bb21e3865e5f54b0806..21c106778a085ebe6d7ff0296b77df7e889c61c7 100644 (file)
@@ -845,8 +845,8 @@ ngx_http_fastcgi_create_request(ngx_http_request_t *r)
 {
     off_t                         file_pos;
     u_char                        ch, sep, *pos, *lowcase_key;
-    size_t                        size, len, key_len, val_len, padding,
-                                  allocated;
+    size_t                        size, len, params_len,
+                                  key_len, val_len, padding, allocated;
     ngx_uint_t                    i, n, next, hash, skip_empty, header_params;
     ngx_buf_t                    *b;
     ngx_chain_t                  *cl, *body;
@@ -861,6 +861,7 @@ ngx_http_fastcgi_create_request(ngx_http_request_t *r)
     ngx_http_script_len_code_pt   lcode;
 
     len = 0;
+    params_len = 0;
     header_params = 0;
     ignored = NULL;
 
@@ -900,8 +901,10 @@ ngx_http_fastcgi_create_request(ngx_http_request_t *r)
                 continue;
             }
 
-            len += 1 + key_len + ((val_len > 127) ? 4 : 1) + val_len;
+            params_len += 1 + key_len + ((val_len > 127) ? 4 : 1) + val_len;
         }
+
+        len += params_len;
     }
 
     if (flcf->upstream.pass_request_headers) {
@@ -1057,6 +1060,7 @@ ngx_http_fastcgi_create_request(ngx_http_request_t *r)
 
         e.ip = params->values->elts;
         e.pos = b->last;
+        e.end = b->last + params_len;
         e.request = r;
         e.flushed = 1;
 
@@ -1089,6 +1093,12 @@ ngx_http_fastcgi_create_request(ngx_http_request_t *r)
                 continue;
             }
 
+            if (ngx_http_script_check_length(&e, 1 + ((val_len > 127) ? 4 : 1))
+                != NGX_OK)
+            {
+                return NGX_ERROR;
+            }
+
             *e.pos++ = (u_char) key_len;
 
             if (val_len > 127) {
@@ -1107,12 +1117,22 @@ ngx_http_fastcgi_create_request(ngx_http_request_t *r)
             }
             e.ip += sizeof(uintptr_t);
 
+            if (e.status) {
+                return NGX_ERROR;
+            }
+
             ngx_log_debug4(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
                            "fastcgi param: \"%*s: %*s\"",
                            key_len, e.pos - (key_len + val_len),
                            val_len, e.pos - val_len);
         }
 
+        if (e.pos != e.end) {
+            ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
+                          "fastcgi request length mismatch");
+            return NGX_ERROR;
+        }
+
         b->last = e.pos;
     }
 
index 1895ef31b763e574cd02e5835c1859fd4ef17c95..6818281096e2f15581e2b7d63c6431fefca807a7 100644 (file)
@@ -717,8 +717,10 @@ ngx_http_grpc_eval(ngx_http_request_t *r, ngx_http_grpc_ctx_t *ctx,
 static ngx_int_t
 ngx_http_grpc_create_request(ngx_http_request_t *r)
 {
-    u_char                       *p, *tmp, *key_tmp, *val_tmp, *headers_frame;
-    size_t                        len, tmp_len, key_len, val_len, uri_len;
+    u_char                       *p, *tmp, *key_tmp, *val_tmp, *headers_frame,
+                                 *headers_end;
+    size_t                        len, headers_len, tmp_len,
+                                  key_len, val_len, uri_len;
     uintptr_t                     escape;
     ngx_buf_t                    *b;
     ngx_uint_t                    i, next;
@@ -742,6 +744,8 @@ ngx_http_grpc_create_request(ngx_http_request_t *r)
     len = sizeof(ngx_http_grpc_connection_start) - 1
           + sizeof(ngx_http_grpc_frame_t);             /* headers frame */
 
+    headers_len = 0;
+
     /* :method header */
 
     if (r->method == NGX_HTTP_GET || r->method == NGX_HTTP_POST) {
@@ -838,8 +842,8 @@ ngx_http_grpc_create_request(ngx_http_request_t *r)
             return NGX_ERROR;
         }
 
-        len += 1 + NGX_HTTP_V2_INT_OCTETS + key_len
-                 + NGX_HTTP_V2_INT_OCTETS + val_len;
+        headers_len += 1 + NGX_HTTP_V2_INT_OCTETS + key_len
+                         + NGX_HTTP_V2_INT_OCTETS + val_len;
 
         if (tmp_len < key_len) {
             tmp_len = key_len;
@@ -850,6 +854,8 @@ ngx_http_grpc_create_request(ngx_http_request_t *r)
         }
     }
 
+    len += headers_len;
+
     if (glcf->upstream.pass_request_headers) {
         part = &r->headers_in.headers.part;
         header = part->elts;
@@ -1046,6 +1052,8 @@ ngx_http_grpc_create_request(ngx_http_request_t *r)
 
     le.ip = glcf->headers.lengths->elts;
 
+    headers_end = b->last + headers_len;
+
     while (*(uintptr_t *) le.ip) {
 
         lcode = *(ngx_http_script_len_code_pt *) le.ip;
@@ -1070,16 +1078,38 @@ ngx_http_grpc_create_request(ngx_http_request_t *r)
             continue;
         }
 
+        if (headers_end - b->last < 1) {
+            ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
+                          "no buffer space in grpc create request");
+            return NGX_ERROR;
+        }
+
         *b->last++ = 0;
 
         e.pos = key_tmp;
+        e.end = key_tmp + tmp_len;
 
         code = *(ngx_http_script_code_pt *) e.ip;
         code((ngx_http_script_engine_t *) &e);
 
+        if (e.status) {
+            return NGX_ERROR;
+        }
+
+        key_len = e.pos - key_tmp;
+
+        if (headers_end - b->last
+            < (ssize_t) (NGX_HTTP_V2_INT_OCTETS + key_len))
+        {
+            ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
+                          "no buffer space in grpc create request");
+            return NGX_ERROR;
+        }
+
         b->last = ngx_http_v2_write_name(b->last, key_tmp, key_len, tmp);
 
         e.pos = val_tmp;
+        e.end = val_tmp + tmp_len;
 
         while (*(uintptr_t *) e.ip) {
             code = *(ngx_http_script_code_pt *) e.ip;
@@ -1087,6 +1117,20 @@ ngx_http_grpc_create_request(ngx_http_request_t *r)
         }
         e.ip += sizeof(uintptr_t);
 
+        if (e.status) {
+            return NGX_ERROR;
+        }
+
+        val_len = e.pos - val_tmp;
+
+        if (headers_end - b->last
+            < (ssize_t) (NGX_HTTP_V2_INT_OCTETS + val_len))
+        {
+            ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
+                          "no buffer space in grpc create request");
+            return NGX_ERROR;
+        }
+
         b->last = ngx_http_v2_write_value(b->last, val_tmp, val_len, tmp);
 
 #if (NGX_DEBUG)
index 18e7049c516b9dc5291505a6e6b01a345808ae1d..149b44725247414a7e975f3481974cf1d1a44ae4 100644 (file)
@@ -126,6 +126,7 @@ ngx_http_index_handler(ngx_http_request_t *r)
     name = NULL;
     /* suppress MSVC warning */
     path.data = NULL;
+    e.status = 0;
 
     index = ilcf->indices->elts;
     for (i = 0; i < ilcf->indices->nelts; i++) {
@@ -180,18 +181,28 @@ ngx_http_index_handler(ngx_http_request_t *r)
         } else {
             e.ip = index[i].values->elts;
             e.pos = name;
+            e.end = name + allocated;
 
             while (*(uintptr_t *) e.ip) {
                 code = *(ngx_http_script_code_pt *) e.ip;
                 code((ngx_http_script_engine_t *) &e);
             }
 
+            if (e.status) {
+                return NGX_HTTP_INTERNAL_SERVER_ERROR;
+            }
+
+            if (ngx_http_script_check_length(&e, 1) != NGX_OK) {
+                return NGX_ERROR;
+            }
+
             if (*name == '/') {
-                uri.len = len - 1;
+                uri.len = e.pos - name;
                 uri.data = name;
                 return ngx_http_internal_redirect(r, &uri, &r->args);
             }
 
+            len = e.pos - name + 1;
             path.len = e.pos - path.data;
 
             *e.pos = '\0';
index 276cc07502ae714b5e90540d1a422b290f47fcef..f3263cd5f33edac0a142c7d4b09866cfc31ed1f4 100644 (file)
@@ -1173,7 +1173,7 @@ ngx_http_proxy_create_key(ngx_http_request_t *r)
 static ngx_int_t
 ngx_http_proxy_create_request(ngx_http_request_t *r)
 {
-    size_t                        len, uri_len, loc_len, body_len,
+    size_t                        len, uri_len, loc_len, body_len, headers_len,
                                   key_len, val_len;
     uintptr_t                     escape;
     ngx_buf_t                    *b;
@@ -1227,6 +1227,8 @@ ngx_http_proxy_create_request(ngx_http_request_t *r)
     escape = 0;
     loc_len = 0;
     unparsed_uri = 0;
+    body_len = 0;
+    headers_len = 0;
 
     if (plcf->proxy_lengths && ctx->vars.uri.len) {
         uri_len = ctx->vars.uri.len;
@@ -1265,7 +1267,6 @@ ngx_http_proxy_create_request(ngx_http_request_t *r)
         le.ip = plcf->body_lengths->elts;
         le.request = r;
         le.flushed = 1;
-        body_len = 0;
 
         while (*(uintptr_t *) le.ip) {
             lcode = *(ngx_http_script_len_code_pt *) le.ip;
@@ -1301,9 +1302,11 @@ ngx_http_proxy_create_request(ngx_http_request_t *r)
             continue;
         }
 
-        len += key_len + sizeof(": ") - 1 + val_len + sizeof(CRLF) - 1;
+        headers_len += key_len + sizeof(": ") - 1 + val_len + sizeof(CRLF) - 1;
     }
 
+    len += headers_len;
+
 
     if (plcf->upstream.pass_request_headers) {
         part = &r->headers_in.headers.part;
@@ -1395,6 +1398,7 @@ ngx_http_proxy_create_request(ngx_http_request_t *r)
 
     e.ip = headers->values->elts;
     e.pos = b->last;
+    e.end = b->last + headers_len;
     e.request = r;
     e.flushed = 1;
 
@@ -1427,6 +1431,14 @@ ngx_http_proxy_create_request(ngx_http_request_t *r)
         code = *(ngx_http_script_code_pt *) e.ip;
         code((ngx_http_script_engine_t *) &e);
 
+        if (e.status) {
+            return NGX_ERROR;
+        }
+
+        if (ngx_http_script_check_length(&e, 2) != NGX_OK) {
+            return NGX_ERROR;
+        }
+
         *e.pos++ = ':'; *e.pos++ = ' ';
 
         while (*(uintptr_t *) e.ip) {
@@ -1435,6 +1447,14 @@ ngx_http_proxy_create_request(ngx_http_request_t *r)
         }
         e.ip += sizeof(uintptr_t);
 
+        if (e.status) {
+            return NGX_ERROR;
+        }
+
+        if (ngx_http_script_check_length(&e, 2) != NGX_OK) {
+            return NGX_ERROR;
+        }
+
         *e.pos++ = CR; *e.pos++ = LF;
     }
 
@@ -1485,6 +1505,7 @@ ngx_http_proxy_create_request(ngx_http_request_t *r)
     if (plcf->body_values) {
         e.ip = plcf->body_values->elts;
         e.pos = b->last;
+        e.end = b->last + body_len;
         e.skip = 0;
 
         while (*(uintptr_t *) e.ip) {
@@ -1492,6 +1513,10 @@ ngx_http_proxy_create_request(ngx_http_request_t *r)
             code((ngx_http_script_engine_t *) &e);
         }
 
+        if (e.status) {
+            return NGX_ERROR;
+        }
+
         b->last = e.pos;
     }
 
index 010c02a8645b6f82da3ac741b4937d6ac9c3165e..ae6007298fc94f9a89f241cc1ce588e38fc1e4d3 100644 (file)
@@ -317,8 +317,10 @@ ngx_http_proxy_v2_handler(ngx_http_request_t *r)
 static ngx_int_t
 ngx_http_proxy_v2_create_request(ngx_http_request_t *r)
 {
-    u_char                       *p, *tmp, *key_tmp, *val_tmp, *headers_frame;
-    size_t                        len, tmp_len, key_len, val_len, uri_len,
+    u_char                       *p, *tmp, *key_tmp, *val_tmp, *headers_frame,
+                                 *headers_end;
+    size_t                        len, headers_len, tmp_len,
+                                  key_len, val_len, uri_len,
                                   loc_len, body_len;
     uintptr_t                     escape;
     ngx_buf_t                    *b;
@@ -370,6 +372,8 @@ ngx_http_proxy_v2_create_request(ngx_http_request_t *r)
     len = sizeof(ngx_http_proxy_v2_connection_start) - 1
           + sizeof(ngx_http_proxy_v2_frame_t);             /* headers frame */
 
+    headers_len = 0;
+
     /* :method header */
 
     if ((method.len == 3 && ngx_strncmp(method.data, "GET", 3) == 0)
@@ -513,8 +517,8 @@ ngx_http_proxy_v2_create_request(ngx_http_request_t *r)
             return NGX_ERROR;
         }
 
-        len += 1 + NGX_HTTP_V2_INT_OCTETS + key_len
-                 + NGX_HTTP_V2_INT_OCTETS + val_len;
+        headers_len += 1 + NGX_HTTP_V2_INT_OCTETS + key_len
+                         + NGX_HTTP_V2_INT_OCTETS + val_len;
 
         if (tmp_len < key_len) {
             tmp_len = key_len;
@@ -525,6 +529,8 @@ ngx_http_proxy_v2_create_request(ngx_http_request_t *r)
         }
     }
 
+    len += headers_len;
+
     if (plcf->upstream.pass_request_headers) {
         part = &r->headers_in.headers.part;
         header = part->elts;
@@ -727,6 +733,8 @@ ngx_http_proxy_v2_create_request(ngx_http_request_t *r)
 
     le.ip = headers->lengths->elts;
 
+    headers_end = b->last + headers_len;
+
     while (*(uintptr_t *) le.ip) {
 
         lcode = *(ngx_http_script_len_code_pt *) le.ip;
@@ -751,16 +759,38 @@ ngx_http_proxy_v2_create_request(ngx_http_request_t *r)
             continue;
         }
 
+        if (headers_end - b->last < 1) {
+            ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
+                          "no buffer space in HTTP/2 create request");
+            return NGX_ERROR;
+        }
+
         *b->last++ = 0;
 
         e.pos = key_tmp;
+        e.end = key_tmp + tmp_len;
 
         code = *(ngx_http_script_code_pt *) e.ip;
         code((ngx_http_script_engine_t *) &e);
 
+        if (e.status) {
+            return NGX_ERROR;
+        }
+
+        key_len = e.pos - key_tmp;
+
+        if (headers_end - b->last
+            < (ssize_t) (NGX_HTTP_V2_INT_OCTETS + key_len))
+        {
+            ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
+                          "no buffer space in HTTP/2 create request");
+            return NGX_ERROR;
+        }
+
         b->last = ngx_http_v2_write_name(b->last, key_tmp, key_len, tmp);
 
         e.pos = val_tmp;
+        e.end = val_tmp + tmp_len;
 
         while (*(uintptr_t *) e.ip) {
             code = *(ngx_http_script_code_pt *) e.ip;
@@ -768,6 +798,20 @@ ngx_http_proxy_v2_create_request(ngx_http_request_t *r)
         }
         e.ip += sizeof(uintptr_t);
 
+        if (e.status) {
+            return NGX_ERROR;
+        }
+
+        val_len = e.pos - val_tmp;
+
+        if (headers_end - b->last
+            < (ssize_t) (NGX_HTTP_V2_INT_OCTETS + val_len))
+        {
+            ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
+                          "no buffer space in HTTP/2 create request");
+            return NGX_ERROR;
+        }
+
         b->last = ngx_http_v2_write_value(b->last, val_tmp, val_len, tmp);
 
 #if (NGX_DEBUG)
@@ -935,6 +979,7 @@ ngx_http_proxy_v2_create_request(ngx_http_request_t *r)
 
         e.ip = plcf->body_values->elts;
         e.pos = b->last;
+        e.end = b->last + body_len;
         e.request = r;
         e.flushed = 1;
         e.skip = 0;
@@ -944,6 +989,10 @@ ngx_http_proxy_v2_create_request(ngx_http_request_t *r)
             code((ngx_http_script_engine_t *) &e);
         }
 
+        if (e.status) {
+            return NGX_ERROR;
+        }
+
         b->last = e.pos;
         b->last_buf = 1;
 
index b4a73a5a6bced5ef8cddcba44674179a4eaab708..7276b4a6f95cd02dbe9e5914e340ae2fb14f0a31 100644 (file)
@@ -643,7 +643,7 @@ ngx_http_scgi_create_request(ngx_http_request_t *r)
 {
     off_t                         content_length_n;
     u_char                        ch, sep, *key, *val, *lowcase_key;
-    size_t                        len, key_len, val_len, allocated;
+    size_t                        len, params_len, key_len, val_len, allocated;
     ngx_buf_t                    *b;
     ngx_str_t                     content_length;
     ngx_uint_t                    i, n, hash, skip_empty, header_params;
@@ -668,6 +668,7 @@ ngx_http_scgi_create_request(ngx_http_request_t *r)
 
     len = sizeof("CONTENT_LENGTH") + content_length.len + 1;
 
+    params_len = 0;
     header_params = 0;
     ignored = NULL;
 
@@ -705,8 +706,10 @@ ngx_http_scgi_create_request(ngx_http_request_t *r)
                 continue;
             }
 
-            len += key_len + val_len + 1;
+            params_len += key_len + val_len + 1;
         }
+
+        len += params_len;
     }
 
     if (scf->upstream.pass_request_headers) {
@@ -821,6 +824,7 @@ ngx_http_scgi_create_request(ngx_http_request_t *r)
 
         e.ip = params->values->elts;
         e.pos = b->last;
+        e.end = b->last + params_len;
         e.request = r;
         e.flushed = 1;
 
@@ -859,6 +863,10 @@ ngx_http_scgi_create_request(ngx_http_request_t *r)
             code = *(ngx_http_script_code_pt *) e.ip;
             code((ngx_http_script_engine_t *) &e);
 
+            if (e.status) {
+                return NGX_ERROR;
+            }
+
 #if (NGX_DEBUG)
             val = e.pos;
 #endif
@@ -866,6 +874,15 @@ ngx_http_scgi_create_request(ngx_http_request_t *r)
                 code = *(ngx_http_script_code_pt *) e.ip;
                 code((ngx_http_script_engine_t *) &e);
             }
+
+            if (e.status) {
+                return NGX_ERROR;
+            }
+
+            if (ngx_http_script_check_length(&e, 1) != NGX_OK) {
+                return NGX_ERROR;
+            }
+
             *e.pos++ = '\0';
             e.ip += sizeof(uintptr_t);
 
@@ -873,6 +890,12 @@ ngx_http_scgi_create_request(ngx_http_request_t *r)
                            "scgi param: \"%s: %s\"", key, val);
         }
 
+        if (e.pos != e.end) {
+            ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
+                          "scgi request length mismatch");
+            return NGX_ERROR;
+        }
+
         b->last = e.pos;
     }
 
index ce783a24da6e0f3f285604d82e2f77f12df134cb..bbdab859842e94895938f42c41aa6aa6f103824d 100644 (file)
@@ -78,7 +78,7 @@ ngx_module_t  ngx_http_try_files_module = {
 static ngx_int_t
 ngx_http_try_files_handler(ngx_http_request_t *r)
 {
-    size_t                          len, root, alias, reserve, allocated;
+    size_t                          len, root, alias, reserve, allocated, n;
     u_char                         *p, *name;
     ngx_str_t                       path, args;
     ngx_uint_t                      test_dir;
@@ -162,8 +162,15 @@ ngx_http_try_files_handler(ngx_http_request_t *r)
             path.len = (name + tf->name.len - 1) - path.data;
 
         } else {
+            n = allocated;
+
+            if (alias != NGX_MAX_SIZE_T_VALUE) {
+                n += (r->uri.len - alias);
+            }
+
             e.ip = tf->values->elts;
             e.pos = name;
+            e.end = name + n;
             e.flushed = 1;
 
             while (*(uintptr_t *) e.ip) {
@@ -171,6 +178,14 @@ ngx_http_try_files_handler(ngx_http_request_t *r)
                 code((ngx_http_script_engine_t *) &e);
             }
 
+            if (e.status) {
+                return NGX_HTTP_INTERNAL_SERVER_ERROR;
+            }
+
+            if (ngx_http_script_check_length(&e, 1) != NGX_OK) {
+                return NGX_ERROR;
+            }
+
             path.len = e.pos - path.data;
 
             *e.pos = '\0';
index ecd6dd0d7e9876aa982864209f3780a4019118f6..71a658c30d43a489df41a44bba745d54e9cd7f29 100644 (file)
@@ -866,7 +866,7 @@ static ngx_int_t
 ngx_http_uwsgi_create_request(ngx_http_request_t *r)
 {
     u_char                        ch, sep, *lowcase_key;
-    size_t                        key_len, val_len, len, allocated;
+    size_t                        key_len, val_len, len, params_len, allocated;
     ngx_uint_t                    i, n, hash, skip_empty, header_params;
     ngx_buf_t                    *b;
     ngx_chain_t                  *cl, *body;
@@ -879,6 +879,7 @@ ngx_http_uwsgi_create_request(ngx_http_request_t *r)
     ngx_http_script_len_code_pt   lcode;
 
     len = 0;
+    params_len = 0;
     header_params = 0;
     ignored = NULL;
 
@@ -916,8 +917,10 @@ ngx_http_uwsgi_create_request(ngx_http_request_t *r)
                 continue;
             }
 
-            len += 2 + key_len + 2 + val_len;
+            params_len += 2 + key_len + 2 + val_len;
         }
+
+        len += params_len;
     }
 
     if (uwcf->upstream.pass_request_headers) {
@@ -1049,6 +1052,7 @@ ngx_http_uwsgi_create_request(ngx_http_request_t *r)
 
         e.ip = params->values->elts;
         e.pos = b->last;
+        e.end = b->last + params_len;
         e.request = r;
         e.flushed = 1;
 
@@ -1081,12 +1085,24 @@ ngx_http_uwsgi_create_request(ngx_http_request_t *r)
                 continue;
             }
 
+            if (ngx_http_script_check_length(&e, 2) != NGX_OK) {
+                return NGX_ERROR;
+            }
+
             *e.pos++ = (u_char) (key_len & 0xff);
             *e.pos++ = (u_char) ((key_len >> 8) & 0xff);
 
             code = *(ngx_http_script_code_pt *) e.ip;
             code((ngx_http_script_engine_t *) &e);
 
+            if (e.status) {
+                return NGX_ERROR;
+            }
+
+            if (ngx_http_script_check_length(&e, 2) != NGX_OK) {
+                return NGX_ERROR;
+            }
+
             *e.pos++ = (u_char) (val_len & 0xff);
             *e.pos++ = (u_char) ((val_len >> 8) & 0xff);
 
@@ -1095,6 +1111,10 @@ ngx_http_uwsgi_create_request(ngx_http_request_t *r)
                 code((ngx_http_script_engine_t *) &e);
             }
 
+            if (e.status) {
+                return NGX_ERROR;
+            }
+
             e.ip += sizeof(uintptr_t);
 
             ngx_log_debug4(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
@@ -1103,6 +1123,12 @@ ngx_http_uwsgi_create_request(ngx_http_request_t *r)
                            val_len, e.pos - val_len);
         }
 
+        if (e.pos != e.end) {
+            ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
+                          "uwsgi request length mismatch");
+            return NGX_ERROR;
+        }
+
         b->last = e.pos;
     }