Hello, everyone,
there is a "heap-use-after-free" issue on the latest version.
How to reproduce:
- clone Git repository with Lua source code:
git clone
https://github.com/lua/lua- apply the patch below: patch -p1 < makefile.patch
```
--- a/makefile
+++ b/makefile
@@ -72,11 +72,11 @@ LOCAL = $(TESTS) $(CWARNS)
# enable Linux goodies
MYCFLAGS= $(LOCAL) -std=c99 -DLUA_USE_LINUX -DLUA_USE_READLINE
MYLDFLAGS= $(LOCAL) -Wl,-E
-MYLIBS= -ldl -lreadline
+MYLIBS= -ldl -lreadline $(LDFLAGS)
-CC= gcc
-CFLAGS= -Wall -O2 $(MYCFLAGS) -fno-stack-protector -fno-common -march=native
+CC?= gcc
+CFLAGS+= -Wall -O2 $(MYCFLAGS) -fno-stack-protector -fno-common -march=native
AR= ar rc
RANLIB= ranlib
RM= rm -f
```
- build Lua with enabled AddressSanitizer:
CC=clang CFLAGS="-ggdb -O0 -fsanitize=address" LDFLAGS=-fsanitize=address make
- create a file with Lua code:
```
cat << EOF > repro.lua
local a
local b
local b
local b
local b
local __index = function(c, d)
if type(c) then
end
end
local e
local b
local h
local b
local b
local b
local b
local b
debug.setmetatable("string", { __index = __index })
local f
local i
g, g, g, g, g, g, g, g, g, g, g, g, g, g, g, g, g, g, g, g, g, g, g, g, g, g, g, g, g, g, g, g = "Name"
g(g:g())
EOF
```
- execute the Lua snippet by command `./lua repro.lua`
and AddressSanitizer will report a heap-use-after-free in `luaV_finishget`:
=================================================================
==159947==ERROR: AddressSanitizer: heap-use-after-free on address 0x51a000000208 at pc 0x596b266ea5bf bp 0x7ffcaab43fe0 sp 0x7ffcaab43fd8
READ of size 1 at 0x51a000000208 thread T0
#0 0x596b266ea5be in luaV_finishget (/home/sergeyb/sources/cache/lua/lua+0x1715be) (BuildId: 6348343d72d6c76f60f3adaaf07ccc041e70a3bd)
#1 0x596b266ef503 in luaV_execute (/home/sergeyb/sources/cache/lua/lua+0x176503) (BuildId: 6348343d72d6c76f60f3adaaf07ccc041e70a3bd)
#2 0x596b266b2809 in luaD_callnoyield (/home/sergeyb/sources/cache/lua/lua+0x139809) (BuildId: 6348343d72d6c76f60f3adaaf07ccc041e70a3bd)
#3 0x596b266ae6e0 in luaD_rawrunprotected (/home/sergeyb/sources/cache/lua/lua+0x1356e0) (BuildId: 6348343d72d6c76f60f3adaaf07ccc041e70a3bd)
#4 0x596b266b3b06 in luaD_pcall (/home/sergeyb/sources/cache/lua/lua+0x13ab06) (BuildId: 6348343d72d6c76f60f3adaaf07ccc041e70a3bd)
#5 0x596b266a4218 in lua_pcallk (/home/sergeyb/sources/cache/lua/lua+0x12b218) (BuildId: 6348343d72d6c76f60f3adaaf07ccc041e70a3bd)
#6 0x596b26699249 in docall lua.c
#7 0x596b2669863b in pmain lua.c
#8 0x596b266b207a in luaD_precall (/home/sergeyb/sources/cache/lua/lua+0x13907a) (BuildId: 6348343d72d6c76f60f3adaaf07ccc041e70a3bd)
#9 0x596b266b27d9 in luaD_callnoyield (/home/sergeyb/sources/cache/lua/lua+0x1397d9) (BuildId: 6348343d72d6c76f60f3adaaf07ccc041e70a3bd)
#10 0x596b266ae6e0 in luaD_rawrunprotected (/home/sergeyb/sources/cache/lua/lua+0x1356e0) (BuildId: 6348343d72d6c76f60f3adaaf07ccc041e70a3bd)
#11 0x596b266b3b06 in luaD_pcall (/home/sergeyb/sources/cache/lua/lua+0x13ab06) (BuildId: 6348343d72d6c76f60f3adaaf07ccc041e70a3bd)
#12 0x596b266a4218 in lua_pcallk (/home/sergeyb/sources/cache/lua/lua+0x12b218) (BuildId: 6348343d72d6c76f60f3adaaf07ccc041e70a3bd)
#13 0x596b26697ba6 in main (/home/sergeyb/sources/cache/lua/lua+0x11eba6) (BuildId: 6348343d72d6c76f60f3adaaf07ccc041e70a3bd)
#14 0x787cf0e29d8f in __libc_start_call_main csu/../sysdeps/nptl/libc_start_call_main.h:58:16
#15 0x787cf0e29e3f in __libc_start_main csu/../csu/libc-start.c:392:3
#16 0x596b265b9614 in _start (/home/sergeyb/sources/cache/lua/lua+0x40614) (BuildId: 6348343d72d6c76f60f3adaaf07ccc041e70a3bd)
0x51a000000208 is located 392 bytes inside of 1360-byte region [0x51a000000080,0x51a0000005d0)
freed by thread T0 here:
#0 0x596b266583fc in realloc (/home/sergeyb/sources/cache/lua/lua+0xdf3fc) (BuildId: 6348343d72d6c76f60f3adaaf07ccc041e70a3bd)
#1 0x596b266c3205 in luaM_realloc_ (/home/sergeyb/sources/cache/lua/lua+0x14a205) (BuildId: 6348343d72d6c76f60f3adaaf07ccc041e70a3bd)
previously allocated by thread T0 here:
#0 0x596b266583fc in realloc (/home/sergeyb/sources/cache/lua/lua+0xdf3fc) (BuildId: 6348343d72d6c76f60f3adaaf07ccc041e70a3bd)
#1 0x596b266c3205 in luaM_realloc_ (/home/sergeyb/sources/cache/lua/lua+0x14a205) (BuildId: 6348343d72d6c76f60f3adaaf07ccc041e70a3bd)
SUMMARY: AddressSanitizer: heap-use-after-free (/home/sergeyb/sources/cache/lua/lua+0x1715be) (BuildId: 6348343d72d6c76f60f3adaaf07ccc041e70a3bd) in luaV_finishget
Shadow bytes around the buggy address:
0x519fffffff80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x51a000000000: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x51a000000080: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
0x51a000000100: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
0x51a000000180: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
=>0x51a000000200: fd[fd]fd fd fd fd fd fd fd fd fd fd fd fd fd fd
0x51a000000280: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
0x51a000000300: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
0x51a000000380: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
0x51a000000400: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
0x51a000000480: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
Shadow byte legend (one shadow byte represents 8 application bytes):
Addressable: 00
Partially addressable: 01 02 03 04 05 06 07
Heap left redzone: fa
Freed heap region: fd
Stack left redzone: f1
Stack mid redzone: f2
Stack right redzone: f3
Stack after return: f5
Stack use after scope: f8
Global redzone: f9
Global init order: f6
Poisoned by user: f7
Container overflow: fc
Array cookie: ac
Intra object redzone: bb
ASan internal: fe
Left alloca redzone: ca
Right alloca redzone: cb
==159947==ABORTING
It seems the commit 0593256707ce ("'luaH_get' functions return tag of the result") [1]
introduced a problem. Because the problem is gone when it is reverted:
$ ./lua repro.lua
./lua: repro.lua:22: attempt to call a nil value (method 'g')
stack traceback:
repro.lua:22: in main chunk
[C]: in ?
Sergey