diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2019-03-27 14:30:12 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2019-03-27 14:30:12 -0300 |
commit | 89aee84cbc9224f638f3b7951b306d2ee8ecb71e (patch) | |
tree | 12e1664dbc5a7a5b519c9971dbb0ec31289201e0 | |
parent | f059c2bcc8e0c99287657f953cca9ba730a5432a (diff) | |
download | lua-github-89aee84cbc9224f638f3b7951b306d2ee8ecb71e.tar.gz |
Fixed bug in 'lua_upvaluejoin'
Bug-fix: joining an upvalue with itself could cause a use-after-free
crash.
-rw-r--r-- | bugs | 64 | ||||
-rw-r--r-- | lapi.c | 12 | ||||
-rw-r--r-- | makefile | 4 |
3 files changed, 41 insertions, 39 deletions
@@ -357,7 +357,7 @@ co = coroutine.create(co_func) coroutine.resume(co) coroutine.resume(co) --> seg. fault ]], -report = [[by Alex Bilyk, 09/05/2003]], +report = [[by Alex Bilyk, 09/05/2003]], patch = [[ * ldo.c: 325,326c325 @@ -399,7 +399,7 @@ what = [[file:close cannot be called without a file. (results in seg fault)]], example = [[ > io.stdin.close() -- correct call shold be io.stdin:close() ]], -report = [[by Tuomo Valkonen, 27/05/2003]], +report = [[by Tuomo Valkonen, 27/05/2003]], patch = [[ * liolib.c: 161c161 @@ -1641,7 +1641,7 @@ what = [[debug.sethook/gethook may overflow the thread's stack]], report = [[Ivko Stanilov, on 2008/01/04]], since = [[5.1]], example = [[ -a = coroutine.create(function() yield() end) +a = coroutine.create(function() yield() end) coroutine.resume(a) debug.sethook(a) -- may overflow the stack of 'a' ]], @@ -2707,7 +2707,7 @@ local firsttime = true local function foo () if firsttime then firsttime = false - return "a = 1" + return "a = 1" else for i = 1, 10 do print(debug.getlocal(2, i)) @@ -2899,28 +2899,6 @@ patch = [[ ]] } -Bug{ -what = [[Lua does not check memory use when creating error messages]], -report = [[John Dunn, 2012/09/24]], -since = [[5.2.0]], -fix = nil, -example = [[ -local code = "function test()\n bob.joe.larry = 23\n end" - -load(code)() - --- memory will grow steadly -for i = 1, math.huge do - pcall(test) - if i % 100000 == 0 then - io.write(collectgarbage'count'*1024, "\n") - end -end -]], -patch = [[ -]] -} - @@ -3859,11 +3837,11 @@ report = [[Viacheslav Usov, 2017/07/06]], since = [[5.3.2]], fix = nil, example = [[ -function test() +function test() bob.joe.larry = 23 end --- memory will grow steadly +-- memory will grow steadly for i = 1, math.huge do pcall(test) if i % 100000 == 0 then @@ -3892,7 +3870,7 @@ report = [[云风 Cloud Wu, 2017/08/15]], since = [[5.2]], fix = nil, example = [[ --- The following chunk, under a memory checker like valgrind, +-- The following chunk, under a memory checker like valgrind, -- produces a memory access violation. local a = setmetatable({}, {__mode = 'kv'}) @@ -4020,7 +3998,6 @@ patch = [[ ----------------------------------------------------------------- -- Lua 5.3.5 ---[=[ Bug{ what = [[Long brackets with a huge number of '=' overflow some internal buffer arithmetic]], @@ -4111,9 +4088,34 @@ patch = [[ } ]] } -]=] +Bug{ +what = [[joining an upvalue with itself can cause a use-after-free crash]], +report = [[Fady Othman, 2019/01/10]], +since = [[5.3]], +fix = nil, +example = [[ +-- the next code may crash the machine +f=load(function() end) +interesting={} +interesting[0]=string.rep("A",512) +debug.upvaluejoin(f,1,f,1) +]], +patch = [[ +--- a/lapi.c ++++ b/lapi.c +@@ -1289,6 +1289,8 @@ LUA_API void lua_upvaluejoin (lua_State *L, int fidx1, int n1, + LClosure *f1; + UpVal **up1 = getupvalref(L, fidx1, n1, &f1); + UpVal **up2 = getupvalref(L, fidx2, n2, NULL); ++ if (*up1 == *up2) ++ return; + luaC_upvdeccount(L, *up1); + *up1 = *up2; + (*up1)->refcount++; +]] +} --[=[ @@ -1254,13 +1254,12 @@ LUA_API const char *lua_setupvalue (lua_State *L, int funcindex, int n) { } -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 *L, int fidx, int n) { 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 *L, int fidx, int n) { 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++; @@ -58,9 +58,9 @@ MYLDFLAGS= $(LOCAL) -Wl,-E MYLIBS= -ldl -lreadline -CC= clang-3.8 +CC= gcc CFLAGS= -Wall -O2 $(MYCFLAGS) -AR= ar rcu +AR= ar rc RANLIB= ranlib RM= rm -f |