Skip to content

Commit 36d6ef4

Browse files
rootagentzh
authored andcommitted
bugfix: tcpsock:connect(): when the nginx resolver's send() immediately fails without yielding, we didn't clean up the coroutine ctx state properly.
This might lead to segmentation faults. thanks xiaocang for the discovery. Signed-off-by: Yichun Zhang (agentzh) <agentzh@gmail.com>
1 parent 77a2851 commit 36d6ef4

File tree

3 files changed

+42
-1
lines changed

3 files changed

+42
-1
lines changed

.travis.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ before_script:
9090
- mysql -uroot -e 'create database ngx_test; grant all on ngx_test.* to "ngx_test"@"%" identified by "ngx_test"; flush privileges;'
9191

9292
script:
93+
- sudo iptables -I OUTPUT 1 -p udp --dport 10086 -j REJECT
9394
- cd luajit2/
9495
- make -j$JOBS CCDEBUG=-g Q= PREFIX=$LUAJIT_PREFIX CC=$CC XCFLAGS='-DLUA_USE_APICHECK -DLUA_USE_ASSERT -msse4.2' > build.log 2>&1 || (cat build.log && exit 1)
9596
- sudo make install PREFIX=$LUAJIT_PREFIX > build.log 2>&1 || (cat build.log && exit 1)

src/ngx_http_lua_socket_tcp.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -743,6 +743,9 @@ ngx_http_lua_socket_tcp_connect(lua_State *L)
743743

744744
u->ft_type |= NGX_HTTP_LUA_SOCKET_FT_RESOLVER;
745745

746+
coctx->cleanup = NULL;
747+
coctx->data = NULL;
748+
746749
u->resolved->ctx = NULL;
747750
lua_pushnil(L);
748751
lua_pushfstring(L, "%s could not be resolved", host.data);

t/058-tcp-socket.t

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use Test::Nginx::Socket::Lua;
44

55
repeat_each(2);
66

7-
plan tests => repeat_each() * 190;
7+
plan tests => repeat_each() * 193;
88

99
our $HtmlDir = html_dir;
1010

@@ -3690,3 +3690,40 @@ received: OK
36903690
close: 1 nil
36913691
--- no_error_log
36923692
[error]
3693+
3694+
3695+
3696+
=== TEST 61: resolver send query failing immediately in connect()
3697+
this case did not clear coctx->cleanup properly and would lead to memory invalid accesses.
3698+
3699+
this test case requires the following iptables rule to work properly:
3700+
3701+
sudo iptables -I OUTPUT 1 -p udp --dport 10086 -j REJECT
3702+
3703+
--- config
3704+
location /t {
3705+
resolver 127.0.0.1:10086 ipv6=off;
3706+
resolver_timeout 10ms;
3707+
3708+
content_by_lua_block {
3709+
local sock = ngx.socket.tcp()
3710+
3711+
for i = 1, 3 do -- retry
3712+
local ok, err = sock:connect("www.google.com", 80)
3713+
if not ok then
3714+
ngx.say("failed to connect: ", err)
3715+
end
3716+
end
3717+
3718+
ngx.say("hello!")
3719+
}
3720+
}
3721+
--- request
3722+
GET /t
3723+
--- response_body
3724+
failed to connect: www.google.com could not be resolved
3725+
failed to connect: www.google.com could not be resolved
3726+
failed to connect: www.google.com could not be resolved
3727+
hello!
3728+
--- error_log eval
3729+
qr{\[alert\] .*? send\(\) failed \(\d+: Operation not permitted\) while resolving}

0 commit comments

Comments
 (0)