diff options
| author | Mike Pall <mike> | 2024-02-04 16:34:30 +0100 |
|---|---|---|
| committer | Mike Pall <mike> | 2024-02-04 16:34:30 +0100 |
| commit | defe61a56751a0db5f00ff3ab7b8f45436ba74c8 (patch) | |
| tree | c9415344aea204341e4c2620d06e624c0209ce67 /src/lj_err.c | |
| parent | 9cdd5a9479d2265f42dfefc17d068174969bbcff (diff) | |
| download | luajit-defe61a56751a0db5f00ff3ab7b8f45436ba74c8.tar.gz luajit-defe61a56751a0db5f00ff3ab7b8f45436ba74c8.tar.bz2 luajit-defe61a56751a0db5f00ff3ab7b8f45436ba74c8.zip | |
Rework stack overflow handling.
Reported by pwnhacker0x18. Fixed by Peter Cawley. #1152
Diffstat (limited to 'src/lj_err.c')
| -rw-r--r-- | src/lj_err.c | 22 |
1 files changed, 19 insertions, 3 deletions
diff --git a/src/lj_err.c b/src/lj_err.c index 4a2d6bbd..7afe1e29 100644 --- a/src/lj_err.c +++ b/src/lj_err.c | |||
| @@ -488,7 +488,14 @@ LJ_NOINLINE void lj_err_mem(lua_State *L) | |||
| 488 | { | 488 | { |
| 489 | if (L->status == LUA_ERRERR+1) /* Don't touch the stack during lua_open. */ | 489 | if (L->status == LUA_ERRERR+1) /* Don't touch the stack during lua_open. */ |
| 490 | lj_vm_unwind_c(L->cframe, LUA_ERRMEM); | 490 | lj_vm_unwind_c(L->cframe, LUA_ERRMEM); |
| 491 | if (curr_funcisL(L)) L->top = curr_topL(L); | 491 | if (curr_funcisL(L)) { |
| 492 | L->top = curr_topL(L); | ||
| 493 | if (LJ_UNLIKELY(L->top > tvref(L->maxstack))) { | ||
| 494 | /* The current Lua frame violates the stack. Replace it with a dummy. */ | ||
| 495 | L->top = L->base; | ||
| 496 | setframe_gc(L->base - 1, obj2gco(L)); | ||
| 497 | } | ||
| 498 | } | ||
| 492 | setstrV(L, L->top++, lj_err_str(L, LJ_ERR_ERRMEM)); | 499 | setstrV(L, L->top++, lj_err_str(L, LJ_ERR_ERRMEM)); |
| 493 | lj_err_throw(L, LUA_ERRMEM); | 500 | lj_err_throw(L, LUA_ERRMEM); |
| 494 | } | 501 | } |
| @@ -551,9 +558,11 @@ LJ_NOINLINE void LJ_FASTCALL lj_err_run(lua_State *L) | |||
| 551 | { | 558 | { |
| 552 | ptrdiff_t ef = finderrfunc(L); | 559 | ptrdiff_t ef = finderrfunc(L); |
| 553 | if (ef) { | 560 | if (ef) { |
| 554 | TValue *errfunc = restorestack(L, ef); | 561 | TValue *errfunc, *top; |
| 555 | TValue *top = L->top; | 562 | lj_state_checkstack(L, LUA_MINSTACK * 2); /* Might raise new error. */ |
| 556 | lj_trace_abort(G(L)); | 563 | lj_trace_abort(G(L)); |
| 564 | errfunc = restorestack(L, ef); | ||
| 565 | top = L->top; | ||
| 557 | if (!tvisfunc(errfunc) || L->status == LUA_ERRERR) { | 566 | if (!tvisfunc(errfunc) || L->status == LUA_ERRERR) { |
| 558 | setstrV(L, top-1, lj_err_str(L, LJ_ERR_ERRERR)); | 567 | setstrV(L, top-1, lj_err_str(L, LJ_ERR_ERRERR)); |
| 559 | lj_err_throw(L, LUA_ERRERR); | 568 | lj_err_throw(L, LUA_ERRERR); |
| @@ -567,6 +576,13 @@ LJ_NOINLINE void LJ_FASTCALL lj_err_run(lua_State *L) | |||
| 567 | lj_err_throw(L, LUA_ERRRUN); | 576 | lj_err_throw(L, LUA_ERRRUN); |
| 568 | } | 577 | } |
| 569 | 578 | ||
| 579 | /* Stack overflow error. */ | ||
| 580 | void LJ_FASTCALL lj_err_stkov(lua_State *L) | ||
| 581 | { | ||
| 582 | lj_debug_addloc(L, err2msg(LJ_ERR_STKOV), L->base-1, NULL); | ||
| 583 | lj_err_run(L); | ||
| 584 | } | ||
| 585 | |||
| 570 | /* Formatted runtime error message. */ | 586 | /* Formatted runtime error message. */ |
| 571 | LJ_NORET LJ_NOINLINE static void err_msgv(lua_State *L, ErrMsg em, ...) | 587 | LJ_NORET LJ_NOINLINE static void err_msgv(lua_State *L, ErrMsg em, ...) |
| 572 | { | 588 | { |
