summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Kandaurov <pluknet@nginx.com>2023-05-01 19:16:05 +0400
committerSergey Kandaurov <pluknet@nginx.com>2023-05-01 19:16:05 +0400
commit1a8ef991d92d22eb8aded7f49595dd31a639e8a4 (patch)
tree3bd3644b2fece440fde318a14ae3aa9501a3674b
parent25c546ac37ba622b93c1a7075bd7eb447bac17b2 (diff)
downloadnginx-1a8ef991d92d22eb8aded7f49595dd31a639e8a4.tar.gz
Variables: avoid possible buffer overrun with some "$sent_http_*".HEADmasterbranches/default
The existing logic to evaluate multi header "$sent_http_*" variables, such as $sent_http_cache_control, as previously introduced in 1.23.0, doesn't take into account that one or more elements can be cleared, yet still present in a linked list, pointed to by the next field. Such elements don't contribute to the resulting variable length, an attempt to append a separator for them ends up in out of bounds write. This is not possible with standard modules, though at least one third party module is known to override multi header values this way, so it makes sense to harden the logic. The fix restores a generic boundary check.
-rw-r--r--src/http/ngx_http_variables.c6
1 files changed, 4 insertions, 2 deletions
diff --git a/src/http/ngx_http_variables.c b/src/http/ngx_http_variables.c
index 16ffda3fe..4f0bd0e4b 100644
--- a/src/http/ngx_http_variables.c
+++ b/src/http/ngx_http_variables.c
@@ -828,7 +828,7 @@ ngx_http_variable_headers_internal(ngx_http_request_t *r,
ngx_http_variable_value_t *v, uintptr_t data, u_char sep)
{
size_t len;
- u_char *p;
+ u_char *p, *end;
ngx_table_elt_t *h, *th;
h = *(ngx_table_elt_t **) ((char *) r + data);
@@ -870,6 +870,8 @@ ngx_http_variable_headers_internal(ngx_http_request_t *r,
v->len = len;
v->data = p;
+ end = p + len;
+
for (th = h; th; th = th->next) {
if (th->hash == 0) {
@@ -878,7 +880,7 @@ ngx_http_variable_headers_internal(ngx_http_request_t *r,
p = ngx_copy(p, th->value.data, th->value.len);
- if (th->next == NULL) {
+ if (p == end) {
break;
}