Skip to content

Commit cd4af8a

Browse files
author
Mike Pall
committed
Avoid out-of-range PC for stack overflow error from snapshot restore.
Reported by Sergey Kaplun. #1359
1 parent 9c8eb7c commit cd4af8a

File tree

3 files changed

+10
-15
lines changed

3 files changed

+10
-15
lines changed

src/lj_bc.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,11 @@ static LJ_AINLINE int bc_isret(BCOp op)
255255
return (op == BC_RETM || op == BC_RET || op == BC_RET0 || op == BC_RET1);
256256
}
257257

258+
static LJ_AINLINE int bc_isret_or_tail(BCOp op)
259+
{
260+
return (op == BC_CALLMT || op == BC_CALLT || bc_isret(op));
261+
}
262+
258263
LJ_DATA const uint16_t lj_bc_mode[];
259264
LJ_DATA const uint16_t lj_bc_ofs[];
260265

src/lj_parse.c

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1529,23 +1529,11 @@ static void fs_fixup_var(LexState *ls, GCproto *pt, uint8_t *p, size_t ofsvar)
15291529

15301530
#endif
15311531

1532-
/* Check if bytecode op returns. */
1533-
static int bcopisret(BCOp op)
1534-
{
1535-
switch (op) {
1536-
case BC_CALLMT: case BC_CALLT:
1537-
case BC_RETM: case BC_RET: case BC_RET0: case BC_RET1:
1538-
return 1;
1539-
default:
1540-
return 0;
1541-
}
1542-
}
1543-
15441532
/* Fixup return instruction for prototype. */
15451533
static void fs_fixup_ret(FuncState *fs)
15461534
{
15471535
BCPos lastpc = fs->pc;
1548-
if (lastpc <= fs->lasttarget || !bcopisret(bc_op(fs->bcbase[lastpc-1].ins))) {
1536+
if (lastpc <= fs->lasttarget || !bc_isret_or_tail(bc_op(fs->bcbase[lastpc-1].ins))) {
15491537
if ((fs->bl->flags & FSCOPE_UPVAL))
15501538
bcemit_AJ(fs, BC_UCLO, 0, 0);
15511539
bcemit_AD(fs, BC_RET0, 0, 1); /* Need final return. */

src/lj_snap.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -872,8 +872,10 @@ const BCIns *lj_snap_restore(jit_State *J, void *exptr)
872872
const BCIns *pc = snap_pc(map[nent]);
873873
lua_State *L = J->L;
874874

875-
/* Set interpreter PC to the next PC to get correct error messages. */
876-
setcframe_pc(L->cframe, pc+1);
875+
/* Set interpreter PC to the next PC to get correct error messages.
876+
** But not for returns or tail calls, since pc+1 may be out-of-range.
877+
*/
878+
setcframe_pc(L->cframe, bc_isret_or_tail(bc_op(*pc)) ? pc : pc+1);
877879
setcframe_pc(cframe_raw(cframe_prev(L->cframe)), pc);
878880

879881
/* Make sure the stack is big enough for the slots from the snapshot. */

0 commit comments

Comments
 (0)