From 45684b5e2a64fe37e5b2b4639f8ade43cd892d7f Mon Sep 17 00:00:00 2001 From: Daniel McIlvaney Date: Thu, 1 Oct 2020 13:09:37 -0700 Subject: [PATCH 1/2] Patch lua CVE-2019-6706, CVE-2020-15888, CVE-2020-15945, nopatch CVE-2020-24342 Signed-off-by: Daniel McIlvaney --- ...-6706-use-after-free-lua_upvaluejoin.patch | 22 +++ SPECS/lua/CVE-2020-15888.patch | 34 ++++ SPECS/lua/CVE-2020-15889.nopatch | 4 +- SPECS/lua/CVE-2020-15945.patch | 166 ++++++++++++++++++ SPECS/lua/CVE-2020-24342.nopatch | 3 + SPECS/lua/lua.spec | 30 +++- .../manifests/package/pkggen_core_aarch64.txt | 2 +- .../manifests/package/pkggen_core_x86_64.txt | 2 +- .../manifests/package/toolchain_aarch64.txt | 6 +- .../manifests/package/toolchain_x86_64.txt | 6 +- 10 files changed, 264 insertions(+), 11 deletions(-) create mode 100644 SPECS/lua/CVE-2019-6706-use-after-free-lua_upvaluejoin.patch create mode 100644 SPECS/lua/CVE-2020-15888.patch create mode 100644 SPECS/lua/CVE-2020-15945.patch create mode 100644 SPECS/lua/CVE-2020-24342.nopatch diff --git a/SPECS/lua/CVE-2019-6706-use-after-free-lua_upvaluejoin.patch b/SPECS/lua/CVE-2019-6706-use-after-free-lua_upvaluejoin.patch new file mode 100644 index 00000000000..89e81b7eb68 --- /dev/null +++ b/SPECS/lua/CVE-2019-6706-use-after-free-lua_upvaluejoin.patch @@ -0,0 +1,22 @@ +--- a/src/lapi.c ++++ b/src/lapi.c +@@ -1285,14 +1285,14 @@ LUA_API void *lua_upvalueid (lua_State * + + LUA_API void lua_upvaluejoin (lua_State *L, int fidx1, int n1, + int fidx2, int n2) { +- LClosure *f1; +- UpVal **up1 = getupvalref(L, fidx1, n1, &f1); ++ UpVal **up1 = getupvalref(L, fidx1, n1, NULL); /* the last parameter not needed */ + UpVal **up2 = getupvalref(L, fidx2, n2, NULL); ++ if (*up1 == *up2) return; /* Already joined */ ++ (*up2)->refcount++; ++ if (upisopen(*up2)) (*up2)->u.open.touched = 1; ++ luaC_upvalbarrier(L, *up2); + luaC_upvdeccount(L, *up1); + *up1 = *up2; +- (*up1)->refcount++; +- if (upisopen(*up1)) (*up1)->u.open.touched = 1; +- luaC_upvalbarrier(L, *up1); + } + + diff --git a/SPECS/lua/CVE-2020-15888.patch b/SPECS/lua/CVE-2020-15888.patch new file mode 100644 index 00000000000..eb8a6af2ebb --- /dev/null +++ b/SPECS/lua/CVE-2020-15888.patch @@ -0,0 +1,34 @@ +From 6298903e35217ab69c279056f925fb72900ce0b7 Mon Sep 17 00:00:00 2001 +From: Roberto Ierusalimschy +Date: Mon, 6 Jul 2020 12:11:54 -0300 +Subject: [PATCH] Keep minimum size when shrinking a stack + +When shrinking a stack (during GC), do not make it smaller than the +initial stack size. +--- + src/ldo.c | 5 ++--- + 1 file changed, 2 insertions(+), 3 deletions(-) + +diff --git a/ldo.c b/ldo.c +index c563b1d9..a89ac010 100644 +--- a/src/ldo.c ++++ b/src/ldo.c +@@ -220,7 +220,7 @@ static int stackinuse (lua_State *L) { + + void luaD_shrinkstack (lua_State *L) { + int inuse = stackinuse(L); +- int goodsize = inuse + (inuse / 8) + 2*EXTRA_STACK; ++ int goodsize = inuse + BASIC_STACK_SIZE; + if (goodsize > LUAI_MAXSTACK) + goodsize = LUAI_MAXSTACK; /* respect stack limit */ + if (L->stacksize > LUAI_MAXSTACK) /* had been handling stack overflow? */ +@@ -229,8 +229,7 @@ void luaD_shrinkstack (lua_State *L) { + luaE_shrinkCI(L); /* shrink list */ + /* if thread is currently not handling a stack overflow and its + good size is smaller than current size, shrink its stack */ +- if (inuse <= (LUAI_MAXSTACK - EXTRA_STACK) && +- goodsize < L->stacksize) ++ if (inuse <= (LUAI_MAXSTACK - EXTRA_STACK) && goodsize < L->stacksize) + luaD_reallocstack(L, goodsize); + else /* don't change stack */ + condmovestack(L,{},{}); /* (change only for debugging) */ diff --git a/SPECS/lua/CVE-2020-15889.nopatch b/SPECS/lua/CVE-2020-15889.nopatch index 1948f0f20a2..650866c7522 100644 --- a/SPECS/lua/CVE-2020-15889.nopatch +++ b/SPECS/lua/CVE-2020-15889.nopatch @@ -1 +1,3 @@ -# CVE-2020-15889 is in the Lua generational garbage collection code, which is new to 5.4.0. 5.3.5 is not affected. \ No newline at end of file +# CVE-2020-15889 is in the Lua generational garbage collection code, which is new to 5.4.0. 5.3.5 is not affected. +# NOTE: Patches needed if updating to 5.4: +# - 127e7a6c8942b362aa3c6627f44d660a4fb75312 \ No newline at end of file diff --git a/SPECS/lua/CVE-2020-15945.patch b/SPECS/lua/CVE-2020-15945.patch new file mode 100644 index 00000000000..0f85f93c77b --- /dev/null +++ b/SPECS/lua/CVE-2020-15945.patch @@ -0,0 +1,166 @@ +From d8d344365945a534f700c82c5dd26f704f89fef3 Mon Sep 17 00:00:00 2001 +From: Roberto Ierusalimschy +Date: Wed, 5 Aug 2020 16:59:58 +0800 +Subject: [PATCH] Fixed bug: invalid 'oldpc' when returning to a function + +The field 'L->oldpc' is not always updated when control returns to a +function; an invalid value can seg. fault when computing 'changedline'. +(One example is an error in a finalizer; control can return to +'luaV_execute' without executing 'luaD_poscall'.) Instead of trying to +fix all possible corner cases, it seems safer to be resilient to invalid +values for 'oldpc'. Valid but wrong values at most cause an extra call +to a line hook. + +CVE: CVE-2020-15945 + +[Adjust the code to be applicable to the tree] + +Upstream-Status: Backport [https://github.com/lua/lua/commit/a2195644d89812e5b157ce7bac35543e06db05e3] + +Signed-off-by: Wenlin Kang +Signed-off-by: Joe Slater + +--- + src/ldebug.c | 30 +++++++++++++++--------------- + src/ldebug.h | 4 ++++ + src/ldo.c | 2 +- + src/lstate.c | 1 + + src/lstate.h | 2 +- + 5 files changed, 22 insertions(+), 17 deletions(-) + +diff --git a/src/ldebug.c b/src/ldebug.c +index 239affb..832b16c 100644 +--- a/src/ldebug.c ++++ b/src/ldebug.c +@@ -34,9 +34,8 @@ + #define noLuaClosure(f) ((f) == NULL || (f)->c.tt == LUA_TCCL) + + +-/* Active Lua function (given call info) */ +-#define ci_func(ci) (clLvalue((ci)->func)) +- ++/* inverse of 'pcRel' */ ++#define invpcRel(pc, p) ((p)->code + (pc) + 1) + + static const char *funcnamefromcode (lua_State *L, CallInfo *ci, + const char **name); +@@ -71,20 +70,18 @@ static void swapextra (lua_State *L) { + + /* + ** This function can be called asynchronously (e.g. during a signal). +-** Fields 'oldpc', 'basehookcount', and 'hookcount' (set by +-** 'resethookcount') are for debug only, and it is no problem if they +-** get arbitrary values (causes at most one wrong hook call). 'hookmask' +-** is an atomic value. We assume that pointers are atomic too (e.g., gcc +-** ensures that for all platforms where it runs). Moreover, 'hook' is +-** always checked before being called (see 'luaD_hook'). ++** Fields 'basehookcount' and 'hookcount' (set by 'resethookcount') ++** are for debug only, and it is no problem if they get arbitrary ++** values (causes at most one wrong hook call). 'hookmask' is an atomic ++** value. We assume that pointers are atomic too (e.g., gcc ensures that ++** for all platforms where it runs). Moreover, 'hook' is always checked ++** before being called (see 'luaD_hook'). + */ + LUA_API void lua_sethook (lua_State *L, lua_Hook func, int mask, int count) { + if (func == NULL || mask == 0) { /* turn off hooks? */ + mask = 0; + func = NULL; + } +- if (isLua(L->ci)) +- L->oldpc = L->ci->u.l.savedpc; + L->hook = func; + L->basehookcount = count; + resethookcount(L); +@@ -665,7 +662,10 @@ l_noret luaG_runerror (lua_State *L, const char *fmt, ...) { + void luaG_traceexec (lua_State *L) { + CallInfo *ci = L->ci; + lu_byte mask = L->hookmask; ++ const Proto *p = ci_func(ci)->p; + int counthook = (--L->hookcount == 0 && (mask & LUA_MASKCOUNT)); ++ /* 'L->oldpc' may be invalid; reset it in this case */ ++ int oldpc = (L->oldpc < p->sizecode) ? L->oldpc : 0; + if (counthook) + resethookcount(L); /* reset count */ + else if (!(mask & LUA_MASKLINE)) +@@ -677,15 +677,15 @@ void luaG_traceexec (lua_State *L) { + if (counthook) + luaD_hook(L, LUA_HOOKCOUNT, -1); /* call count hook */ + if (mask & LUA_MASKLINE) { +- Proto *p = ci_func(ci)->p; + int npc = pcRel(ci->u.l.savedpc, p); + int newline = getfuncline(p, npc); + if (npc == 0 || /* call linehook when enter a new function, */ +- ci->u.l.savedpc <= L->oldpc || /* when jump back (loop), or when */ +- newline != getfuncline(p, pcRel(L->oldpc, p))) /* enter a new line */ ++ ci->u.l.savedpc <= invpcRel(oldpc, p) || /* when jump back (loop), or when */ ++ newline != getfuncline(p, oldpc)) /* enter a new line */ + luaD_hook(L, LUA_HOOKLINE, newline); /* call line hook */ ++ ++ L->oldpc = npc; /* 'pc' of last call to line hook */ + } +- L->oldpc = ci->u.l.savedpc; + if (L->status == LUA_YIELD) { /* did hook yield? */ + if (counthook) + L->hookcount = 1; /* undo decrement to zero */ +diff --git a/src/ldebug.h b/src/ldebug.h +index 0e31546..c224cc4 100644 +--- a/src/ldebug.h ++++ b/src/ldebug.h +@@ -13,6 +13,10 @@ + + #define pcRel(pc, p) (cast(int, (pc) - (p)->code) - 1) + ++/* Active Lua function (given call info) */ ++#define ci_func(ci) (clLvalue((ci)->func)) ++ ++ + #define getfuncline(f,pc) (((f)->lineinfo) ? (f)->lineinfo[pc] : -1) + + #define resethookcount(L) (L->hookcount = L->basehookcount) +diff --git a/src/ldo.c b/src/ldo.c +index 90b695f..f66ac1a 100644 +--- a/src/ldo.c ++++ b/src/ldo.c +@@ -382,7 +382,7 @@ int luaD_poscall (lua_State *L, CallInfo *ci, StkId firstResult, int nres) { + luaD_hook(L, LUA_HOOKRET, -1); + firstResult = restorestack(L, fr); + } +- L->oldpc = ci->previous->u.l.savedpc; /* 'oldpc' for caller function */ ++ L->oldpc = pcRel(ci->u.l.savedpc, ci_func(ci)->p); /* 'oldpc' for caller function */ + } + res = ci->func; /* res == final position of 1st result */ + L->ci = ci->previous; /* back to caller */ +diff --git a/src/lstate.c b/src/lstate.c +index 9194ac3..3573e36 100644 +--- a/src/lstate.c ++++ b/src/lstate.c +@@ -236,6 +236,7 @@ static void preinit_thread (lua_State *L, global_State *g) { + L->nny = 1; + L->status = LUA_OK; + L->errfunc = 0; ++ L->oldpc = 0; + } + + +diff --git a/src/lstate.h b/src/lstate.h +index a469466..d75eadf 100644 +--- a/src/lstate.h ++++ b/src/lstate.h +@@ -164,7 +164,6 @@ struct lua_State { + StkId top; /* first free slot in the stack */ + global_State *l_G; + CallInfo *ci; /* call info for current function */ +- const Instruction *oldpc; /* last pc traced */ + StkId stack_last; /* last free slot in the stack */ + StkId stack; /* stack base */ + UpVal *openupval; /* list of open upvalues in this stack */ +@@ -174,6 +173,7 @@ struct lua_State { + CallInfo base_ci; /* CallInfo for first level (C calling Lua) */ + volatile lua_Hook hook; + ptrdiff_t errfunc; /* current error handling function (stack index) */ ++ int oldpc; /* last pc traced */ + int stacksize; + int basehookcount; + int hookcount; +-- +2.13.3 diff --git a/SPECS/lua/CVE-2020-24342.nopatch b/SPECS/lua/CVE-2020-24342.nopatch new file mode 100644 index 00000000000..13c9a983442 --- /dev/null +++ b/SPECS/lua/CVE-2020-24342.nopatch @@ -0,0 +1,3 @@ +# CVE-2020-24342 appears to not affect 5.3.5 (no repro of exploit) +# NOTE: Patches needed if updating to 5.4: +# - 34affe7a63fc5d842580a9f23616d057e17dfe27 \ No newline at end of file diff --git a/SPECS/lua/lua.spec b/SPECS/lua/lua.spec index 5f1460ff2e6..5d55dc87e19 100644 --- a/SPECS/lua/lua.spec +++ b/SPECS/lua/lua.spec @@ -4,7 +4,7 @@ Summary: Programming language Name: lua Version: 5.3.5 -Release: 7%{?dist} +Release: 8%{?dist} License: MIT URL: https://www.lua.org Group: Development/Tools @@ -13,8 +13,26 @@ Distribution: Mariner Source0: https://www.lua.org/ftp/%{name}-%{version}.tar.gz Source1: %{LICENSE_PATH} Patch0: lua-5.3.4-shared_library-1.patch +# CVE-2020-15888 patch taken from Open Embedded's Lua meta layer https://github.com/openembedded/meta-openembedded/blob/master/meta-oe/recipes-devtools/lua/lua/CVE-2020-15888.patch +# NOTE: Upstream patches needed if updating to 5.4: +# - eb41999461b6f428186c55abd95f4ce1a76217d5 +# - 6298903e35217ab69c279056f925fb72900ce0b7 +Patch1: CVE-2020-15888.patch # CVE-2020-15889 is in the Lua generational garbage collection code, which is new to 5.4.0. 5.3.5 is not affected. -Patch1: CVE-2020-15889.nopatch +# NOTE: Patches needed if updating to 5.4: +# - 127e7a6c8942b362aa3c6627f44d660a4fb75312 +Patch2: CVE-2020-15889.nopatch +# CVE-2020-15945 patch taken from Open Embedded's Lua meta layer https://github.com/openembedded/meta-openembedded/blob/master/meta-oe/recipes-devtools/lua/lua/CVE-2020-15945.patch +# NOTE: Upstream patches needed if updating to 5.4: +# - a2195644d89812e5b157ce7bac35543e06db05e3 +Patch3: CVE-2020-15945.patch +# CVE-2020-24342 appears to not affect 5.3.5 (no repro of exploit) +# NOTE: Patches needed if updating to 5.4: +# - 34affe7a63fc5d842580a9f23616d057e17dfe27 +Patch4: CVE-2020-24342.nopatch +# From http://lua.2524044.n2.nabble.com/CVE-2019-6706-use-after-free-in-lua-upvaluejoin-function-tt7685575.html +Patch5: CVE-2019-6706-use-after-free-lua_upvaluejoin.patch + BuildRequires: readline-devel Requires: readline @@ -32,6 +50,9 @@ Static libraries and header files for the support library for lua %prep %setup -q %patch0 -p1 +%patch1 -p1 +%patch3 -p1 +%patch5 -p1 sed -i '/#define LUA_ROOT/s:/usr/local/:/usr/:' src/luaconf.h sed -i 's/CFLAGS= -fPIC -O2 /CFLAGS+= -fPIC -O2 -DLUA_COMPAT_MODULE /' src/Makefile cp %{SOURCE1} ./ @@ -93,6 +114,11 @@ rm -rf %{buildroot} %{_libdir}/liblua.so %changelog +* Thu Oct 01 2020 Daniel McIlvaney 5.3.5-8 +- Nopatch CVE-2020-24342 +- Apply patch for CVE-2019-6706 from Lua mailing list +- Apply patch for CVE-2020-15888 from Open Embedded +- Apply patch for CVE-2020-15945 from Open Embedded * Mon Sep 28 2020 Daniel McIlvaney 5.3.5-7 - Nopatch CVE-2020-15889 since it only affects 5.4.0 * Tue Aug 11 2020 Mateusz Malisz 5.3.5-6 diff --git a/toolkit/resources/manifests/package/pkggen_core_aarch64.txt b/toolkit/resources/manifests/package/pkggen_core_aarch64.txt index 511344b4958..a90b46a4f27 100644 --- a/toolkit/resources/manifests/package/pkggen_core_aarch64.txt +++ b/toolkit/resources/manifests/package/pkggen_core_aarch64.txt @@ -144,7 +144,7 @@ libltdl-2.4.6-5.cm1.aarch64.rpm libltdl-devel-2.4.6-5.cm1.aarch64.rpm pcre-libs-8.42-4.cm1.aarch64.rpm krb5-1.17-4.cm1.aarch64.rpm -lua-5.3.5-7.cm1.aarch64.rpm +lua-5.3.5-8.cm1.aarch64.rpm mariner-rpm-macros-1.0-3.cm1.noarch.rpm mariner-check-macros-1.0-3.cm1.noarch.rpm libassuan-2.5.1-3.cm1.aarch64.rpm diff --git a/toolkit/resources/manifests/package/pkggen_core_x86_64.txt b/toolkit/resources/manifests/package/pkggen_core_x86_64.txt index 6d20b92ace8..71ed15bee74 100644 --- a/toolkit/resources/manifests/package/pkggen_core_x86_64.txt +++ b/toolkit/resources/manifests/package/pkggen_core_x86_64.txt @@ -144,7 +144,7 @@ libltdl-2.4.6-5.cm1.x86_64.rpm libltdl-devel-2.4.6-5.cm1.x86_64.rpm pcre-libs-8.42-4.cm1.x86_64.rpm krb5-1.17-4.cm1.x86_64.rpm -lua-5.3.5-7.cm1.x86_64.rpm +lua-5.3.5-8.cm1.x86_64.rpm mariner-rpm-macros-1.0-3.cm1.noarch.rpm mariner-check-macros-1.0-3.cm1.noarch.rpm libassuan-2.5.1-3.cm1.x86_64.rpm diff --git a/toolkit/resources/manifests/package/toolchain_aarch64.txt b/toolkit/resources/manifests/package/toolchain_aarch64.txt index 7269c078c8e..995552dc9a3 100644 --- a/toolkit/resources/manifests/package/toolchain_aarch64.txt +++ b/toolkit/resources/manifests/package/toolchain_aarch64.txt @@ -225,9 +225,9 @@ libxml2-python-2.9.10-2.cm1.aarch64.rpm libxslt-1.1.34-2.cm1.aarch64.rpm libxslt-debuginfo-1.1.34-2.cm1.aarch64.rpm libxslt-devel-1.1.34-2.cm1.aarch64.rpm -lua-5.3.5-7.cm1.aarch64.rpm -lua-debuginfo-5.3.5-7.cm1.aarch64.rpm -lua-devel-5.3.5-7.cm1.aarch64.rpm +lua-5.3.5-8.cm1.aarch64.rpm +lua-debuginfo-5.3.5-8.cm1.aarch64.rpm +lua-devel-5.3.5-8.cm1.aarch64.rpm lvm2-2.03.05-5.cm1.aarch64.rpm lvm2-debuginfo-2.03.05-5.cm1.aarch64.rpm lvm2-devel-2.03.05-5.cm1.aarch64.rpm diff --git a/toolkit/resources/manifests/package/toolchain_x86_64.txt b/toolkit/resources/manifests/package/toolchain_x86_64.txt index 7ad095b5fbe..c722c2ceae7 100644 --- a/toolkit/resources/manifests/package/toolchain_x86_64.txt +++ b/toolkit/resources/manifests/package/toolchain_x86_64.txt @@ -225,9 +225,9 @@ libxml2-python-2.9.10-2.cm1.x86_64.rpm libxslt-1.1.34-2.cm1.x86_64.rpm libxslt-debuginfo-1.1.34-2.cm1.x86_64.rpm libxslt-devel-1.1.34-2.cm1.x86_64.rpm -lua-5.3.5-7.cm1.x86_64.rpm -lua-debuginfo-5.3.5-7.cm1.x86_64.rpm -lua-devel-5.3.5-7.cm1.x86_64.rpm +lua-5.3.5-8.cm1.x86_64.rpm +lua-debuginfo-5.3.5-8.cm1.x86_64.rpm +lua-devel-5.3.5-8.cm1.x86_64.rpm lvm2-2.03.05-5.cm1.x86_64.rpm lvm2-debuginfo-2.03.05-5.cm1.x86_64.rpm lvm2-devel-2.03.05-5.cm1.x86_64.rpm From e5384c4486a13b9afb43411176c336d77e8099f7 Mon Sep 17 00:00:00 2001 From: Daniel McIlvaney Date: Wed, 21 Oct 2020 12:20:18 -0700 Subject: [PATCH 2/2] Roll back CVE-2020-15945, patch ineffective Signed-off-by: Daniel McIlvaney --- SPECS/lua/CVE-2020-15945.patch | 166 --------------------------------- SPECS/lua/lua.spec | 12 +-- 2 files changed, 3 insertions(+), 175 deletions(-) delete mode 100644 SPECS/lua/CVE-2020-15945.patch diff --git a/SPECS/lua/CVE-2020-15945.patch b/SPECS/lua/CVE-2020-15945.patch deleted file mode 100644 index 0f85f93c77b..00000000000 --- a/SPECS/lua/CVE-2020-15945.patch +++ /dev/null @@ -1,166 +0,0 @@ -From d8d344365945a534f700c82c5dd26f704f89fef3 Mon Sep 17 00:00:00 2001 -From: Roberto Ierusalimschy -Date: Wed, 5 Aug 2020 16:59:58 +0800 -Subject: [PATCH] Fixed bug: invalid 'oldpc' when returning to a function - -The field 'L->oldpc' is not always updated when control returns to a -function; an invalid value can seg. fault when computing 'changedline'. -(One example is an error in a finalizer; control can return to -'luaV_execute' without executing 'luaD_poscall'.) Instead of trying to -fix all possible corner cases, it seems safer to be resilient to invalid -values for 'oldpc'. Valid but wrong values at most cause an extra call -to a line hook. - -CVE: CVE-2020-15945 - -[Adjust the code to be applicable to the tree] - -Upstream-Status: Backport [https://github.com/lua/lua/commit/a2195644d89812e5b157ce7bac35543e06db05e3] - -Signed-off-by: Wenlin Kang -Signed-off-by: Joe Slater - ---- - src/ldebug.c | 30 +++++++++++++++--------------- - src/ldebug.h | 4 ++++ - src/ldo.c | 2 +- - src/lstate.c | 1 + - src/lstate.h | 2 +- - 5 files changed, 22 insertions(+), 17 deletions(-) - -diff --git a/src/ldebug.c b/src/ldebug.c -index 239affb..832b16c 100644 ---- a/src/ldebug.c -+++ b/src/ldebug.c -@@ -34,9 +34,8 @@ - #define noLuaClosure(f) ((f) == NULL || (f)->c.tt == LUA_TCCL) - - --/* Active Lua function (given call info) */ --#define ci_func(ci) (clLvalue((ci)->func)) -- -+/* inverse of 'pcRel' */ -+#define invpcRel(pc, p) ((p)->code + (pc) + 1) - - static const char *funcnamefromcode (lua_State *L, CallInfo *ci, - const char **name); -@@ -71,20 +70,18 @@ static void swapextra (lua_State *L) { - - /* - ** This function can be called asynchronously (e.g. during a signal). --** Fields 'oldpc', 'basehookcount', and 'hookcount' (set by --** 'resethookcount') are for debug only, and it is no problem if they --** get arbitrary values (causes at most one wrong hook call). 'hookmask' --** is an atomic value. We assume that pointers are atomic too (e.g., gcc --** ensures that for all platforms where it runs). Moreover, 'hook' is --** always checked before being called (see 'luaD_hook'). -+** Fields 'basehookcount' and 'hookcount' (set by 'resethookcount') -+** are for debug only, and it is no problem if they get arbitrary -+** values (causes at most one wrong hook call). 'hookmask' is an atomic -+** value. We assume that pointers are atomic too (e.g., gcc ensures that -+** for all platforms where it runs). Moreover, 'hook' is always checked -+** before being called (see 'luaD_hook'). - */ - LUA_API void lua_sethook (lua_State *L, lua_Hook func, int mask, int count) { - if (func == NULL || mask == 0) { /* turn off hooks? */ - mask = 0; - func = NULL; - } -- if (isLua(L->ci)) -- L->oldpc = L->ci->u.l.savedpc; - L->hook = func; - L->basehookcount = count; - resethookcount(L); -@@ -665,7 +662,10 @@ l_noret luaG_runerror (lua_State *L, const char *fmt, ...) { - void luaG_traceexec (lua_State *L) { - CallInfo *ci = L->ci; - lu_byte mask = L->hookmask; -+ const Proto *p = ci_func(ci)->p; - int counthook = (--L->hookcount == 0 && (mask & LUA_MASKCOUNT)); -+ /* 'L->oldpc' may be invalid; reset it in this case */ -+ int oldpc = (L->oldpc < p->sizecode) ? L->oldpc : 0; - if (counthook) - resethookcount(L); /* reset count */ - else if (!(mask & LUA_MASKLINE)) -@@ -677,15 +677,15 @@ void luaG_traceexec (lua_State *L) { - if (counthook) - luaD_hook(L, LUA_HOOKCOUNT, -1); /* call count hook */ - if (mask & LUA_MASKLINE) { -- Proto *p = ci_func(ci)->p; - int npc = pcRel(ci->u.l.savedpc, p); - int newline = getfuncline(p, npc); - if (npc == 0 || /* call linehook when enter a new function, */ -- ci->u.l.savedpc <= L->oldpc || /* when jump back (loop), or when */ -- newline != getfuncline(p, pcRel(L->oldpc, p))) /* enter a new line */ -+ ci->u.l.savedpc <= invpcRel(oldpc, p) || /* when jump back (loop), or when */ -+ newline != getfuncline(p, oldpc)) /* enter a new line */ - luaD_hook(L, LUA_HOOKLINE, newline); /* call line hook */ -+ -+ L->oldpc = npc; /* 'pc' of last call to line hook */ - } -- L->oldpc = ci->u.l.savedpc; - if (L->status == LUA_YIELD) { /* did hook yield? */ - if (counthook) - L->hookcount = 1; /* undo decrement to zero */ -diff --git a/src/ldebug.h b/src/ldebug.h -index 0e31546..c224cc4 100644 ---- a/src/ldebug.h -+++ b/src/ldebug.h -@@ -13,6 +13,10 @@ - - #define pcRel(pc, p) (cast(int, (pc) - (p)->code) - 1) - -+/* Active Lua function (given call info) */ -+#define ci_func(ci) (clLvalue((ci)->func)) -+ -+ - #define getfuncline(f,pc) (((f)->lineinfo) ? (f)->lineinfo[pc] : -1) - - #define resethookcount(L) (L->hookcount = L->basehookcount) -diff --git a/src/ldo.c b/src/ldo.c -index 90b695f..f66ac1a 100644 ---- a/src/ldo.c -+++ b/src/ldo.c -@@ -382,7 +382,7 @@ int luaD_poscall (lua_State *L, CallInfo *ci, StkId firstResult, int nres) { - luaD_hook(L, LUA_HOOKRET, -1); - firstResult = restorestack(L, fr); - } -- L->oldpc = ci->previous->u.l.savedpc; /* 'oldpc' for caller function */ -+ L->oldpc = pcRel(ci->u.l.savedpc, ci_func(ci)->p); /* 'oldpc' for caller function */ - } - res = ci->func; /* res == final position of 1st result */ - L->ci = ci->previous; /* back to caller */ -diff --git a/src/lstate.c b/src/lstate.c -index 9194ac3..3573e36 100644 ---- a/src/lstate.c -+++ b/src/lstate.c -@@ -236,6 +236,7 @@ static void preinit_thread (lua_State *L, global_State *g) { - L->nny = 1; - L->status = LUA_OK; - L->errfunc = 0; -+ L->oldpc = 0; - } - - -diff --git a/src/lstate.h b/src/lstate.h -index a469466..d75eadf 100644 ---- a/src/lstate.h -+++ b/src/lstate.h -@@ -164,7 +164,6 @@ struct lua_State { - StkId top; /* first free slot in the stack */ - global_State *l_G; - CallInfo *ci; /* call info for current function */ -- const Instruction *oldpc; /* last pc traced */ - StkId stack_last; /* last free slot in the stack */ - StkId stack; /* stack base */ - UpVal *openupval; /* list of open upvalues in this stack */ -@@ -174,6 +173,7 @@ struct lua_State { - CallInfo base_ci; /* CallInfo for first level (C calling Lua) */ - volatile lua_Hook hook; - ptrdiff_t errfunc; /* current error handling function (stack index) */ -+ int oldpc; /* last pc traced */ - int stacksize; - int basehookcount; - int hookcount; --- -2.13.3 diff --git a/SPECS/lua/lua.spec b/SPECS/lua/lua.spec index 5d55dc87e19..67505fa2545 100644 --- a/SPECS/lua/lua.spec +++ b/SPECS/lua/lua.spec @@ -22,16 +22,12 @@ Patch1: CVE-2020-15888.patch # NOTE: Patches needed if updating to 5.4: # - 127e7a6c8942b362aa3c6627f44d660a4fb75312 Patch2: CVE-2020-15889.nopatch -# CVE-2020-15945 patch taken from Open Embedded's Lua meta layer https://github.com/openembedded/meta-openembedded/blob/master/meta-oe/recipes-devtools/lua/lua/CVE-2020-15945.patch -# NOTE: Upstream patches needed if updating to 5.4: -# - a2195644d89812e5b157ce7bac35543e06db05e3 -Patch3: CVE-2020-15945.patch # CVE-2020-24342 appears to not affect 5.3.5 (no repro of exploit) # NOTE: Patches needed if updating to 5.4: # - 34affe7a63fc5d842580a9f23616d057e17dfe27 -Patch4: CVE-2020-24342.nopatch +Patch3: CVE-2020-24342.nopatch # From http://lua.2524044.n2.nabble.com/CVE-2019-6706-use-after-free-in-lua-upvaluejoin-function-tt7685575.html -Patch5: CVE-2019-6706-use-after-free-lua_upvaluejoin.patch +Patch4: CVE-2019-6706-use-after-free-lua_upvaluejoin.patch BuildRequires: readline-devel Requires: readline @@ -51,8 +47,7 @@ Static libraries and header files for the support library for lua %setup -q %patch0 -p1 %patch1 -p1 -%patch3 -p1 -%patch5 -p1 +%patch4 -p1 sed -i '/#define LUA_ROOT/s:/usr/local/:/usr/:' src/luaconf.h sed -i 's/CFLAGS= -fPIC -O2 /CFLAGS+= -fPIC -O2 -DLUA_COMPAT_MODULE /' src/Makefile cp %{SOURCE1} ./ @@ -118,7 +113,6 @@ rm -rf %{buildroot} - Nopatch CVE-2020-24342 - Apply patch for CVE-2019-6706 from Lua mailing list - Apply patch for CVE-2020-15888 from Open Embedded -- Apply patch for CVE-2020-15945 from Open Embedded * Mon Sep 28 2020 Daniel McIlvaney 5.3.5-7 - Nopatch CVE-2020-15889 since it only affects 5.4.0 * Tue Aug 11 2020 Mateusz Malisz 5.3.5-6