summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWenlin Kang <wenlin.kang@windriver.com>2020-09-01 14:11:30 -0700
committerKhem Raj <raj.khem@gmail.com>2020-09-01 15:37:44 -0700
commit6c43941d116bbb9f0d62ca5376da24ae03eb9eab (patch)
tree6877c8832e1b772a64a7b7f71f391f2b719a04bf
parent43bd735121964ee4ad2b951f26988528338b1795 (diff)
downloadmeta-openembedded-6c43941d116bbb9f0d62ca5376da24ae03eb9eab.tar.gz
lua: fix CVE-2020-15945
Backport with modifications to apply successfully. Signed-off-by: Wenlin Kang <wenlin.kang@windriver.com> Signed-off-by: Joe Slater <joe.slater@windriver.com> Signed-off-by: Khem Raj <raj.khem@gmail.com>
-rw-r--r--meta-oe/recipes-devtools/lua/lua/CVE-2020-15945.patch167
-rw-r--r--meta-oe/recipes-devtools/lua/lua_5.3.5.bb1
2 files changed, 168 insertions, 0 deletions
diff --git a/meta-oe/recipes-devtools/lua/lua/CVE-2020-15945.patch b/meta-oe/recipes-devtools/lua/lua/CVE-2020-15945.patch
new file mode 100644
index 000000000..89ce49148
--- /dev/null
+++ b/meta-oe/recipes-devtools/lua/lua/CVE-2020-15945.patch
@@ -0,0 +1,167 @@
1From d8d344365945a534f700c82c5dd26f704f89fef3 Mon Sep 17 00:00:00 2001
2From: Roberto Ierusalimschy <roberto@inf.puc-rio.br>
3Date: Wed, 5 Aug 2020 16:59:58 +0800
4Subject: [PATCH] Fixed bug: invalid 'oldpc' when returning to a function
5
6The field 'L->oldpc' is not always updated when control returns to a
7function; an invalid value can seg. fault when computing 'changedline'.
8(One example is an error in a finalizer; control can return to
9'luaV_execute' without executing 'luaD_poscall'.) Instead of trying to
10fix all possible corner cases, it seems safer to be resilient to invalid
11values for 'oldpc'. Valid but wrong values at most cause an extra call
12to a line hook.
13
14CVE: CVE-2020-15945
15
16[Adjust the code to be applicable to the tree]
17
18Upstream-Status: Backport [https://github.com/lua/lua/commit/a2195644d89812e5b157ce7bac35543e06db05e3]
19
20Signed-off-by: Wenlin Kang <wenlin.kang@windriver.com>
21Signed-off-by: Joe Slater <joe.slater@@windriver.com>
22
23---
24 src/ldebug.c | 30 +++++++++++++++---------------
25 src/ldebug.h | 4 ++++
26 src/ldo.c | 2 +-
27 src/lstate.c | 1 +
28 src/lstate.h | 2 +-
29 5 files changed, 22 insertions(+), 17 deletions(-)
30
31diff --git a/src/ldebug.c b/src/ldebug.c
32index 239affb..832b16c 100644
33--- a/src/ldebug.c
34+++ b/src/ldebug.c
35@@ -34,9 +34,8 @@
36 #define noLuaClosure(f) ((f) == NULL || (f)->c.tt == LUA_TCCL)
37
38
39-/* Active Lua function (given call info) */
40-#define ci_func(ci) (clLvalue((ci)->func))
41-
42+/* inverse of 'pcRel' */
43+#define invpcRel(pc, p) ((p)->code + (pc) + 1)
44
45 static const char *funcnamefromcode (lua_State *L, CallInfo *ci,
46 const char **name);
47@@ -71,20 +70,18 @@ static void swapextra (lua_State *L) {
48
49 /*
50 ** This function can be called asynchronously (e.g. during a signal).
51-** Fields 'oldpc', 'basehookcount', and 'hookcount' (set by
52-** 'resethookcount') are for debug only, and it is no problem if they
53-** get arbitrary values (causes at most one wrong hook call). 'hookmask'
54-** is an atomic value. We assume that pointers are atomic too (e.g., gcc
55-** ensures that for all platforms where it runs). Moreover, 'hook' is
56-** always checked before being called (see 'luaD_hook').
57+** Fields 'basehookcount' and 'hookcount' (set by 'resethookcount')
58+** are for debug only, and it is no problem if they get arbitrary
59+** values (causes at most one wrong hook call). 'hookmask' is an atomic
60+** value. We assume that pointers are atomic too (e.g., gcc ensures that
61+** for all platforms where it runs). Moreover, 'hook' is always checked
62+** before being called (see 'luaD_hook').
63 */
64 LUA_API void lua_sethook (lua_State *L, lua_Hook func, int mask, int count) {
65 if (func == NULL || mask == 0) { /* turn off hooks? */
66 mask = 0;
67 func = NULL;
68 }
69- if (isLua(L->ci))
70- L->oldpc = L->ci->u.l.savedpc;
71 L->hook = func;
72 L->basehookcount = count;
73 resethookcount(L);
74@@ -665,7 +662,10 @@ l_noret luaG_runerror (lua_State *L, const char *fmt, ...) {
75 void luaG_traceexec (lua_State *L) {
76 CallInfo *ci = L->ci;
77 lu_byte mask = L->hookmask;
78+ const Proto *p = ci_func(ci)->p;
79 int counthook = (--L->hookcount == 0 && (mask & LUA_MASKCOUNT));
80+ /* 'L->oldpc' may be invalid; reset it in this case */
81+ int oldpc = (L->oldpc < p->sizecode) ? L->oldpc : 0;
82 if (counthook)
83 resethookcount(L); /* reset count */
84 else if (!(mask & LUA_MASKLINE))
85@@ -677,15 +677,15 @@ void luaG_traceexec (lua_State *L) {
86 if (counthook)
87 luaD_hook(L, LUA_HOOKCOUNT, -1); /* call count hook */
88 if (mask & LUA_MASKLINE) {
89- Proto *p = ci_func(ci)->p;
90 int npc = pcRel(ci->u.l.savedpc, p);
91 int newline = getfuncline(p, npc);
92 if (npc == 0 || /* call linehook when enter a new function, */
93- ci->u.l.savedpc <= L->oldpc || /* when jump back (loop), or when */
94- newline != getfuncline(p, pcRel(L->oldpc, p))) /* enter a new line */
95+ ci->u.l.savedpc <= invpcRel(oldpc, p) || /* when jump back (loop), or when */
96+ newline != getfuncline(p, oldpc)) /* enter a new line */
97 luaD_hook(L, LUA_HOOKLINE, newline); /* call line hook */
98+
99+ L->oldpc = npc; /* 'pc' of last call to line hook */
100 }
101- L->oldpc = ci->u.l.savedpc;
102 if (L->status == LUA_YIELD) { /* did hook yield? */
103 if (counthook)
104 L->hookcount = 1; /* undo decrement to zero */
105diff --git a/src/ldebug.h b/src/ldebug.h
106index 0e31546..c224cc4 100644
107--- a/src/ldebug.h
108+++ b/src/ldebug.h
109@@ -13,6 +13,10 @@
110
111 #define pcRel(pc, p) (cast(int, (pc) - (p)->code) - 1)
112
113+/* Active Lua function (given call info) */
114+#define ci_func(ci) (clLvalue((ci)->func))
115+
116+
117 #define getfuncline(f,pc) (((f)->lineinfo) ? (f)->lineinfo[pc] : -1)
118
119 #define resethookcount(L) (L->hookcount = L->basehookcount)
120diff --git a/src/ldo.c b/src/ldo.c
121index 90b695f..f66ac1a 100644
122--- a/src/ldo.c
123+++ b/src/ldo.c
124@@ -382,7 +382,7 @@ int luaD_poscall (lua_State *L, CallInfo *ci, StkId firstResult, int nres) {
125 luaD_hook(L, LUA_HOOKRET, -1);
126 firstResult = restorestack(L, fr);
127 }
128- L->oldpc = ci->previous->u.l.savedpc; /* 'oldpc' for caller function */
129+ L->oldpc = pcRel(ci->u.l.savedpc, ci_func(ci)->p); /* 'oldpc' for caller function */
130 }
131 res = ci->func; /* res == final position of 1st result */
132 L->ci = ci->previous; /* back to caller */
133diff --git a/src/lstate.c b/src/lstate.c
134index 9194ac3..3573e36 100644
135--- a/src/lstate.c
136+++ b/src/lstate.c
137@@ -236,6 +236,7 @@ static void preinit_thread (lua_State *L, global_State *g) {
138 L->nny = 1;
139 L->status = LUA_OK;
140 L->errfunc = 0;
141+ L->oldpc = 0;
142 }
143
144
145diff --git a/src/lstate.h b/src/lstate.h
146index a469466..d75eadf 100644
147--- a/src/lstate.h
148+++ b/src/lstate.h
149@@ -164,7 +164,6 @@ struct lua_State {
150 StkId top; /* first free slot in the stack */
151 global_State *l_G;
152 CallInfo *ci; /* call info for current function */
153- const Instruction *oldpc; /* last pc traced */
154 StkId stack_last; /* last free slot in the stack */
155 StkId stack; /* stack base */
156 UpVal *openupval; /* list of open upvalues in this stack */
157@@ -174,6 +173,7 @@ struct lua_State {
158 CallInfo base_ci; /* CallInfo for first level (C calling Lua) */
159 volatile lua_Hook hook;
160 ptrdiff_t errfunc; /* current error handling function (stack index) */
161+ int oldpc; /* last pc traced */
162 int stacksize;
163 int basehookcount;
164 int hookcount;
165--
1662.13.3
167
diff --git a/meta-oe/recipes-devtools/lua/lua_5.3.5.bb b/meta-oe/recipes-devtools/lua/lua_5.3.5.bb
index d3461b06d..4f89579c7 100644
--- a/meta-oe/recipes-devtools/lua/lua_5.3.5.bb
+++ b/meta-oe/recipes-devtools/lua/lua_5.3.5.bb
@@ -8,6 +8,7 @@ SRC_URI = "http://www.lua.org/ftp/lua-${PV}.tar.gz;name=tarballsrc \
8 file://lua.pc.in \ 8 file://lua.pc.in \
9 file://0001-Allow-building-lua-without-readline-on-Linux.patch \ 9 file://0001-Allow-building-lua-without-readline-on-Linux.patch \
10 file://CVE-2020-15888.patch \ 10 file://CVE-2020-15888.patch \
11 file://CVE-2020-15945.patch \
11 " 12 "
12 13
13# if no test suite matches PV release of Lua exactly, download the suite for the closest Lua release. 14# if no test suite matches PV release of Lua exactly, download the suite for the closest Lua release.