Welcome! Log In Create A New Profile

Advanced

[nginx] HTTP: uniform checks in ngx_http_alloc_large_header_buffer().

Sergey Kandaurov
December 11, 2023 08:52AM
details: https://hg.nginx.org/nginx/rev/b05c622715fa
branches:
changeset: 9188:b05c622715fa
user: Vladimir Khomutov <vl@wbsrv.ru>
date: Wed Nov 29 11:13:05 2023 +0300
description:
HTTP: uniform 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 is flawed.

According to C11, 6.5.6 Additive operators, p.9:

: When two pointers are subtracted, both shall point to elements
: of the same array object, or one past the last element of the
: array object

Since "ptr" is not set, subtraction leads to undefined behaviour, because
"ptr" and "old" are not in the same buffer (i.e. array objects).

Prodded by GCC undefined behaviour sanitizer.

diffstat:

src/http/ngx_http_request.c | 34 ++++++++++++++++++++++++++--------
1 files changed, 26 insertions(+), 8 deletions(-)

diffs (54 lines):

diff -r dacad3a9c7b8 -r b05c622715fa src/http/ngx_http_request.c
--- a/src/http/ngx_http_request.c Tue Nov 28 12:57:14 2023 +0300
+++ b/src/http/ngx_http_request.c Wed Nov 29 11:13:05 2023 +0300
@@ -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) {
@@ -1749,9 +1758,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
Subject Author Views Posted

[nginx] HTTP: uniform checks in ngx_http_alloc_large_header_buffer().

Sergey Kandaurov 211 December 11, 2023 08:52AM



Sorry, you do not have permission to post/reply in this forum.

Online Users

Guests: 86
Record Number of Users: 8 on April 13, 2023
Record Number of Guests: 421 on December 02, 2018
Powered by nginx      Powered by FreeBSD      PHP Powered      Powered by MariaDB      ipv6 ready