Skip to content

Commit c97473b

Browse files
committed
bugfix: segmentation faults might happen when pipelined http requests are used in the downsteram connection. thanks Gao Yan for the report.
1 parent 36d6ef4 commit c97473b

14 files changed

+117
-30
lines changed

src/ngx_http_lua_accessby.c

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,7 @@ ngx_http_lua_access_by_chunk(lua_State *L, ngx_http_request_t *r)
238238
{
239239
int co_ref;
240240
ngx_int_t rc;
241+
ngx_uint_t nreqs;
241242
lua_State *co;
242243
ngx_event_t *rev;
243244
ngx_connection_t *c;
@@ -329,6 +330,9 @@ ngx_http_lua_access_by_chunk(lua_State *L, ngx_http_request_t *r)
329330
r->read_event_handler = ngx_http_block_reading;
330331
}
331332

333+
c = r->connection;
334+
nreqs = c->requests;
335+
332336
rc = ngx_http_lua_run_thread(L, r, ctx, 0);
333337

334338
dd("returned %d", (int) rc);
@@ -337,10 +341,8 @@ ngx_http_lua_access_by_chunk(lua_State *L, ngx_http_request_t *r)
337341
return rc;
338342
}
339343

340-
c = r->connection;
341-
342344
if (rc == NGX_AGAIN) {
343-
rc = ngx_http_lua_run_posted_threads(c, L, r, ctx);
345+
rc = ngx_http_lua_run_posted_threads(c, L, r, ctx, nreqs);
344346

345347
if (rc == NGX_ERROR || rc == NGX_DONE || rc > NGX_OK) {
346348
return rc;
@@ -353,7 +355,7 @@ ngx_http_lua_access_by_chunk(lua_State *L, ngx_http_request_t *r)
353355
} else if (rc == NGX_DONE) {
354356
ngx_http_lua_finalize_request(r, NGX_DONE);
355357

356-
rc = ngx_http_lua_run_posted_threads(c, L, r, ctx);
358+
rc = ngx_http_lua_run_posted_threads(c, L, r, ctx, nreqs);
357359

358360
if (rc == NGX_ERROR || rc == NGX_DONE || rc > NGX_OK) {
359361
return rc;

src/ngx_http_lua_output.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -724,6 +724,7 @@ ngx_http_lua_flush_resume_helper(ngx_http_request_t *r, ngx_http_lua_ctx_t *ctx)
724724
int n;
725725
lua_State *vm;
726726
ngx_int_t rc;
727+
ngx_uint_t nreqs;
727728
ngx_connection_t *c;
728729

729730
c = r->connection;
@@ -748,18 +749,20 @@ ngx_http_lua_flush_resume_helper(ngx_http_request_t *r, ngx_http_lua_ctx_t *ctx)
748749
}
749750

750751
vm = ngx_http_lua_get_lua_vm(r, ctx);
752+
nreqs = c->requests;
753+
751754
rc = ngx_http_lua_run_thread(vm, r, ctx, n);
752755

753756
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
754757
"lua run thread returned %d", rc);
755758

756759
if (rc == NGX_AGAIN) {
757-
return ngx_http_lua_run_posted_threads(c, vm, r, ctx);
760+
return ngx_http_lua_run_posted_threads(c, vm, r, ctx, nreqs);
758761
}
759762

760763
if (rc == NGX_DONE) {
761764
ngx_http_lua_finalize_request(r, NGX_DONE);
762-
return ngx_http_lua_run_posted_threads(c, vm, r, ctx);
765+
return ngx_http_lua_run_posted_threads(c, vm, r, ctx, nreqs);
763766
}
764767

765768
/* rc == NGX_ERROR || rc >= NGX_OK */

src/ngx_http_lua_req_body.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1125,6 +1125,7 @@ ngx_http_lua_read_body_resume(ngx_http_request_t *r)
11251125
{
11261126
lua_State *vm;
11271127
ngx_int_t rc;
1128+
ngx_uint_t nreqs;
11281129
ngx_connection_t *c;
11291130
ngx_http_lua_ctx_t *ctx;
11301131

@@ -1134,19 +1135,20 @@ ngx_http_lua_read_body_resume(ngx_http_request_t *r)
11341135

11351136
c = r->connection;
11361137
vm = ngx_http_lua_get_lua_vm(r, ctx);
1138+
nreqs = c->requests;
11371139

11381140
rc = ngx_http_lua_run_thread(vm, r, ctx, 0);
11391141

11401142
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
11411143
"lua run thread returned %d", rc);
11421144

11431145
if (rc == NGX_AGAIN) {
1144-
return ngx_http_lua_run_posted_threads(c, vm, r, ctx);
1146+
return ngx_http_lua_run_posted_threads(c, vm, r, ctx, nreqs);
11451147
}
11461148

11471149
if (rc == NGX_DONE) {
11481150
ngx_http_lua_finalize_request(r, NGX_DONE);
1149-
return ngx_http_lua_run_posted_threads(c, vm, r, ctx);
1151+
return ngx_http_lua_run_posted_threads(c, vm, r, ctx, nreqs);
11501152
}
11511153

11521154
if (ctx->entered_content_phase) {

src/ngx_http_lua_rewriteby.c

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,7 @@ ngx_http_lua_rewrite_by_chunk(lua_State *L, ngx_http_request_t *r)
235235
int co_ref;
236236
lua_State *co;
237237
ngx_int_t rc;
238+
ngx_uint_t nreqs;
238239
ngx_event_t *rev;
239240
ngx_connection_t *c;
240241
ngx_http_lua_ctx_t *ctx;
@@ -324,20 +325,21 @@ ngx_http_lua_rewrite_by_chunk(lua_State *L, ngx_http_request_t *r)
324325
r->read_event_handler = ngx_http_block_reading;
325326
}
326327

328+
c = r->connection;
329+
nreqs = c->requests;
330+
327331
rc = ngx_http_lua_run_thread(L, r, ctx, 0);
328332

329333
if (rc == NGX_ERROR || rc > NGX_OK) {
330334
return rc;
331335
}
332336

333-
c = r->connection;
334-
335337
if (rc == NGX_AGAIN) {
336-
rc = ngx_http_lua_run_posted_threads(c, L, r, ctx);
338+
rc = ngx_http_lua_run_posted_threads(c, L, r, ctx, nreqs);
337339

338340
} else if (rc == NGX_DONE) {
339341
ngx_http_lua_finalize_request(r, NGX_DONE);
340-
rc = ngx_http_lua_run_posted_threads(c, L, r, ctx);
342+
rc = ngx_http_lua_run_posted_threads(c, L, r, ctx, nreqs);
341343
}
342344

343345
if (rc == NGX_OK || rc == NGX_DECLINED) {

src/ngx_http_lua_semaphore.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,7 @@ ngx_http_lua_sema_resume(ngx_http_request_t *r)
258258
lua_State *vm;
259259
ngx_connection_t *c;
260260
ngx_int_t rc;
261+
ngx_uint_t nreqs;
261262
ngx_http_lua_ctx_t *ctx;
262263

263264
ctx = ngx_http_get_module_ctx(r, ngx_http_lua_module);
@@ -269,6 +270,7 @@ ngx_http_lua_sema_resume(ngx_http_request_t *r)
269270

270271
c = r->connection;
271272
vm = ngx_http_lua_get_lua_vm(r, ctx);
273+
nreqs = c->requests;
272274

273275
if (ctx->cur_co_ctx->sem_resume_status == SEMAPHORE_WAIT_SUCC) {
274276
lua_pushboolean(ctx->cur_co_ctx->co, 1);
@@ -285,12 +287,12 @@ ngx_http_lua_sema_resume(ngx_http_request_t *r)
285287
"lua run thread returned %d", rc);
286288

287289
if (rc == NGX_AGAIN) {
288-
return ngx_http_lua_run_posted_threads(c, vm, r, ctx);
290+
return ngx_http_lua_run_posted_threads(c, vm, r, ctx, nreqs);
289291
}
290292

291293
if (rc == NGX_DONE) {
292294
ngx_http_lua_finalize_request(r, NGX_DONE);
293-
return ngx_http_lua_run_posted_threads(c, vm, r, ctx);
295+
return ngx_http_lua_run_posted_threads(c, vm, r, ctx, nreqs);
294296
}
295297

296298
/* rc == NGX_ERROR || rc >= NGX_OK */

src/ngx_http_lua_sleep.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,7 @@ ngx_http_lua_sleep_resume(ngx_http_request_t *r)
180180
lua_State *vm;
181181
ngx_connection_t *c;
182182
ngx_int_t rc;
183+
ngx_uint_t nreqs;
183184
ngx_http_lua_ctx_t *ctx;
184185

185186
ctx = ngx_http_get_module_ctx(r, ngx_http_lua_module);
@@ -191,19 +192,20 @@ ngx_http_lua_sleep_resume(ngx_http_request_t *r)
191192

192193
c = r->connection;
193194
vm = ngx_http_lua_get_lua_vm(r, ctx);
195+
nreqs = c->requests;
194196

195197
rc = ngx_http_lua_run_thread(vm, r, ctx, 0);
196198

197199
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
198200
"lua run thread returned %d", rc);
199201

200202
if (rc == NGX_AGAIN) {
201-
return ngx_http_lua_run_posted_threads(c, vm, r, ctx);
203+
return ngx_http_lua_run_posted_threads(c, vm, r, ctx, nreqs);
202204
}
203205

204206
if (rc == NGX_DONE) {
205207
ngx_http_lua_finalize_request(r, NGX_DONE);
206-
return ngx_http_lua_run_posted_threads(c, vm, r, ctx);
208+
return ngx_http_lua_run_posted_threads(c, vm, r, ctx, nreqs);
207209
}
208210

209211
if (ctx->entered_content_phase) {

src/ngx_http_lua_socket_tcp.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5256,6 +5256,7 @@ ngx_http_lua_socket_tcp_resume_helper(ngx_http_request_t *r, int socket_op)
52565256
int nret;
52575257
lua_State *vm;
52585258
ngx_int_t rc;
5259+
ngx_uint_t nreqs;
52595260
ngx_connection_t *c;
52605261
ngx_http_lua_ctx_t *ctx;
52615262
ngx_http_lua_co_ctx_t *coctx;
@@ -5306,19 +5307,20 @@ ngx_http_lua_socket_tcp_resume_helper(ngx_http_request_t *r, int socket_op)
53065307

53075308
c = r->connection;
53085309
vm = ngx_http_lua_get_lua_vm(r, ctx);
5310+
nreqs = c->requests;
53095311

53105312
rc = ngx_http_lua_run_thread(vm, r, ctx, nret);
53115313

53125314
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
53135315
"lua run thread returned %d", rc);
53145316

53155317
if (rc == NGX_AGAIN) {
5316-
return ngx_http_lua_run_posted_threads(c, vm, r, ctx);
5318+
return ngx_http_lua_run_posted_threads(c, vm, r, ctx, nreqs);
53175319
}
53185320

53195321
if (rc == NGX_DONE) {
53205322
ngx_http_lua_finalize_request(r, NGX_DONE);
5321-
return ngx_http_lua_run_posted_threads(c, vm, r, ctx);
5323+
return ngx_http_lua_run_posted_threads(c, vm, r, ctx, nreqs);
53225324
}
53235325

53245326
if (ctx->entered_content_phase) {

src/ngx_http_lua_socket_udp.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1514,6 +1514,7 @@ ngx_http_lua_socket_udp_resume(ngx_http_request_t *r)
15141514
int nret;
15151515
lua_State *vm;
15161516
ngx_int_t rc;
1517+
ngx_uint_t nreqs;
15171518
ngx_connection_t *c;
15181519
ngx_http_lua_ctx_t *ctx;
15191520
ngx_http_lua_co_ctx_t *coctx;
@@ -1549,19 +1550,20 @@ ngx_http_lua_socket_udp_resume(ngx_http_request_t *r)
15491550

15501551
c = r->connection;
15511552
vm = ngx_http_lua_get_lua_vm(r, ctx);
1553+
nreqs = c->requests;
15521554

15531555
rc = ngx_http_lua_run_thread(vm, r, ctx, nret);
15541556

15551557
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
15561558
"lua run thread returned %d", rc);
15571559

15581560
if (rc == NGX_AGAIN) {
1559-
return ngx_http_lua_run_posted_threads(c, vm, r, ctx);
1561+
return ngx_http_lua_run_posted_threads(c, vm, r, ctx, nreqs);
15601562
}
15611563

15621564
if (rc == NGX_DONE) {
15631565
ngx_http_lua_finalize_request(r, NGX_DONE);
1564-
return ngx_http_lua_run_posted_threads(c, vm, r, ctx);
1566+
return ngx_http_lua_run_posted_threads(c, vm, r, ctx, nreqs);
15651567
}
15661568

15671569
if (ctx->entered_content_phase) {

src/ngx_http_lua_subrequest.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1587,6 +1587,7 @@ ngx_http_lua_subrequest_resume(ngx_http_request_t *r)
15871587
{
15881588
lua_State *vm;
15891589
ngx_int_t rc;
1590+
ngx_uint_t nreqs;
15901591
ngx_connection_t *c;
15911592
ngx_http_lua_ctx_t *ctx;
15921593
ngx_http_lua_co_ctx_t *coctx;
@@ -1620,19 +1621,20 @@ ngx_http_lua_subrequest_resume(ngx_http_request_t *r)
16201621

16211622
c = r->connection;
16221623
vm = ngx_http_lua_get_lua_vm(r, ctx);
1624+
nreqs = c->requests;
16231625

16241626
rc = ngx_http_lua_run_thread(vm, r, ctx, coctx->nsubreqs);
16251627

16261628
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
16271629
"lua run thread returned %d", rc);
16281630

16291631
if (rc == NGX_AGAIN) {
1630-
return ngx_http_lua_run_posted_threads(c, vm, r, ctx);
1632+
return ngx_http_lua_run_posted_threads(c, vm, r, ctx, nreqs);
16311633
}
16321634

16331635
if (rc == NGX_DONE) {
16341636
ngx_http_lua_finalize_request(r, NGX_DONE);
1635-
return ngx_http_lua_run_posted_threads(c, vm, r, ctx);
1637+
return ngx_http_lua_run_posted_threads(c, vm, r, ctx, nreqs);
16361638
}
16371639

16381640
/* rc == NGX_ERROR || rc >= NGX_OK */

src/ngx_http_lua_util.c

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3055,13 +3055,13 @@ ngx_http_lua_create_co_ctx(ngx_http_request_t *r, ngx_http_lua_ctx_t *ctx)
30553055
/* this is for callers other than the content handler */
30563056
ngx_int_t
30573057
ngx_http_lua_run_posted_threads(ngx_connection_t *c, lua_State *L,
3058-
ngx_http_request_t *r, ngx_http_lua_ctx_t *ctx)
3058+
ngx_http_request_t *r, ngx_http_lua_ctx_t *ctx, ngx_uint_t nreqs)
30593059
{
30603060
ngx_int_t rc;
30613061
ngx_http_lua_posted_thread_t *pt;
30623062

30633063
for ( ;; ) {
3064-
if (c->destroyed) {
3064+
if (c->destroyed || c->requests != nreqs) {
30653065
return NGX_DONE;
30663066
}
30673067

@@ -3461,6 +3461,7 @@ ngx_http_lua_on_abort_resume(ngx_http_request_t *r)
34613461
{
34623462
lua_State *vm;
34633463
ngx_int_t rc;
3464+
ngx_uint_t nreqs;
34643465
ngx_connection_t *c;
34653466
ngx_http_lua_ctx_t *ctx;
34663467

@@ -3480,19 +3481,20 @@ ngx_http_lua_on_abort_resume(ngx_http_request_t *r)
34803481

34813482
c = r->connection;
34823483
vm = ngx_http_lua_get_lua_vm(r, ctx);
3484+
nreqs = c->requests;
34833485

34843486
rc = ngx_http_lua_run_thread(vm, r, ctx, 0);
34853487

34863488
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
34873489
"lua run thread returned %d", rc);
34883490

34893491
if (rc == NGX_AGAIN) {
3490-
return ngx_http_lua_run_posted_threads(c, vm, r, ctx);
3492+
return ngx_http_lua_run_posted_threads(c, vm, r, ctx, nreqs);
34913493
}
34923494

34933495
if (rc == NGX_DONE) {
34943496
ngx_http_lua_finalize_request(r, NGX_DONE);
3495-
return ngx_http_lua_run_posted_threads(c, vm, r, ctx);
3497+
return ngx_http_lua_run_posted_threads(c, vm, r, ctx, nreqs);
34963498
}
34973499

34983500
if (ctx->entered_content_phase) {

src/ngx_http_lua_util.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,7 @@ ngx_http_lua_co_ctx_t *ngx_http_lua_create_co_ctx(ngx_http_request_t *r,
205205
ngx_http_lua_ctx_t *ctx);
206206

207207
ngx_int_t ngx_http_lua_run_posted_threads(ngx_connection_t *c, lua_State *L,
208-
ngx_http_request_t *r, ngx_http_lua_ctx_t *ctx);
208+
ngx_http_request_t *r, ngx_http_lua_ctx_t *ctx, ngx_uint_t nreqs);
209209

210210
ngx_int_t ngx_http_lua_post_thread(ngx_http_request_t *r,
211211
ngx_http_lua_ctx_t *ctx, ngx_http_lua_co_ctx_t *coctx);

t/017-exec.t

Lines changed: 23 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() * (blocks() * 2 + 4);
7+
plan tests => repeat_each() * (blocks() * 2 + 8);
88

99
$ENV{TEST_NGINX_MEMCACHED_PORT} ||= 11211;
1010

@@ -572,3 +572,25 @@ hello, bah
572572
["dummy", "dummy"]
573573
--- no_error_log
574574
[error]
575+
576+
577+
578+
=== TEST 25: pipelined requests
579+
--- config
580+
location /t {
581+
content_by_lua_block {
582+
ngx.exec("@foo")
583+
}
584+
}
585+
586+
location @foo {
587+
return 200;
588+
}
589+
--- pipelined_requests eval
590+
["GET /t", "GET /t"]
591+
--- error_code eval
592+
[200, 200]
593+
--- response_body eval
594+
["", ""]
595+
--- no_error_log
596+
[error]

0 commit comments

Comments
 (0)