From 8050c843bd8068fcf2a96c099c3bb508cd5413c9 Mon Sep 17 00:00:00 2001 From: Tom spot Callaway Date: Mon, 24 Jan 2022 17:23:29 -0500 Subject: [PATCH] apply upstream fix for CVE-2021-44647, apply upstream fixes for known lua bugs 4-10 (11 assumes other changes beyond 5.4.3) --- lua-5.4.3-CVE-2021-44647.patch | 11 ++ lua-5.4.3-bug10.patch | 261 +++++++++++++++++++++++++++++++++ lua-5.4.3-bug4.patch | 23 +++ lua-5.4.3-bug5.patch | 11 ++ lua-5.4.3-bug6.patch | 12 ++ lua-5.4.3-bug7.patch | 50 +++++++ lua-5.4.3-bug8.patch | 143 ++++++++++++++++++ lua.spec | 22 ++- 8 files changed, 532 insertions(+), 1 deletion(-) create mode 100644 lua-5.4.3-CVE-2021-44647.patch create mode 100644 lua-5.4.3-bug10.patch create mode 100644 lua-5.4.3-bug4.patch create mode 100644 lua-5.4.3-bug5.patch create mode 100644 lua-5.4.3-bug6.patch create mode 100644 lua-5.4.3-bug7.patch create mode 100644 lua-5.4.3-bug8.patch diff --git a/lua-5.4.3-CVE-2021-44647.patch b/lua-5.4.3-CVE-2021-44647.patch new file mode 100644 index 0000000..5e1d5a7 --- /dev/null +++ b/lua-5.4.3-CVE-2021-44647.patch @@ -0,0 +1,11 @@ +diff -up lua-5.4.3/src/lstate.c.CVE-2021-44647 lua-5.4.3/src/lstate.c +--- lua-5.4.3/src/lstate.c.CVE-2021-44647 2022-01-24 11:15:00.851544455 -0500 ++++ lua-5.4.3/src/lstate.c 2022-01-24 11:15:27.187694727 -0500 +@@ -271,6 +271,7 @@ static void close_state (lua_State *L) { + if (!completestate(g)) /* closing a partially built state? */ + luaC_freeallobjects(L); /* jucst collect its objects */ + else { /* closing a fully built state */ ++ L->ci = &L->base_ci; /* unwind CallInfo list */ + luaD_closeprotected(L, 1, LUA_OK); /* close all upvalues */ + luaC_freeallobjects(L); /* collect all objects */ + luai_userstateclose(L); diff --git a/lua-5.4.3-bug10.patch b/lua-5.4.3-bug10.patch new file mode 100644 index 0000000..9245cbc --- /dev/null +++ b/lua-5.4.3-bug10.patch @@ -0,0 +1,261 @@ +diff -up lua-5.4.3/lua-5.4.3-tests/api.lua.bug10 lua-5.4.3/lua-5.4.3-tests/api.lua +--- lua-5.4.3/lua-5.4.3-tests/api.lua.bug10 2022-01-24 17:07:28.084973092 -0500 ++++ lua-5.4.3/lua-5.4.3-tests/api.lua 2022-01-24 17:08:50.306551450 -0500 +@@ -804,15 +804,14 @@ F = function (x) + d = nil + assert(debug.getmetatable(x).__gc == F) + assert(load("table.insert({}, {})"))() -- create more garbage +- collectgarbage() -- force a GC during GC +- assert(debug.getmetatable(x).__gc == F) -- previous GC did not mess this? ++ assert(not collectgarbage()) -- GC during GC (no op) + local dummy = {} -- create more garbage during GC + if A ~= nil then + assert(type(A) == "userdata") + assert(T.udataval(A) == B) + debug.getmetatable(A) -- just access it + end +- A = x -- ressucita userdata ++ A = x -- ressurect userdata + B = udval + return 1,2,3 + end +diff -up lua-5.4.3/lua-5.4.3-tests/gc.lua.bug10 lua-5.4.3/lua-5.4.3-tests/gc.lua +--- lua-5.4.3/lua-5.4.3-tests/gc.lua.bug10 2022-01-24 17:08:57.241600231 -0500 ++++ lua-5.4.3/lua-5.4.3-tests/gc.lua 2022-01-24 17:10:20.100183086 -0500 +@@ -676,11 +676,13 @@ end + -- just to make sure + assert(collectgarbage'isrunning') + +-do -- check that the collector is reentrant in incremental mode ++do -- check that the collector is not reentrant in incremental mode ++ local res = true + setmetatable({}, {__gc = function () +- collectgarbage() ++ res = collectgarbage() + end}) + collectgarbage() ++ assert(not res) + end + + +diff -up lua-5.4.3/src/lapi.c.bug10 lua-5.4.3/src/lapi.c +--- lua-5.4.3/src/lapi.c.bug10 2022-01-24 16:56:54.409515673 -0500 ++++ lua-5.4.3/src/lapi.c 2022-01-24 16:59:36.136653287 -0500 +@@ -1126,18 +1126,19 @@ LUA_API int lua_status (lua_State *L) { + LUA_API int lua_gc (lua_State *L, int what, ...) { + va_list argp; + int res = 0; +- global_State *g; ++ global_State *g = G(L); ++ if (g->gcstp & GCSTPGC) /* internal stop? */ ++ return -1; /* all options are invalid when stopped */ + lua_lock(L); +- g = G(L); + va_start(argp, what); + switch (what) { + case LUA_GCSTOP: { +- g->gcrunning = 0; ++ g->gcstp = GCSTPUSR; /* stopeed by the user */ + break; + } + case LUA_GCRESTART: { + luaE_setdebt(g, 0); +- g->gcrunning = 1; ++ g->gcstp = 0; /* (GCSTPGC must be already zero here) */ + break; + } + case LUA_GCCOLLECT: { +@@ -1156,8 +1157,8 @@ LUA_API int lua_gc (lua_State *L, int wh + case LUA_GCSTEP: { + int data = va_arg(argp, int); + l_mem debt = 1; /* =1 to signal that it did an actual step */ +- lu_byte oldrunning = g->gcrunning; +- g->gcrunning = 1; /* allow GC to run */ ++ lu_byte oldstp = g->gcstp; ++ g->gcstp = 0; /* allow GC to run (GCSTPGC must be zero here) */ + if (data == 0) { + luaE_setdebt(g, 0); /* do a basic step */ + luaC_step(L); +@@ -1167,7 +1168,7 @@ LUA_API int lua_gc (lua_State *L, int wh + luaE_setdebt(g, debt); + luaC_checkGC(L); + } +- g->gcrunning = oldrunning; /* restore previous state */ ++ g->gcstp = oldstp; /* restore previous state */ + if (debt > 0 && g->gcstate == GCSpause) /* end of cycle? */ + res = 1; /* signal it */ + break; +@@ -1185,7 +1186,7 @@ LUA_API int lua_gc (lua_State *L, int wh + break; + } + case LUA_GCISRUNNING: { +- res = g->gcrunning; ++ res = gcrunning(g); + break; + } + case LUA_GCGEN: { +diff -up lua-5.4.3/src/lbaselib.c.bug10 lua-5.4.3/src/lbaselib.c +--- lua-5.4.3/src/lbaselib.c.bug10 2022-01-24 16:59:43.337703940 -0500 ++++ lua-5.4.3/src/lbaselib.c 2022-01-24 17:02:19.898805225 -0500 +@@ -182,12 +182,20 @@ static int luaB_rawset (lua_State *L) { + + + static int pushmode (lua_State *L, int oldmode) { +- lua_pushstring(L, (oldmode == LUA_GCINC) ? "incremental" +- : "generational"); ++ if (oldmode == -1) ++ luaL_pushfail(L); /* invalid call to 'lua_gc' */ ++ else ++ lua_pushstring(L, (oldmode == LUA_GCINC) ? "incremental" ++ : "generational"); + return 1; + } + + ++/* ++** check whether call to 'lua_gc' was valid (not inside a finalizer) ++*/ ++#define checkvalres(res) { if (res == -1) break; } ++ + static int luaB_collectgarbage (lua_State *L) { + static const char *const opts[] = {"stop", "restart", "collect", + "count", "step", "setpause", "setstepmul", +@@ -200,12 +208,14 @@ static int luaB_collectgarbage (lua_Stat + case LUA_GCCOUNT: { + int k = lua_gc(L, o); + int b = lua_gc(L, LUA_GCCOUNTB); ++ checkvalres(k); + lua_pushnumber(L, (lua_Number)k + ((lua_Number)b/1024)); + return 1; + } + case LUA_GCSTEP: { + int step = (int)luaL_optinteger(L, 2, 0); + int res = lua_gc(L, o, step); ++ checkvalres(res); + lua_pushboolean(L, res); + return 1; + } +@@ -213,11 +223,13 @@ static int luaB_collectgarbage (lua_Stat + case LUA_GCSETSTEPMUL: { + int p = (int)luaL_optinteger(L, 2, 0); + int previous = lua_gc(L, o, p); ++ checkvalres(previous); + lua_pushinteger(L, previous); + return 1; + } + case LUA_GCISRUNNING: { + int res = lua_gc(L, o); ++ checkvalres(res); + lua_pushboolean(L, res); + return 1; + } +@@ -234,10 +246,13 @@ static int luaB_collectgarbage (lua_Stat + } + default: { + int res = lua_gc(L, o); ++ checkvalres(res); + lua_pushinteger(L, res); + return 1; + } + } ++ luaL_pushfail(L); /* invalid call (inside a finalizer) */ ++ return 1; + } + + +diff -up lua-5.4.3/src/lgc.c.bug10 lua-5.4.3/src/lgc.c +--- lua-5.4.3/src/lgc.c.bug10 2022-01-24 17:02:30.231877910 -0500 ++++ lua-5.4.3/src/lgc.c 2022-01-24 17:04:02.486526852 -0500 +@@ -906,16 +906,16 @@ static void GCTM (lua_State *L) { + if (!notm(tm)) { /* is there a finalizer? */ + int status; + lu_byte oldah = L->allowhook; +- int running = g->gcrunning; ++ int oldgcstp = g->gcstp; ++ g->gcstp = GCSTPGC; /* avoid GC steps */ + L->allowhook = 0; /* stop debug hooks during GC metamethod */ +- g->gcrunning = 0; /* avoid GC steps */ + setobj2s(L, L->top++, tm); /* push finalizer... */ + setobj2s(L, L->top++, &v); /* ... and its argument */ + L->ci->callstatus |= CIST_FIN; /* will run a finalizer */ + status = luaD_pcall(L, dothecall, NULL, savestack(L, L->top - 2), 0); + L->ci->callstatus &= ~CIST_FIN; /* not running a finalizer anymore */ + L->allowhook = oldah; /* restore hooks */ +- g->gcrunning = running; /* restore state */ ++ g->gcstp = oldgcstp; /* restore state */ + if (l_unlikely(status != LUA_OK)) { /* error while running __gc? */ + luaE_warnerror(L, "__gc metamethod"); + L->top--; /* pops error object */ +@@ -1502,9 +1502,11 @@ static void deletelist (lua_State *L, GC + */ + void luaC_freeallobjects (lua_State *L) { + global_State *g = G(L); ++ g->gcstp = GCSTPGC; + luaC_changemode(L, KGC_INC); + separatetobefnz(g, 1); /* separate all objects with finalizers */ + lua_assert(g->finobj == NULL); ++ g->gcstp = 0; + callallpendingfinalizers(L); + deletelist(L, g->allgc, obj2gco(g->mainthread)); + deletelist(L, g->finobj, NULL); +@@ -1678,7 +1680,7 @@ static void incstep (lua_State *L, globa + void luaC_step (lua_State *L) { + global_State *g = G(L); + lua_assert(!g->gcemergency); +- if (g->gcrunning) { /* running? */ ++ if (gcrunning(g)) { /* running? */ + if(isdecGCmodegen(g)) + genstep(L, g); + else +diff -up lua-5.4.3/src/lgc.h.bug10 lua-5.4.3/src/lgc.h +--- lua-5.4.3/src/lgc.h.bug10 2022-01-24 17:04:08.890571899 -0500 ++++ lua-5.4.3/src/lgc.h 2022-01-24 17:04:41.260799595 -0500 +@@ -148,6 +148,15 @@ + */ + #define isdecGCmodegen(g) (g->gckind == KGC_GEN || g->lastatomic != 0) + ++ ++/* ++** Control when GC is running: ++*/ ++#define GCSTPUSR 1 /* bit true when GC stopped by user */ ++#define GCSTPGC 2 /* bit true when GC stopped by itself */ ++#define gcrunning(g) ((g)->gcstp == 0) ++ ++ + /* + ** Does one step of collection when debt becomes positive. 'pre'/'pos' + ** allows some adjustments to be done only when needed. macro +diff -up lua-5.4.3/src/lstate.c.bug10 lua-5.4.3/src/lstate.c +--- lua-5.4.3/src/lstate.c.bug10 2022-01-24 17:04:51.775873561 -0500 ++++ lua-5.4.3/src/lstate.c 2022-01-24 17:05:26.544118136 -0500 +@@ -236,7 +236,7 @@ static void f_luaopen (lua_State *L, voi + luaS_init(L); + luaT_init(L); + luaX_init(L); +- g->gcrunning = 1; /* allow gc */ ++ g->gcstp = 0; /* allow gc */ + setnilvalue(&g->nilvalue); /* now state is complete */ + luai_userstateopen(L); + } +@@ -373,7 +373,7 @@ LUA_API lua_State *lua_newstate (lua_All + g->ud_warn = NULL; + g->mainthread = L; + g->seed = luai_makeseed(L); +- g->gcrunning = 0; /* no GC while building state */ ++ g->gcstp = GCSTPGC; /* no GC while building state */ + g->strt.size = g->strt.nuse = 0; + g->strt.hash = NULL; + setnilvalue(&g->l_registry); +diff -up lua-5.4.3/src/lstate.h.bug10 lua-5.4.3/src/lstate.h +--- lua-5.4.3/src/lstate.h.bug10 2022-01-24 17:05:30.179143707 -0500 ++++ lua-5.4.3/src/lstate.h 2022-01-24 17:07:05.577814767 -0500 +@@ -263,7 +263,7 @@ typedef struct global_State { + lu_byte gcstopem; /* stops emergency collections */ + lu_byte genminormul; /* control for minor generational collections */ + lu_byte genmajormul; /* control for major generational collections */ +- lu_byte gcrunning; /* true if GC is running */ ++ lu_byte gcstp; /* control whether GC is running */ + lu_byte gcemergency; /* true if this is an emergency collection */ + lu_byte gcpause; /* size of pause between successive GCs */ + lu_byte gcstepmul; /* GC "speed" */ diff --git a/lua-5.4.3-bug4.patch b/lua-5.4.3-bug4.patch new file mode 100644 index 0000000..5df1de9 --- /dev/null +++ b/lua-5.4.3-bug4.patch @@ -0,0 +1,23 @@ +diff -up lua-5.4.3/lua-5.4.3-tests/locals.lua.bug4 lua-5.4.3/lua-5.4.3-tests/locals.lua +--- lua-5.4.3/lua-5.4.3-tests/locals.lua.bug4 2022-01-24 11:21:11.757660851 -0500 ++++ lua-5.4.3/lua-5.4.3-tests/locals.lua 2022-01-24 11:21:34.088788271 -0500 +@@ -187,6 +187,8 @@ do -- constants + checkro("y", "local x, y , z = 10, 20, 30; x = 11; y = 12") + checkro("x", "local x , y, z = 10, 20, 30; x = 11") + checkro("z", "local x , y, z = 10, 20, 30; y = 10; z = 11") ++ checkro("foo", "local foo = 10; function foo() end") ++ checkro("foo", "local foo = {}; function foo() end") + + checkro("z", [[ + local a, z , b = 10; +diff -up lua-5.4.3/src/lparser.c.bug4 lua-5.4.3/src/lparser.c +--- lua-5.4.3/src/lparser.c.bug4 2022-01-24 11:20:27.808410077 -0500 ++++ lua-5.4.3/src/lparser.c 2022-01-24 11:20:49.592534377 -0500 +@@ -1776,6 +1776,7 @@ static void funcstat (LexState *ls, int + luaX_next(ls); /* skip FUNCTION */ + ismethod = funcname(ls, &v); + body(ls, &b, ismethod, line); ++ check_readonly(ls, &v); + luaK_storevar(ls->fs, &v, &b); + luaK_fixline(ls->fs, line); /* definition "happens" in the first line */ + } diff --git a/lua-5.4.3-bug5.patch b/lua-5.4.3-bug5.patch new file mode 100644 index 0000000..a72b0e4 --- /dev/null +++ b/lua-5.4.3-bug5.patch @@ -0,0 +1,11 @@ +diff -up lua-5.4.3/src/lauxlib.c.bug5 lua-5.4.3/src/lauxlib.c +--- lua-5.4.3/src/lauxlib.c.bug5 2022-01-24 11:23:19.763391239 -0500 ++++ lua-5.4.3/src/lauxlib.c 2022-01-24 11:23:52.554578345 -0500 +@@ -881,6 +881,7 @@ LUALIB_API lua_Integer luaL_len (lua_Sta + + + LUALIB_API const char *luaL_tolstring (lua_State *L, int idx, size_t *len) { ++ idx = lua_absindex(L,idx); + if (luaL_callmeta(L, idx, "__tostring")) { /* metafield? */ + if (!lua_isstring(L, -1)) + luaL_error(L, "'__tostring' must return a string"); diff --git a/lua-5.4.3-bug6.patch b/lua-5.4.3-bug6.patch new file mode 100644 index 0000000..140cbab --- /dev/null +++ b/lua-5.4.3-bug6.patch @@ -0,0 +1,12 @@ +diff -up lua-5.4.3/src/lvm.c.bug6 lua-5.4.3/src/lvm.c +--- lua-5.4.3/src/lvm.c.bug6 2022-01-24 11:25:20.620080850 -0500 ++++ lua-5.4.3/src/lvm.c 2022-01-24 11:25:46.443228197 -0500 +@@ -766,7 +766,7 @@ lua_Number luaV_modf (lua_State *L, lua_ + /* + ** Shift left operation. (Shift right just negates 'y'.) + */ +-#define luaV_shiftr(x,y) luaV_shiftl(x,-(y)) ++#define luaV_shiftr(x,y) luaV_shiftl(x,intop(-, 0, y)) + + lua_Integer luaV_shiftl (lua_Integer x, lua_Integer y) { + if (y < 0) { /* shift right? */ diff --git a/lua-5.4.3-bug7.patch b/lua-5.4.3-bug7.patch new file mode 100644 index 0000000..ccb7a56 --- /dev/null +++ b/lua-5.4.3-bug7.patch @@ -0,0 +1,50 @@ +diff -up lua-5.4.3/lua-5.4.3-tests/cstack.lua.bug7 lua-5.4.3/lua-5.4.3-tests/cstack.lua +--- lua-5.4.3/lua-5.4.3-tests/cstack.lua.bug7 2022-01-24 11:29:00.412334975 -0500 ++++ lua-5.4.3/lua-5.4.3-tests/cstack.lua 2022-01-24 11:32:08.101405924 -0500 +@@ -103,6 +103,20 @@ do + end + + ++do -- bug in 5.4.2 ++ print("nesting coroutines running after recoverable errors") ++ local count = 0 ++ local function foo() ++ count = count + 1 ++ pcall(1) -- create an error ++ -- running now inside 'precover' ("protected recover") ++ coroutine.wrap(foo)() -- call another coroutine ++ end ++ checkerror("C stack overflow", foo) ++ print("final count: ", count) ++end ++ ++ + if T then + print("testing stack recovery") + local N = 0 -- trace number of calls +diff -up lua-5.4.3/src/ldo.c.bug7 lua-5.4.3/src/ldo.c +--- lua-5.4.3/src/ldo.c.bug7 2022-01-24 11:27:41.226883145 -0500 ++++ lua-5.4.3/src/ldo.c 2022-01-24 11:28:45.374249175 -0500 +@@ -728,11 +728,10 @@ static void resume (lua_State *L, void * + StkId firstArg = L->top - n; /* first argument */ + CallInfo *ci = L->ci; + if (L->status == LUA_OK) /* starting a coroutine? */ +- ccall(L, firstArg - 1, LUA_MULTRET, 1); /* just call its body */ ++ ccall(L, firstArg - 1, LUA_MULTRET, 0); /* just call its body */ + else { /* resuming from previous yield */ + lua_assert(L->status == LUA_YIELD); + L->status = LUA_OK; /* mark that it is running (again) */ +- luaE_incCstack(L); /* control the C stack */ + if (isLua(ci)) { /* yielded inside a hook? */ + L->top = firstArg; /* discard arguments */ + luaV_execute(L, ci); /* just continue running Lua code */ +@@ -783,6 +782,9 @@ LUA_API int lua_resume (lua_State *L, lu + else if (L->status != LUA_YIELD) /* ended with errors? */ + return resume_error(L, "cannot resume dead coroutine", nargs); + L->nCcalls = (from) ? getCcalls(from) : 0; ++ if (getCcalls(L) >= LUAI_MAXCCALLS) ++ return resume_error(L, "C stack overflow", nargs); ++ L->nCcalls++; + luai_userstateresume(L, nargs); + api_checknelems(L, (L->status == LUA_OK) ? nargs + 1 : nargs); + status = luaD_rawrunprotected(L, resume, &nargs); diff --git a/lua-5.4.3-bug8.patch b/lua-5.4.3-bug8.patch new file mode 100644 index 0000000..8e6ce8e --- /dev/null +++ b/lua-5.4.3-bug8.patch @@ -0,0 +1,143 @@ +diff -up lua-5.4.3/lua-5.4.3-tests/coroutine.lua.bug8 lua-5.4.3/lua-5.4.3-tests/coroutine.lua +--- lua-5.4.3/lua-5.4.3-tests/coroutine.lua.bug8 2022-01-24 13:52:57.345650003 -0500 ++++ lua-5.4.3/lua-5.4.3-tests/coroutine.lua 2022-01-24 13:55:46.679628140 -0500 +@@ -137,11 +137,16 @@ do + local st, msg = coroutine.close(co) + assert(st and msg == nil) + ++ + -- cannot close the running coroutine + local st, msg = pcall(coroutine.close, coroutine.running()) + assert(not st and string.find(msg, "running")) + + local main = coroutine.running() ++ -- also ok to close it again ++ st, msg = coroutine.close(co) ++ assert(st and msg == nil) ++ + + -- cannot close a "normal" coroutine + ;(coroutine.wrap(function () +@@ -149,6 +154,22 @@ do + assert(not st and string.find(msg, "normal")) + end))() + ++ -- cannot close a coroutine while closing it ++ do ++ local co ++ co = coroutine.create( ++ function() ++ local x = func2close(function() ++ coroutine.close(co) -- try to close it again ++ end) ++ coroutine.yield(20) ++ end) ++ local st, msg = coroutine.resume(co) ++ assert(st and msg == 20) ++ st, msg = coroutine.close(co) ++ assert(not st and string.find(msg, "running coroutine")) ++ end ++ + -- to-be-closed variables in coroutines + local X + +@@ -158,6 +179,9 @@ do + assert(not st and msg == 100) + st, msg = coroutine.close(co) + assert(not st and msg == 100) ++ -- after closing, no more errors ++ st, msg = coroutine.close(co) ++ assert(st and msg == nil) + + co = coroutine.create(function () + local x = func2close(function (self, err) +@@ -189,6 +213,9 @@ do + local st, msg = coroutine.close(co) + assert(st == false and coroutine.status(co) == "dead" and msg == 200) + assert(x == 200) ++ -- after closing, no more errors ++ st, msg = coroutine.close(co) ++ assert(st and msg == nil) + end + + do +@@ -419,7 +446,7 @@ do + + local X = false + A = coroutine.wrap(function() +- local _ = setmetatable({}, {__close = function () X = true end}) ++ local _ = func2close(function () X = true end) + return pcall(A, 1) + end) + st, res = A() +@@ -427,6 +454,22 @@ do + end + + ++-- bug in 5.4.1 ++do ++ -- coroutine ran close metamethods with invalid status during a ++ -- reset. ++ local co ++ co = coroutine.wrap(function() ++ local x = func2close(function() return pcall(co) end) ++ error(111) ++ end) ++ local st, errobj = pcall(co) ++ assert(not st and errobj == 111) ++ st, errobj = pcall(co) ++ assert(not st and string.find(errobj, "dead coroutine")) ++end ++ ++ + -- attempt to resume 'normal' coroutine + local co1, co2 + co1 = coroutine.create(function () return co2() end) +diff -up lua-5.4.3/src/lcorolib.c.bug8 lua-5.4.3/src/lcorolib.c +--- lua-5.4.3/src/lcorolib.c.bug8 2022-01-24 13:51:10.238031307 -0500 ++++ lua-5.4.3/src/lcorolib.c 2022-01-24 13:51:58.951312692 -0500 +@@ -78,7 +78,7 @@ static int luaB_auxwrap (lua_State *L) { + if (stat != LUA_OK && stat != LUA_YIELD) { /* error in the coroutine? */ + stat = lua_resetthread(co); /* close its tbc variables */ + lua_assert(stat != LUA_OK); +- lua_xmove(co, L, 1); /* copy error message */ ++ lua_xmove(co, L, 1); /* move error message to the caller */ + } + if (stat != LUA_ERRMEM && /* not a memory error and ... */ + lua_type(L, -1) == LUA_TSTRING) { /* ... error object is a string? */ +@@ -179,7 +179,7 @@ static int luaB_close (lua_State *L) { + } + else { + lua_pushboolean(L, 0); +- lua_xmove(co, L, 1); /* copy error message */ ++ lua_xmove(co, L, 1); /* move error message */ + return 2; + } + } +diff -up lua-5.4.3/src/lstate.c.bug8 lua-5.4.3/src/lstate.c +--- lua-5.4.3/src/lstate.c.bug8 2022-01-24 13:52:07.581362543 -0500 ++++ lua-5.4.3/src/lstate.c 2022-01-24 13:52:40.932555194 -0500 +@@ -166,7 +166,7 @@ void luaE_checkcstack (lua_State *L) { + if (getCcalls(L) == LUAI_MAXCCALLS) + luaG_runerror(L, "C stack overflow"); + else if (getCcalls(L) >= (LUAI_MAXCCALLS / 10 * 11)) +- luaD_throw(L, LUA_ERRERR); /* error while handing stack error */ ++ luaD_throw(L, LUA_ERRERR); /* error while handling stack error */ + } + + +@@ -331,13 +331,13 @@ int luaE_resetthread (lua_State *L, int + ci->callstatus = CIST_C; + if (status == LUA_YIELD) + status = LUA_OK; ++ L->status = LUA_OK; /* so it can run __close metamethods */ + status = luaD_closeprotected(L, 1, status); + if (status != LUA_OK) /* errors? */ + luaD_seterrorobj(L, status, L->stack + 1); + else + L->top = L->stack + 1; + ci->top = L->top + LUA_MINSTACK; +- L->status = cast_byte(status); + luaD_reallocstack(L, cast_int(ci->top - L->stack), 0); + return status; + } diff --git a/lua.spec b/lua.spec index 641894f..4bc243f 100644 --- a/lua.spec +++ b/lua.spec @@ -14,7 +14,7 @@ Name: lua Version: %{major_version}.3 -Release: 3%{?dist} +Release: 4%{?dist} Summary: Powerful light-weight programming language License: MIT URL: http://www.lua.org/ @@ -36,9 +36,18 @@ Patch4: %{name}-5.3.0-configure-compat-module.patch Patch5: %{name}-5.3.0-autotoolize.patch Patch6: %{name}-5.3.5-luac-shared-link-fix.patch %endif +# This is also bug 9 +Patch7: %{name}-5.4.3-CVE-2021-44647.patch + # https://www.lua.org/bugs.html Patch18: %{name}-5.3.5-CVE-2020-24370.patch Patch19: %{name}-5.4.3-bug3.patch +Patch20: %{name}-5.4.3-bug4.patch +Patch21: %{name}-5.4.3-bug5.patch +Patch22: %{name}-5.4.3-bug6.patch +Patch23: %{name}-5.4.3-bug7.patch +Patch24: %{name}-5.4.3-bug8.patch +Patch25: %{name}-5.4.3-bug10.patch BuildRequires: automake autoconf libtool readline-devel ncurses-devel BuildRequires: make @@ -93,9 +102,16 @@ mv src/luaconf.h src/luaconf.h.template.in #%% patch2 -p1 -z .luac-shared %patch3 -p1 -z .configure-linux %patch4 -p1 -z .configure-compat-all +%patch7 -p1 -b .CVE-2021-44647 # Put proper version in configure.ac, patch0 hardcodes 5.3.0 sed -i 's|5.3.0|%{version}|g' configure.ac %patch19 -p1 -b .bug3 +%patch20 -p1 -b .bug4 +%patch21 -p1 -b .bug5 +%patch22 -p1 -b .bug6 +%patch23 -p1 -b .bug7 +%patch24 -p1 -b .bug8 +%patch25 -p1 -b .bug10 autoreconf -ifv %if 0%{?bootstrap} @@ -211,6 +227,10 @@ popd %{_libdir}/*.a %changelog +* Mon Jan 24 2022 Tom Callaway - 5.4.3-4 +- apply upstream fix for CVE-2021-44647 +- apply upstream fixes for known lua bugs 4-10 (11 assumes other changes beyond 5.4.3) + * Thu Jan 20 2022 Fedora Release Engineering - 5.4.3-3 - Rebuilt for https://fedoraproject.org/wiki/Fedora_36_Mass_Rebuild