Skip to content

Commit 397f366

Browse files
Emil Stolarskyagentzh
Emil Stolarsky
authored andcommitted
bugfix: ngx.req.set_header: skips setting multi-value headers for bad requests to avoid segfaults.
When setting a multi-value header during bad requests, the value isn't added into the header's array. Despite failing to be set, the size of the array is still incremented. Later, if Nginx attempts to iterate over the array, a segfault will occur. e21d9b5 established a pattern of silently ignoring the header being set. I've moved the check for a bad request into `ngx_http_lua_set_input_header` so that setting a header value is ignored for both types of headers. Signed-off-by: Yichun Zhang (agentzh) <[email protected]>
1 parent 37e5362 commit 397f366

File tree

2 files changed

+27
-6
lines changed

2 files changed

+27
-6
lines changed

src/ngx_http_lua_headers_in.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -263,11 +263,6 @@ ngx_http_set_header_helper(ngx_http_request_t *r, ngx_http_lua_header_val_t *hv,
263263

264264
new_header:
265265

266-
if (r->headers_in.headers.last == NULL) {
267-
/* must be 400 bad request */
268-
return NGX_OK;
269-
}
270-
271266
h = ngx_list_push(&r->headers_in.headers);
272267

273268
if (h == NULL) {
@@ -698,6 +693,11 @@ ngx_http_lua_set_input_header(ngx_http_request_t *r, ngx_str_t key,
698693
}
699694
#endif
700695

696+
if (r->headers_out.status == 400 || r->headers_in.headers.last == NULL) {
697+
/* must be a 400 Bad Request */
698+
return NGX_OK;
699+
}
700+
701701
return hv.handler(r, &hv, &value);
702702
}
703703

t/028-req-header.t

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use Test::Nginx::Socket::Lua;
88

99
repeat_each(2);
1010

11-
plan tests => repeat_each() * (2 * blocks() + 30);
11+
plan tests => repeat_each() * (2 * blocks() + 31);
1212

1313
#no_diff();
1414
#no_long_string();
@@ -1622,3 +1622,24 @@ ok
16221622
--- no_error_log
16231623
[error]
16241624
--- no_check_leak
1625+
1626+
1627+
1628+
=== TEST 54: for bad requests causing segfaults when setting & getting multi-value headers
1629+
--- config
1630+
error_page 400 = /err;
1631+
1632+
location = /err {
1633+
content_by_lua_block {
1634+
ngx.req.set_header("Cookie", "foo=bar")
1635+
local test = ngx.var.cookie_bar
1636+
1637+
ngx.say("ok")
1638+
}
1639+
}
1640+
--- raw_request
1641+
GeT / HTTP/1.1
1642+
--- response_body
1643+
ok
1644+
--- no_error_log
1645+
[error]

0 commit comments

Comments
 (0)