52 lines
1.7 KiB
Diff
52 lines
1.7 KiB
Diff
From 89aee84cbc9224f638f3b7951b306d2ee8ecb71e Mon Sep 17 00:00:00 2001
|
|
From: Roberto Ierusalimschy <roberto@inf.puc-rio.br>
|
|
Date: Wed, 27 Mar 2019 14:30:12 -0300
|
|
Subject: [PATCH] Fixed bug in 'lua_upvaluejoin'
|
|
|
|
Bug-fix: joining an upvalue with itself could cause a use-after-free
|
|
crash.
|
|
---
|
|
src/lapi.c | 12 +++++------
|
|
1 file changed, 41 insertions(+), 39 deletions(-)
|
|
|
|
--- a/src/lapi.c
|
|
+++ b/src/lapi.c
|
|
@@ -1254,13 +1254,12 @@ LUA_API const char *lua_setupvalue (lua_
|
|
}
|
|
|
|
|
|
-static UpVal **getupvalref (lua_State *L, int fidx, int n, LClosure **pf) {
|
|
+static UpVal **getupvalref (lua_State *L, int fidx, int n) {
|
|
LClosure *f;
|
|
StkId fi = index2addr(L, fidx);
|
|
api_check(L, ttisLclosure(fi), "Lua function expected");
|
|
f = clLvalue(fi);
|
|
api_check(L, (1 <= n && n <= f->p->sizeupvalues), "invalid upvalue index");
|
|
- if (pf) *pf = f;
|
|
return &f->upvals[n - 1]; /* get its upvalue pointer */
|
|
}
|
|
|
|
@@ -1269,7 +1268,7 @@ LUA_API void *lua_upvalueid (lua_State *
|
|
StkId fi = index2addr(L, fidx);
|
|
switch (ttype(fi)) {
|
|
case LUA_TLCL: { /* lua closure */
|
|
- return *getupvalref(L, fidx, n, NULL);
|
|
+ return *getupvalref(L, fidx, n);
|
|
}
|
|
case LUA_TCCL: { /* C closure */
|
|
CClosure *f = clCvalue(fi);
|
|
@@ -1286,9 +1285,10 @@ 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 **up2 = getupvalref(L, fidx2, n2, NULL);
|
|
+ UpVal **up1 = getupvalref(L, fidx1, n1);
|
|
+ UpVal **up2 = getupvalref(L, fidx2, n2);
|
|
+ if (*up1 == *up2)
|
|
+ return;
|
|
luaC_upvdeccount(L, *up1);
|
|
*up1 = *up2;
|
|
(*up1)->refcount++;
|