]> 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 15:51:22 +0000 (19:51 +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 cb34dcc8d8372c4d48e3ec9f90fe96ee1fd7a47e..96e0b3b5de9774da2a3d0ccf2734e3453b722047 100644 (file)
@@ -859,8 +859,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;
@@ -875,6 +875,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;
 
@@ -914,8 +915,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) {
@@ -1071,6 +1074,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;
 
@@ -1103,6 +1107,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) {
@@ -1121,12 +1131,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 533806ced73da4829bc2544ea18978b158f95c81..c19833fbc4ea0afa0c8f5695b6b9098535ce4fb9 100644 (file)
@@ -733,8 +733,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;
@@ -758,6 +760,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) {
@@ -854,8 +858,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;
@@ -866,6 +870,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;
@@ -1062,6 +1068,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;
@@ -1086,16 +1094,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;
@@ -1103,6 +1133,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 8a9bffe1028fd5b5a80bd1bb2388b1e83a77c0d5..3ae8c97664584a73f2efb5f0550e41db97e37a19 100644 (file)
@@ -1189,7 +1189,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;
@@ -1243,6 +1243,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;
@@ -1281,7 +1283,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;
@@ -1317,9 +1318,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;
@@ -1411,6 +1414,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;
 
@@ -1443,6 +1447,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) {
@@ -1451,6 +1463,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;
     }
 
@@ -1501,6 +1521,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) {
@@ -1508,6 +1529,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 cecc56ba841aba15664f4031cb28d9f7bf0d27f1..372ab05e9e480e63d312387b62eafbad636c63b6 100644 (file)
@@ -319,8 +319,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;
@@ -372,6 +374,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)
@@ -515,8 +519,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;
@@ -527,6 +531,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;
@@ -729,6 +735,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;
@@ -753,16 +761,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;
@@ -770,6 +800,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)
@@ -937,6 +981,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;
@@ -946,6 +991,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 05cbdded0df9ef9815aaed8064808c9f36ae09b7..fd0907c13d95e81535e239226d80b8d07c6d6d87 100644 (file)
@@ -657,7 +657,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;
@@ -682,6 +682,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;
 
@@ -719,8 +720,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) {
@@ -835,6 +838,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;
 
@@ -873,6 +877,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
@@ -880,6 +888,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);
 
@@ -887,6 +904,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 f5841375f59b2e5f5245889de1a92e8afe06ea94..8d243bc907d15638d35ea239ce53541146814d35 100644 (file)
@@ -880,7 +880,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;
@@ -893,6 +893,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;
 
@@ -930,8 +931,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) {
@@ -1063,6 +1066,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;
 
@@ -1095,12 +1099,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);
 
@@ -1109,6 +1125,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,
@@ -1117,6 +1137,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;
     }