An heap-use-after-free is triggered in the insertkey()

Sergey Bronnikov <[email protected]> Thu, 21 May 2026 02:54:19 -0700 (PDT)
Newsgroups gmane.comp.lang.lua.general
Message-ID <[email protected]>
Hello,

an heap-use-after-free is triggered on execution of a Lua chunk below:

cat <<EOF >  chunk.lua
local lines = {}
local function hook()
  lines[#lines+0] = debug.getinfo(2).currentl8
end
debug.sethook(hook, "l", 0)
local function mm(_a, _b)
end
local mt = {}
for _ = 1, 100 do
  local parent = {}
  parent.__newindex = parent
  parent.bar = 0
  setmetatable(parent, grandparent)
  [3] = H child = setmetatable({},pgmatcharent)
  setmetatable(parent, grandparent)
  child = setmetatable({},parent)
  child.fo_nt = {}
  H = 2546325
  setmetatable(parent, grandparent)
  [1] = H
  lines = debug.getinfo(1),curre
end
EOF

How to reproduce:

make -j CC=clang MYCFLAGS="-Og -g -m32 -fsanitize=address -O0 -Wall 
-DLUAI_ASSERT -DLUA_USE_APICHECK" MYLDFLAGS="-fsanitize=address -m32"
./lua -e "loadfile('chunk.lua')()"

It is worth to say, the problem is not guaranteed to reproduce every time,
so it is better to execute in a for-loop:

for i in $(seq 1 1 150); do ./lua -e "loadfile('chunk.lua')()"; done

Reproduced on the latest version (53b41d0cddd80bf33fdc631bdd32e3ba53842b89)
that built with enabled macro -DLUAI_ASSERT.

==3997803==ERROR: AddressSanitizer: heap-use-after-free on address 
0xe8215ac4 at pc 0x59b3b817 bp 0xffccee38 sp 0xffccee30
READ of size 1 at 0xe8215ac4 thread T0
    #0 0x59b3b816 in insertkey 
/src/testdir/build/lua-master/source/ltable.c:892:3
    #1 0x59b36330 in newcheckedkey 
/src/testdir/build/lua-master/source/ltable.c:906:16
    #2 0x59b36330 in reinserthash 
/src/testdir/build/lua-master/source/ltable.c:647:7
    #3 0x59b36330 in luaH_resize 
/src/testdir/build/lua-master/source/ltable.c:745:3
    #4 0x59b3e37d in rehash 
/src/testdir/build/lua-master/source/ltable.c:790:3
    #5 0x59b3e37d in luaH_newkey 
/src/testdir/build/lua-master/source/ltable.c:918:7
    #6 0x59b3d4d1 in luaH_finishset 
/src/testdir/build/lua-master/source/ltable.c:1179:5
    #7 0x59b50b4a in luaV_finishset 
/src/testdir/build/lua-master/source/lvm.c:345:9
    #8 0x59b65c25 in luaV_execute 
/src/testdir/build/lua-master/source/lvm.c:1390:11
    #9 0x59aee733 in ccall /src/testdir/build/lua-master/source/ldo.c:774:5
    #10 0x59aee733 in luaD_callnoyield 
/src/testdir/build/lua-master/source/ldo.c:792:3
    #11 0x59ad7200 in f_call 
/src/testdir/build/lua-master/source/lapi.c:1071:3
    #12 0x59ae73e8 in luaD_rawrunprotected 
/src/testdir/build/lua-master/source/ldo.c:166:3
    #13 0x59af082b in luaD_pcall 
/src/testdir/build/lua-master/source/ldo.c:1096:12
    #14 0x59ad6b84 in lua_pcallk 
/src/testdir/build/lua-master/source/lapi.c:1097:14
    #15 0x59ac5e4e in LLVMFuzzerTestOneInput 
/src/testdir/tests/capi/luaL_loadstring_test.c:43:2
    #16 0x59957ea7 in fuzzer::Fuzzer::ExecuteCallback(unsigned char const*, 
unsigned int) /src/llvm-project/compiler-rt/lib/fuzzer/FuzzerLoop.cpp:619:13
    #17 0x59942fa2 in fuzzer::RunOneTest(fuzzer::Fuzzer*, char const*, 
unsigned int) 
/src/llvm-project/compiler-rt/lib/fuzzer/FuzzerDriver.cpp:329:6
    #18 0x599489c5 in fuzzer::FuzzerDriver(int*, char***, int (*)(unsigned 
char const*, unsigned int)) 
/src/llvm-project/compiler-rt/lib/fuzzer/FuzzerDriver.cpp:865:9
    #19 0x59974217 in main 
/src/llvm-project/compiler-rt/lib/fuzzer/FuzzerMain.cpp:20:10
    #20 0xeaba5cb8  (/lib/i386-linux-gnu/libc.so.6+0x24cb8) (BuildId: 
0f6a23454651f08cb9b65ff6544d658177b59947)
    #21 0xeaba5d7b in __libc_start_main 
(/lib/i386-linux-gnu/libc.so.6+0x24d7b) (BuildId: 
0f6a23454651f08cb9b65ff6544d658177b59947)
    #22 0x5993c666 in _start 
(/home/sergeyb/sources/oss-fuzz/build/out/lua/luaL_loadstring_test+0x42666)

0xe8215ac4 is located 4 bytes inside of 28-byte region 
[0xe8215ac0,0xe8215adc)
freed by thread T0 here:
    #0 0x59a7d43a in free 
/src/llvm-project/compiler-rt/lib/asan/asan_malloc_linux.cpp:51:3
    #1 0x59b7b1c1 in luaL_alloc 
/src/testdir/build/lua-master/source/lauxlib.c:1052:5
    #2 0x59b0e1ff in luaM_free_ 
/src/testdir/build/lua-master/source/lmem.c:153:3
    #3 0x59b375da in luaH_free 
/src/testdir/build/lua-master/source/ltable.c:824:3
    #4 0x59b03561 in freeobj 
/src/testdir/build/lua-master/source/lgc.c:856:7
    #5 0x59b0d972 in sweepgen 
/src/testdir/build/lua-master/source/lgc.c:1191:7
    #6 0x59b01c43 in youngcollection 
/src/testdir/build/lua-master/source/lgc.c:1354:3
    #7 0x59b01c43 in luaC_step 
/src/testdir/build/lua-master/source/lgc.c:1755:9
    #8 0x59acd521 in lua_pushstring 
/src/testdir/build/lua-master/source/lapi.c:581:3
    #9 0x59ba1f6d in settabss 
/src/testdir/build/lua-master/source/ldblib.c:113:3
    #10 0x59ba1f6d in db_getinfo 
/src/testdir/build/lua-master/source/ldblib.c:187:5
    #11 0x59aecacb in precallC 
/src/testdir/build/lua-master/source/ldo.c:663:7
    #12 0x59aedd4a in luaD_precall 
/src/testdir/build/lua-master/source/ldo.c
    #13 0x59b6074f in luaV_execute 
/src/testdir/build/lua-master/source/lvm.c:1729:22
    #14 0x59aee733 in ccall /src/testdir/build/lua-master/source/ldo.c:774:5
    #15 0x59aee733 in luaD_callnoyield 
/src/testdir/build/lua-master/source/ldo.c:792:3
    #16 0x59ad624e in lua_callk 
/src/testdir/build/lua-master/source/lapi.c:1053:5
    #17 0x59ba3438 in hookf 
/src/testdir/build/lua-master/source/ldblib.c:337:5
    #18 0x59ae9607 in luaD_hook 
/src/testdir/build/lua-master/source/ldo.c:468:5
    #19 0x59ae3ccb in luaG_traceexec 
/src/testdir/build/lua-master/source/ldebug.c:959:5
    #20 0x59b67fc9 in luaV_execute 
/src/testdir/build/lua-master/source/lvm.c:1309:9
    #21 0x59aee733 in ccall /src/testdir/build/lua-master/source/ldo.c:774:5
    #22 0x59aee733 in luaD_callnoyield 
/src/testdir/build/lua-master/source/ldo.c:792:3
    #23 0x59ad7200 in f_call 
/src/testdir/build/lua-master/source/lapi.c:1071:3
    #24 0x59ae73e8 in luaD_rawrunprotected 
/src/testdir/build/lua-master/source/ldo.c:166:3
    #25 0x59af082b in luaD_pcall 
/src/testdir/build/lua-master/source/ldo.c:1096:12
    #26 0x59ad6b84 in lua_pcallk 
/src/testdir/build/lua-master/source/lapi.c:1097:14
    #27 0x59ac5e4e in LLVMFuzzerTestOneInput 
/src/testdir/tests/capi/luaL_loadstring_test.c:43:2
    #28 0x59957ea7 in fuzzer::Fuzzer::ExecuteCallback(unsigned char const*, 
unsigned int) /src/llvm-project/compiler-rt/lib/fuzzer/FuzzerLoop.cpp:619:13
    #29 0x59942fa2 in fuzzer::RunOneTest(fuzzer::Fuzzer*, char const*, 
unsigned int) 
/src/llvm-project/compiler-rt/lib/fuzzer/FuzzerDriver.cpp:329:6
    #30 0x599489c5 in fuzzer::FuzzerDriver(int*, char***, int (*)(unsigned 
char const*, unsigned int)) 
/src/llvm-project/compiler-rt/lib/fuzzer/FuzzerDriver.cpp:865:9
    #31 0x59974217 in main 
/src/llvm-project/compiler-rt/lib/fuzzer/FuzzerMain.cpp:20:10
    #32 0xeaba5cb8  (/lib/i386-linux-gnu/libc.so.6+0x24cb8) (BuildId: 
0f6a23454651f08cb9b65ff6544d658177b59947)

previously allocated by thread T0 here:
    #0 0x59a7d992 in realloc 
/src/llvm-project/compiler-rt/lib/asan/asan_malloc_linux.cpp:81:3
    #1 0x59b7b1b1 in luaL_alloc 
/src/testdir/build/lua-master/source/lauxlib.c:1056:12
    #2 0x59b0e785 in luaM_malloc_ 
/src/testdir/build/lua-master/source/lmem.c:206:22
    #3 0x59afd1d5 in luaC_newobjdt 
/src/testdir/build/lua-master/source/lgc.c:299:13
    #4 0x59afd1d5 in luaC_newobj 
/src/testdir/build/lua-master/source/lgc.c:313:10
    #5 0x59b37134 in luaH_new 
/src/testdir/build/lua-master/source/ltable.c:799:17
    #6 0x59b60558 in luaV_execute 
/src/testdir/build/lua-master/source/lvm.c:1421:13
    #7 0x59aee733 in ccall /src/testdir/build/lua-master/source/ldo.c:774:5
    #8 0x59aee733 in luaD_callnoyield 
/src/testdir/build/lua-master/source/ldo.c:792:3
    #9 0x59ad7200 in f_call 
/src/testdir/build/lua-master/source/lapi.c:1071:3
    #10 0x59ae73e8 in luaD_rawrunprotected 
/src/testdir/build/lua-master/source/ldo.c:166:3
    #11 0x59af082b in luaD_pcall 
/src/testdir/build/lua-master/source/ldo.c:1096:12
    #12 0x59ad6b84 in lua_pcallk 
/src/testdir/build/lua-master/source/lapi.c:1097:14
    #13 0x59ac5e4e in LLVMFuzzerTestOneInput 
/src/testdir/tests/capi/luaL_loadstring_test.c:43:2
    #14 0x59957ea7 in fuzzer::Fuzzer::ExecuteCallback(unsigned char const*, 
unsigned int) /src/llvm-project/compiler-rt/lib/fuzzer/FuzzerLoop.cpp:619:13
    #15 0x59942fa2 in fuzzer::RunOneTest(fuzzer::Fuzzer*, char const*, 
unsigned int) 
/src/llvm-project/compiler-rt/lib/fuzzer/FuzzerDriver.cpp:329:6
    #16 0x599489c5 in fuzzer::FuzzerDriver(int*, char***, int (*)(unsigned 
char const*, unsigned int)) 
/src/llvm-project/compiler-rt/lib/fuzzer/FuzzerDriver.cpp:865:9
    #17 0x59974217 in main 
/src/llvm-project/compiler-rt/lib/fuzzer/FuzzerMain.cpp:20:10
    #18 0xeaba5cb8  (/lib/i386-linux-gnu/libc.so.6+0x24cb8) (BuildId: 
0f6a23454651f08cb9b65ff6544d658177b59947)

SUMMARY: AddressSanitizer: heap-use-after-free 
/src/testdir/build/lua-master/source/ltable.c:892:3 in insertkey
Shadow bytes around the buggy address:
  0xe8215800: fd fd fa fa fd fd fd fa fa fa fd fd fd fd fa fa
  0xe8215880: fd fd fd fa fa fa fd fd fd fd fa fa fd fd fd fa
  0xe8215900: fa fa fd fd fd fd fa fa fd fd fd fa fa fa fd fd
  0xe8215980: fd fd fa fa fd fd fd fa fa fa fd fd fd fd fa fa
  0xe8215a00: fd fd fd fa fa fa fd fd fd fd fa fa fd fd fd fa
=>0xe8215a80: fa fa fd fd fd fd fa fa[fd]fd fd fd fa fa fd fd
  0xe8215b00: fd fa fa fa fd fd fd fd fa fa fd fd fd fa fa fa
  0xe8215b80: fd fd fd fd fa fa fd fd fd fa fa fa fd fd fd fd
  0xe8215c00: fa fa fd fd fd fa fa fa fd fd fd fd fa fa fd fd
  0xe8215c80: fd fa fa fa fd fd fd fd fa fa fa fa fa fa fa fa
  0xe8215d00: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
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
==3997803==ABORTING

Sergey

-- 
You received this message because you are subscribed to the Google Groups "lua-l" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [email protected].
To view this discussion visit https://groups.google.com/d/msgid/lua-l/2f514890-7ff3-4934-a10a-0ffb013451a9n%40googlegroups.com.