diff --git a/lua-5.3.5-CVE-2020-24370.patch b/lua-5.3.5-CVE-2020-24370.patch new file mode 100644 index 0000000..5f3668b --- /dev/null +++ b/lua-5.3.5-CVE-2020-24370.patch @@ -0,0 +1,26 @@ +diff -up lua-5.3.5/src/ldebug.c.CVE-2020-24370 lua-5.3.5/src/ldebug.c +--- lua-5.3.5/src/ldebug.c.CVE-2020-24370 2020-08-19 13:37:17.075859557 -0400 ++++ lua-5.3.5/src/ldebug.c 2020-08-19 13:38:53.117779244 -0400 +@@ -133,10 +133,11 @@ static const char *upvalname (Proto *p, + + static const char *findvararg (CallInfo *ci, int n, StkId *pos) { + int nparams = clLvalue(ci->func)->p->numparams; +- if (n >= cast_int(ci->u.l.base - ci->func) - nparams) ++ int nvararg = cast_int(ci->u.l.base - ci->func) - nparams; ++ if (n <= -nvararg) + return NULL; /* no such vararg */ + else { +- *pos = ci->func + nparams + n; ++ *pos = ci->func + nparams - n; + return "(*vararg)"; /* generic name for any vararg */ + } + } +@@ -148,7 +149,7 @@ static const char *findlocal (lua_State + StkId base; + if (isLua(ci)) { + if (n < 0) /* access to vararg values? */ +- return findvararg(ci, -n, pos); ++ return findvararg(ci, n, pos); + else { + base = ci->u.l.base; + name = luaF_getlocalname(ci_func(ci)->p, n, currentpc(ci)); diff --git a/lua-5.4.0-CVE-2020-24370.patch b/lua-5.4.0-CVE-2020-24370.patch new file mode 100644 index 0000000..b707aa0 --- /dev/null +++ b/lua-5.4.0-CVE-2020-24370.patch @@ -0,0 +1,23 @@ +diff -up lua-5.4.0/src/ldebug.c.CVE-2020-24370 lua-5.4.0/src/ldebug.c +--- lua-5.4.0/src/ldebug.c.CVE-2020-24370 2020-08-19 13:25:29.295135397 -0400 ++++ lua-5.4.0/src/ldebug.c 2020-08-19 13:25:35.012135113 -0400 +@@ -188,8 +188,8 @@ static const char *upvalname (const Prot + static const char *findvararg (CallInfo *ci, int n, StkId *pos) { + if (clLvalue(s2v(ci->func))->p->is_vararg) { + int nextra = ci->u.l.nextraargs; +- if (n <= nextra) { +- *pos = ci->func - nextra + (n - 1); ++ if (n >= -nextra) { /* 'n' is negative */ ++ *pos = ci->func - nextra - (n + 1); + return "(vararg)"; /* generic name for any vararg */ + } + } +@@ -202,7 +202,7 @@ const char *luaG_findlocal (lua_State *L + const char *name = NULL; + if (isLua(ci)) { + if (n < 0) /* access to vararg values? */ +- return findvararg(ci, -n, pos); ++ return findvararg(ci, n, pos); + else + name = luaF_getlocalname(ci_func(ci)->p, n, currentpc(ci)); + } diff --git a/lua-5.4.0-CVE-2020-24371.patch b/lua-5.4.0-CVE-2020-24371.patch new file mode 100644 index 0000000..3f102e0 --- /dev/null +++ b/lua-5.4.0-CVE-2020-24371.patch @@ -0,0 +1,117 @@ +diff -up lua-5.4.0/src/lgc.c.CVE-2020-24371 lua-5.4.0/src/lgc.c +--- lua-5.4.0/src/lgc.c.CVE-2020-24371 2020-08-19 13:29:50.766122493 -0400 ++++ lua-5.4.0/src/lgc.c 2020-08-19 13:34:31.886997668 -0400 +@@ -181,14 +181,17 @@ static int iscleared (global_State *g, c + + + /* +-** barrier that moves collector forward, that is, mark the white object +-** 'v' being pointed by the black object 'o'. (If in sweep phase, clear +-** the black object to white [sweep it] to avoid other barrier calls for +-** this same object.) In the generational mode, 'v' must also become +-** old, if 'o' is old; however, it cannot be changed directly to OLD, +-** because it may still point to non-old objects. So, it is marked as +-** OLD0. In the next cycle it will become OLD1, and in the next it +-** will finally become OLD (regular old). ++** Barrier that moves collector forward, that is, marks the white object ++** 'v' being pointed by the black object 'o'. In the generational ++** mode, 'v' must also become old, if 'o' is old; however, it cannot ++** be changed directly to OLD, because it may still point to non-old ++** objects. So, it is marked as OLD0. In the next cycle it will become ++** OLD1, and in the next it will finally become OLD (regular old). By ++** then, any object it points to will also be old. If called in the ++** incremental sweep phase, it clears the black object to white (sweep ++** it) to avoid other barrier calls for this same object. (That cannot ++** be done is generational mode, as its sweep does not distinguish ++** whites from deads.) + */ + void luaC_barrier_ (lua_State *L, GCObject *o, GCObject *v) { + global_State *g = G(L); +@@ -202,7 +205,8 @@ void luaC_barrier_ (lua_State *L, GCObje + } + else { /* sweep phase */ + lua_assert(issweepphase(g)); +- makewhite(g, o); /* mark main obj. as white to avoid other barriers */ ++ if (g->gckind == KGC_INC) /* incremental mode? */ ++ makewhite(g, o); /* mark 'o' as white to avoid other barriers */ + } + } + +@@ -324,10 +328,15 @@ static lu_mem markbeingfnz (global_State + + + /* +-** Mark all values stored in marked open upvalues from non-marked threads. +-** (Values from marked threads were already marked when traversing the +-** thread.) Remove from the list threads that no longer have upvalues and +-** not-marked threads. ++** For each non-marked thread, simulates a barrier between each open ++** upvalue and its value. (If the thread is collected, the value will be ++** assigned to the upvalue, but then it can be too late for the barrier ++** to act. The "barrier" does not need to check colors: A non-marked ++** thread must be young; upvalues cannot be older than their threads; so ++** any visited upvalue must be young too.) Also removes the thread from ++** the list, as it was already visited. Removes also threads with no ++** upvalues, as they have nothing to be checked. (If the thread gets an ++** upvalue later, it will be linked in the list again.) + */ + static int remarkupvals (global_State *g) { + lua_State *thread; +@@ -340,9 +349,11 @@ static int remarkupvals (global_State *g + p = &thread->twups; /* keep marked thread with upvalues in the list */ + else { /* thread is not marked or without upvalues */ + UpVal *uv; ++ lua_assert(!isold(thread) || thread->openupval == NULL); + *p = thread->twups; /* remove thread from the list */ + thread->twups = thread; /* mark that it is out of list */ + for (uv = thread->openupval; uv != NULL; uv = uv->u.open.next) { ++ lua_assert(getage(uv) <= getage(thread)); + work++; + if (!iswhite(uv)) /* upvalue already visited? */ + markvalue(g, uv->v); /* mark its value */ +@@ -997,6 +1008,9 @@ static void sweep2old (lua_State *L, GCO + ** during the sweep. So, any white object must be dead.) For + ** non-dead objects, advance their ages and clear the color of + ** new objects. (Old objects keep their colors.) ++** The ages of G_TOUCHED1 and G_TOUCHED2 objects will advance ++** in 'correctgraylist'. (That function will also remove objects ++** turned white here from any gray list.) + */ + static GCObject **sweepgen (lua_State *L, global_State *g, GCObject **p, + GCObject *limit) { +@@ -1057,16 +1071,16 @@ static GCObject **correctgraylist (GCObj + lua_assert(isgray(curr)); + gray2black(curr); /* make it black, for next barrier */ + changeage(curr, G_TOUCHED1, G_TOUCHED2); +- p = next; /* go to next element */ ++ p = next; /* keep it in the list and go to next element */ + } +- else { /* not touched in this cycle */ ++ else { /* everything else is removed */ ++ /* white objects are simply removed */ + if (!iswhite(curr)) { /* not white? */ + lua_assert(isold(curr)); + if (getage(curr) == G_TOUCHED2) /* advance from G_TOUCHED2... */ + changeage(curr, G_TOUCHED2, G_OLD); /* ... to G_OLD */ + gray2black(curr); /* make it black */ + } +- /* else, object is white: just remove it from this list */ + *p = *next; /* remove 'curr' from gray list */ + } + break; +@@ -1145,6 +1159,7 @@ static void youngcollection (lua_State * + atomic(L); + + /* sweep nursery and get a pointer to its last live element */ ++ g->gcstate = GCSswpallgc; + psurvival = sweepgen(L, g, &g->allgc, g->survival); + /* sweep 'survival' and 'old' */ + sweepgen(L, g, psurvival, g->reallyold); +@@ -1168,6 +1183,7 @@ static void youngcollection (lua_State * + + static void atomic2gen (lua_State *L, global_State *g) { + /* sweep all elements making them old */ ++ g->gcstate = GCSswpallgc; + sweep2old(L, &g->allgc); + /* everything alive now is old */ + g->reallyold = g->old = g->survival = g->allgc; diff --git a/lua.spec b/lua.spec index b11d7b4..be9d603 100644 --- a/lua.spec +++ b/lua.spec @@ -15,7 +15,7 @@ Name: lua Version: %{major_version}.0 -Release: 5%{?dist} +Release: 6%{?dist} Summary: Powerful light-weight programming language License: MIT URL: http://www.lua.org/ @@ -54,6 +54,11 @@ Patch14: %{name}-5.4.0-bug7.patch Patch15: %{name}-5.4.0-bug8.patch # This is bug 12. Patch16: %{name}-5.4.0-CVE-2020-24369.patch +# This is bug 11 +Patch17: %{name}-5.4.0-CVE-2020-24370.patch +Patch18: %{name}-5.3.5-CVE-2020-24370.patch +# This is bug 9 +Patch19: %{name}-5.4.0-CVE-2020-24371.patch BuildRequires: automake autoconf libtool readline-devel ncurses-devel Requires: lua-libs = %{version}-%{release} @@ -114,6 +119,8 @@ mv src/luaconf.h src/luaconf.h.template.in %patch14 -p1 -b .bug7 %patch15 -p1 -b .bug8 %patch16 -p1 -b .CVE-2020-24369 +%patch17 -p1 -b .CVE-2020-24370 +%patch19 -p1 -b .CVE-2020-24371 # Put proper version in configure.ac, patch0 hardcodes 5.3.0 sed -i 's|5.3.0|%{version}|g' configure.ac autoreconf -ifv @@ -126,6 +133,7 @@ mv src/luaconf.h src/luaconf.h.template.in %patch3 -p1 -z .configure-linux %patch4 -p1 -z .configure-compat-all %patch6 -p1 -b .luac-shared-link-fix +%patch18 -p1 -b .CVE-2020-24370 autoreconf -i cd .. %endif @@ -238,6 +246,9 @@ install -Dpm 0644 %{SOURCE1001} $RPM_BUILD_ROOT/%{_fileattrsdir}/lua.attr %{_libdir}/*.a %changelog +* Wed Aug 19 2020 Tom Callaway - 5.4.0-6 +- apply upstream fix for CVE-2020-24370, CVE-2020-24371 + * Wed Aug 19 2020 Tom Callaway - 5.4.0-5 - apply upstream fix for CVE-2020-24369