If URI is not fully parsed yet, some pointers are not set. As a result, the calculation of "new + (ptr - old)" expression may overflow. In such a case, just avoid calculating it, as value will be set correctly later by the parser in any case.
The issue was found by GCC undefined behaviour sanitizer. src/http/ngx_http_request.c | 34 ++++++++++++++++++++++++++-------- 1 files changed, 26 insertions(+), 8 deletions(-)
# HG changeset patch # User Vladimir Khomutov <v...@wbsrv.ru> # Date 1699604478 -10800 # Fri Nov 10 11:21:18 2023 +0300 # Node ID 505e927eb7a75f0fdce4caddb4ab9d9c71c9b9c8 # Parent dadd13fdcf5228c8e8380e120d4621002e3b0919 HTTP: uniform overflow checks in ngx_http_alloc_large_header_buffer. If URI is not fully parsed yet, some pointers are not set. As a result, the calculation of "new + (ptr - old)" expression may overflow. In such a case, just avoid calculating it, as value will be set correctly later by the parser in any case. The issue was found by GCC undefined behaviour sanitizer. diff --git a/src/http/ngx_http_request.c b/src/http/ngx_http_request.c --- a/src/http/ngx_http_request.c +++ b/src/http/ngx_http_request.c @@ -1718,14 +1718,23 @@ ngx_http_alloc_large_header_buffer(ngx_h r->request_end = new + (r->request_end - old); } - r->method_end = new + (r->method_end - old); - - r->uri_start = new + (r->uri_start - old); - r->uri_end = new + (r->uri_end - old); + if (r->method_end) { + r->method_end = new + (r->method_end - old); + } + + if (r->uri_start) { + r->uri_start = new + (r->uri_start - old); + } + + if (r->uri_end) { + r->uri_end = new + (r->uri_end - old); + } if (r->schema_start) { r->schema_start = new + (r->schema_start - old); - r->schema_end = new + (r->schema_end - old); + if (r->schema_end) { + r->schema_end = new + (r->schema_end - old); + } } if (r->host_start) { @@ -1754,9 +1763,18 @@ ngx_http_alloc_large_header_buffer(ngx_h } else { r->header_name_start = new; - r->header_name_end = new + (r->header_name_end - old); - r->header_start = new + (r->header_start - old); - r->header_end = new + (r->header_end - old); + + if (r->header_name_end) { + r->header_name_end = new + (r->header_name_end - old); + } + + if (r->header_start) { + r->header_start = new + (r->header_start - old); + } + + if (r->header_end) { + r->header_end = new + (r->header_end - old); + } } r->header_in = b;
_______________________________________________ nginx-devel mailing list nginx-devel@nginx.org https://mailman.nginx.org/mailman/listinfo/nginx-devel