fix Segmentation fault
This commit is contained in:
parent
37f5c71827
commit
5b8c8d7755
236
backport-Bug-Recursion-in-getobjname-can-stack-overflow.patch
Normal file
236
backport-Bug-Recursion-in-getobjname-can-stack-overflow.patch
Normal file
@ -0,0 +1,236 @@
|
||||
From 7923dbbf72da303ca1cca17efd24725668992f15 Mon Sep 17 00:00:00 2001
|
||||
From: Roberto Ierusalimschy <roberto@inf.puc-rio.br>
|
||||
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
|
||||
|
||||
8
lua.spec
8
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 <wangjiang37@h-partners.com> - 5.4.6-2
|
||||
- fix Segmentation fault
|
||||
|
||||
* Wed Jun 14 2023 yanglongkang <yanglongkang@h-partners.com> - 5.4.6-1
|
||||
- upgrade to version 5.4.6
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user