| 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++; |