Skip to content

Commit 94801d8

Browse files
committed
bugfix: lua panic handling in ngx.socket.tcp
If luaL_pushresult() encounters a buffer larger than 2GB, it triggers a Lua panic. This panic is handled by ngx_http_lua_atpanic(), which performs a longjmp() back to the last setjmp() call point (e.g., ngx_http_lua_log_by_chunk()), potentially causing a SEGFAULT or ABORT signal if stack protection is enabled. The fix sets the handler that manages Lua panics directly within ngx_http_lua_socket_push_input_data().
1 parent 950b1fb commit 94801d8

File tree

1 file changed

+46
-35
lines changed

1 file changed

+46
-35
lines changed

src/ngx_http_lua_socket_tcp.c

+46-35
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include "ngx_http_lua_socket_tcp.h"
1414
#include "ngx_http_lua_input_filters.h"
1515
#include "ngx_http_lua_util.h"
16+
#include "ngx_http_lua_exception.h"
1617
#include "ngx_http_lua_uthread.h"
1718
#include "ngx_http_lua_output.h"
1819
#include "ngx_http_lua_contentby.h"
@@ -5923,62 +5924,72 @@ ngx_http_lua_socket_push_input_data(ngx_http_request_t *r,
59235924
size_t nbufs;
59245925
luaL_Buffer luabuf;
59255926

5926-
dd("bufs_in: %p, buf_in: %p", u->bufs_in, u->buf_in);
5927+
/* set Lua VM panic handler */
5928+
lua_atpanic(L, ngx_http_lua_atpanic);
59275929

5928-
nbufs = 0;
5929-
ll = NULL;
5930+
NGX_LUA_EXCEPTION_TRY {
59305931

5931-
luaL_buffinit(L, &luabuf);
5932+
dd("bufs_in: %p, buf_in: %p", u->bufs_in, u->buf_in);
59325933

5933-
for (cl = u->bufs_in; cl; cl = cl->next) {
5934-
b = cl->buf;
5935-
chunk_size = b->last - b->pos;
5934+
nbufs = 0;
5935+
ll = NULL;
5936+
5937+
luaL_buffinit(L, &luabuf);
59365938

5937-
dd("copying input data chunk from %p: \"%.*s\"", cl,
5938-
(int) chunk_size, b->pos);
5939+
for (cl = u->bufs_in; cl; cl = cl->next) {
5940+
b = cl->buf;
5941+
chunk_size = b->last - b->pos;
59395942

5940-
luaL_addlstring(&luabuf, (char *) b->pos, chunk_size);
5943+
dd("copying input data chunk from %p: \"%.*s\"", cl,
5944+
(int) chunk_size, b->pos);
59415945

5942-
if (cl->next) {
5943-
ll = &cl->next;
5944-
}
5946+
luaL_addlstring(&luabuf, (char *) b->pos, chunk_size);
5947+
5948+
if (cl->next) {
5949+
ll = &cl->next;
5950+
}
59455951

59465952
#if (DDEBUG) || (NGX_DTRACE)
5947-
size += chunk_size;
5953+
size += chunk_size;
59485954
#endif
59495955

5950-
nbufs++;
5951-
}
5956+
nbufs++;
5957+
}
59525958

5953-
luaL_pushresult(&luabuf);
5959+
luaL_pushresult(&luabuf);
59545960

59555961
#if (DDEBUG)
5956-
dd("size: %d, nbufs: %d", (int) size, (int) nbufs);
5962+
dd("size: %d, nbufs: %d", (int) size, (int) nbufs);
59575963
#endif
59585964

59595965
#if (NGX_DTRACE)
5960-
ngx_http_lua_probe_socket_tcp_receive_done(r, u,
5961-
(u_char *) lua_tostring(L, -1),
5962-
size);
5966+
ngx_http_lua_probe_socket_tcp_receive_done(
5967+
r, u, (u_char *) lua_tostring(L, -1), size);
59635968
#endif
59645969

5965-
if (nbufs > 1 && ll) {
5966-
dd("recycle buffers: %d", (int) (nbufs - 1));
5970+
if (nbufs > 1 && ll) {
5971+
dd("recycle buffers: %d", (int) (nbufs - 1));
59675972

5968-
*ll = ctx->free_recv_bufs;
5969-
ctx->free_recv_bufs = u->bufs_in;
5970-
u->bufs_in = u->buf_in;
5971-
}
5973+
*ll = ctx->free_recv_bufs;
5974+
ctx->free_recv_bufs = u->bufs_in;
5975+
u->bufs_in = u->buf_in;
5976+
}
59725977

5973-
if (u->buffer.pos == u->buffer.last) {
5974-
dd("resetting u->buffer pos & last");
5975-
u->buffer.pos = u->buffer.start;
5976-
u->buffer.last = u->buffer.start;
5977-
}
5978+
if (u->buffer.pos == u->buffer.last) {
5979+
dd("resetting u->buffer pos & last");
5980+
u->buffer.pos = u->buffer.start;
5981+
u->buffer.last = u->buffer.start;
5982+
}
59785983

5979-
if (u->bufs_in) {
5980-
u->buf_in->buf->last = u->buffer.pos;
5981-
u->buf_in->buf->pos = u->buffer.pos;
5984+
if (u->bufs_in) {
5985+
u->buf_in->buf->last = u->buffer.pos;
5986+
u->buf_in->buf->pos = u->buffer.pos;
5987+
}
5988+
5989+
} NGX_LUA_EXCEPTION_CATCH {
5990+
5991+
dd("nginx execution restored");
5992+
return NGX_ERROR;
59825993
}
59835994

59845995
return NGX_OK;

0 commit comments

Comments
 (0)