From 71d080279aa80917b945f433f18aa6b237b72ef9 Mon Sep 17 00:00:00 2001 From: wangjiang Date: Tue, 13 Aug 2024 17:09:57 +0800 Subject: [PATCH] fix Segmentation fault (cherry picked from commit 5b8c8d7755833314ce3ac40f097a1e6072c5f82f) --- ...ion-in-getobjname-can-stack-overflow.patch | 236 ++++++++++++++++++ lua.spec | 8 +- 2 files changed, 243 insertions(+), 1 deletion(-) create mode 100644 backport-Bug-Recursion-in-getobjname-can-stack-overflow.patch diff --git a/backport-Bug-Recursion-in-getobjname-can-stack-overflow.patch b/backport-Bug-Recursion-in-getobjname-can-stack-overflow.patch new file mode 100644 index 0000000..c5adaa0 --- /dev/null +++ b/backport-Bug-Recursion-in-getobjname-can-stack-overflow.patch @@ -0,0 +1,236 @@ +From 7923dbbf72da303ca1cca17efd24725668992f15 Mon Sep 17 00:00:00 2001 +From: Roberto Ierusalimschy +Date: Wed, 1 Nov 2023 12:00:54 -0300 +Subject: [PATCH 3/3] Bug: Recursion in 'getobjname' can stack overflow + +'getobjname' now broken in two, a basic version that handles locals, +upvalues, and constants, and a full version, which uses the basic +version to handle table accesses (globals and fields). + +Reference:https://github.com/lua/lua/commit/7923dbbf72da303ca1cca17efd24725668992f15 +Conflict:lua-5.4.6-tests/errors.lua, src/ldebug.c +--- + lua-5.4.6-tests/errors.lua | 3 + + src/ldebug.c | 154 ++++++++++++++++++++----------------- + 2 files changed, 87 insertions(+), 70 deletions(-) + +diff --git a/lua-5.4.6-tests/errors.lua b/lua-5.4.6-tests/errors.lua +index a3d0676..5cef9e1 100644 +--- a/lua-5.4.6-tests/errors.lua ++++ b/lua-5.4.6-tests/errors.lua +@@ -123,6 +123,9 @@ assert(not string.find(doit"a={13}; local bbbb=1; a[bbbb](3)", "'bbbb'")) + + _G.aaa, _G.bbbb = nil + ++-- bug in 5.4.6 ++checkmessage("a = {_ENV = {}}; print(a._ENV.x + 1)", "field 'x'") ++ + -- calls + checkmessage("local a; a(13)", "local 'a'") + checkmessage([[ +diff --git a/src/ldebug.c b/src/ldebug.c +index 5524fae..c605a8a 100644 +--- a/src/ldebug.c ++++ b/src/ldebug.c +@@ -417,41 +417,6 @@ LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar) { + ** ======================================================= + */ + +-static const char *getobjname (const Proto *p, int lastpc, int reg, +- const char **name); +- +- +-/* +-** Find a "name" for the constant 'c'. +-*/ +-static void kname (const Proto *p, int c, const char **name) { +- TValue *kvalue = &p->k[c]; +- *name = (ttisstring(kvalue)) ? svalue(kvalue) : "?"; +-} +- +- +-/* +-** Find a "name" for the register 'c'. +-*/ +-static void rname (const Proto *p, int pc, int c, const char **name) { +- const char *what = getobjname(p, pc, c, name); /* search for 'c' */ +- if (!(what && *what == 'c')) /* did not find a constant name? */ +- *name = "?"; +-} +- +- +-/* +-** Find a "name" for a 'C' value in an RK instruction. +-*/ +-static void rkname (const Proto *p, int pc, Instruction i, const char **name) { +- int c = GETARG_C(i); /* key index */ +- if (GETARG_k(i)) /* is 'c' a constant? */ +- kname(p, c, name); +- else /* 'c' is a register */ +- rname(p, pc, c, name); +-} +- +- + static int filterpc (int pc, int jmptarget) { + if (pc < jmptarget) /* is code conditional (inside a jump)? */ + return -1; /* cannot know who sets that register */ +@@ -509,28 +474,29 @@ static int findsetreg (const Proto *p, int lastpc, int reg) { + + + /* +-** Check whether table being indexed by instruction 'i' is the +-** environment '_ENV' ++** Find a "name" for the constant 'c'. + */ +-static const char *gxf (const Proto *p, int pc, Instruction i, int isup) { +- int t = GETARG_B(i); /* table index */ +- const char *name; /* name of indexed variable */ +- if (isup) /* is an upvalue? */ +- name = upvalname(p, t); +- else +- getobjname(p, pc, t, &name); +- return (name && strcmp(name, LUA_ENV) == 0) ? "global" : "field"; ++static const char *kname (const Proto *p, int index, const char **name) { ++ TValue *kvalue = &p->k[index]; ++ if (ttisstring(kvalue)) { ++ *name = getstr(tsvalue(kvalue)); ++ return "constant"; ++ } ++ else { ++ *name = "?"; ++ return NULL; ++ } + } + + +-static const char *getobjname (const Proto *p, int lastpc, int reg, +- const char **name) { +- int pc; +- *name = luaF_getlocalname(p, reg + 1, lastpc); ++static const char *basicgetobjname (const Proto *p, int *ppc, int reg, ++ const char **name) { ++ int pc = *ppc; ++ *name = luaF_getlocalname(p, reg + 1, pc); + if (*name) /* is a local? */ + return "local"; + /* else try symbolic execution */ +- pc = findsetreg(p, lastpc, reg); ++ *ppc = pc = findsetreg(p, pc, reg); + if (pc != -1) { /* could find instruction? */ + Instruction i = p->code[pc]; + OpCode op = GET_OPCODE(i); +@@ -538,18 +504,80 @@ static const char *getobjname (const Proto *p, int lastpc, int reg, + case OP_MOVE: { + int b = GETARG_B(i); /* move from 'b' to 'a' */ + if (b < GETARG_A(i)) +- return getobjname(p, pc, b, name); /* get name for 'b' */ ++ return basicgetobjname(p, ppc, b, name); /* get name for 'b' */ + break; + } ++ case OP_GETUPVAL: { ++ *name = upvalname(p, GETARG_B(i)); ++ return "upvalue"; ++ } ++ case OP_LOADK: return kname(p, GETARG_Bx(i), name); ++ case OP_LOADKX: return kname(p, GETARG_Ax(p->code[pc + 1]), name); ++ default: break; ++ } ++ } ++ return NULL; /* could not find reasonable name */ ++} ++ ++ ++/* ++** Find a "name" for the register 'c'. ++*/ ++static void rname (const Proto *p, int pc, int c, const char **name) { ++ const char *what = basicgetobjname(p, &pc, c, name); /* search for 'c' */ ++ if (!(what && *what == 'c')) /* did not find a constant name? */ ++ *name = "?"; ++} ++ ++ ++/* ++** Find a "name" for a 'C' value in an RK instruction. ++*/ ++static void rkname (const Proto *p, int pc, Instruction i, const char **name) { ++ int c = GETARG_C(i); /* key index */ ++ if (GETARG_k(i)) /* is 'c' a constant? */ ++ kname(p, c, name); ++ else /* 'c' is a register */ ++ rname(p, pc, c, name); ++} ++ ++ ++/* ++** Check whether table being indexed by instruction 'i' is the ++** environment '_ENV' ++*/ ++static const char *isEnv (const Proto *p, int pc, Instruction i, int isup) { ++ int t = GETARG_B(i); /* table index */ ++ const char *name; /* name of indexed variable */ ++ if (isup) /* is 't' an upvalue? */ ++ name = upvalname(p, t); ++ else /* 't' is a register */ ++ basicgetobjname(p, &pc, t, &name); ++ return (name && strcmp(name, LUA_ENV) == 0) ? "global" : "field"; ++} ++ ++ ++/* ++** Extend 'basicgetobjname' to handle table accesses ++*/ ++static const char *getobjname (const Proto *p, int lastpc, int reg, ++ const char **name) { ++ const char *kind = basicgetobjname(p, &lastpc, reg, name); ++ if (kind != NULL) ++ return kind; ++ else if (lastpc != -1) { /* could find instruction? */ ++ Instruction i = p->code[lastpc]; ++ OpCode op = GET_OPCODE(i); ++ switch (op) { + case OP_GETTABUP: { + int k = GETARG_C(i); /* key index */ + kname(p, k, name); +- return gxf(p, pc, i, 1); ++ return isEnv(p, lastpc, i, 1); + } + case OP_GETTABLE: { + int k = GETARG_C(i); /* key index */ +- rname(p, pc, k, name); +- return gxf(p, pc, i, 0); ++ rname(p, lastpc, k, name); ++ return isEnv(p, lastpc, i, 0); + } + case OP_GETI: { + *name = "integer index"; +@@ -558,24 +586,10 @@ static const char *getobjname (const Proto *p, int lastpc, int reg, + case OP_GETFIELD: { + int k = GETARG_C(i); /* key index */ + kname(p, k, name); +- return gxf(p, pc, i, 0); +- } +- case OP_GETUPVAL: { +- *name = upvalname(p, GETARG_B(i)); +- return "upvalue"; +- } +- case OP_LOADK: +- case OP_LOADKX: { +- int b = (op == OP_LOADK) ? GETARG_Bx(i) +- : GETARG_Ax(p->code[pc + 1]); +- if (ttisstring(&p->k[b])) { +- *name = svalue(&p->k[b]); +- return "constant"; +- } +- break; ++ return isEnv(p, lastpc, i, 0); + } + case OP_SELF: { +- rkname(p, pc, i, name); ++ rkname(p, lastpc, i, name); + return "method"; + } + default: break; /* go through to return NULL */ +-- +2.33.0 + diff --git a/lua.spec b/lua.spec index 7d5fffc..55ed186 100644 --- a/lua.spec +++ b/lua.spec @@ -6,7 +6,7 @@ Name: lua Version: 5.4.6 -Release: 1 +Release: 2 Summary: A powerful, efficient, lightweight, embeddable scripting language License: MIT URL: http://www.lua.org/ @@ -24,6 +24,8 @@ Patch1: lua-5.4.6-idsize.patch Patch2: lua-5.2.2-configure-linux.patch Patch3: lua-5.3.0-configure-compat-module.patch +Patch6000: backport-Bug-Recursion-in-getobjname-can-stack-overflow.patch + BuildRequires: automake autoconf libtool readline-devel ncurses-devel Obsoletes: %{name}-libs < %{version}-%{release} @@ -55,6 +57,7 @@ mv src/luaconf.h src/luaconf.h.template.in %patch1 -p1 -z .idsize %patch2 -p1 -z .configure-linux %patch3 -p1 -z .configure-compat-all +%patch6000 -p1 # Put proper version in configure.ac, patch0 hardcodes 5.3.0 sed -i 's|5.3.0|%{version}|g' configure.ac @@ -129,6 +132,9 @@ LD_LIBRARY_PATH=$RPM_BUILD_ROOT/%{_libdir} $RPM_BUILD_ROOT/%{_bindir}/lua -e"_U= %{_mandir}/man1/lua*.1* %changelog +* Tue Aug 13 2024 wangjiang - 5.4.6-2 +- fix Segmentation fault + * Wed Jun 14 2023 yanglongkang - 5.4.6-1 - upgrade to version 5.4.6 -- Gitee