|
Hello,
I am researcher in software testing from the University of Stuttgart, Germany. We are testing grammar-based fuzzers and have chosen Lua as one of our fuzz targets for our experiments. We found 2 issues in Lua, but one of those seems to be already fixed in recent versions. Thus, here is the remaining issue we found, which still results in a crash in the current Lua version. Please excuse that the example looks weird. This is typically the case when generating random test inputs. I wasn't able to trim the input by much. ### System Lua version: 5.4.5 (c4b71b7ba0dee419b5bda1ec297eca8e42c9f1d2) System: Rocky Linux release 9.1 (Blue Onyx), 5.14.0-162.18.1.el9_1.x86_64 ### Build: # enable address sanitizer vim makefile # change MYCFLAGS and MYLDFLAGS to include '-fsanitize=address' MYCFLAGS= $(LOCAL) -std=c99 -DLUA_USE_LINUX -DLUA_USE_READLINE -fsanitize=address MYLDFLAGS= $(LOCAL) -Wl,-E -fsanitize=address # compile lua make ### Test input (test1.lua): I included the complete example between three opening and closing backticks (```) like in a Markdown syntax, to distinguish it from the rest of the email. Note that the line breaks seem necessary.
``` return utf8.dump (load (string.dump (function (...) return (((1.8e-2)//(function (table) if ((0.0e-1)//(function (table) if ((0.0e-0)+coroutine) then coroutine = coroutine.wrap(function (...) ::labelb:: end) end end).gsub ([[ ]], "")) then return (((00)+coroutine)>>"") end end).ceil {[( not (1.8e-2))]=(true)})>>function (table) coroutine = coroutine.wrap(function (...) return (((1.8e-2)//(function (table) if ((0.0e-0)~(00)) then return (((00)+coroutine)>>"") end end).ceil {[( not (1.8e-2))]=(true)})>>function (table) coroutine = coroutine.wrap(function (...) ::labelb:: end) end) end) end) end):gsub ([[ ]], "")), (((00)+coroutine)>>"")) ``` ### Execution: ./lua test1.lua ### Output with ASAN enabled: ================================================================= ==19331==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x6020000009a0 at pc 0x000000443a15 bp 0x7ffdb4e46000 sp 0x7ffdb4e45ff0 WRITE of size 8 at 0x6020000009a0 thread T0 #0 0x443a14 in loadFunction (/home/rocky/lua/lua+0x443a14) #1 0x4431eb in loadFunction (/home/rocky/lua/lua+0x4431eb) #2 0x4431eb in loadFunction (/home/rocky/lua/lua+0x4431eb) #3 0x444062 in luaU_undump (/home/rocky/lua/lua+0x444062) #4 0x4173c2 in f_parser (/home/rocky/lua/lua+0x4173c2) #5 0x4175b9 in luaD_rawrunprotected (/home/rocky/lua/lua+0x4175b9) #6 0x41bd99 in luaD_pcall (/home/rocky/lua/lua+0x41bd99) #7 0x41c335 in luaD_protectedparser (/home/rocky/lua/lua+0x41c335) #8 0x410333 in lua_load (/home/rocky/lua/lua+0x410333) #9 0x457443 in luaL_loadbufferx (/home/rocky/lua/lua+0x457443) #10 0x467fb2 in luaB_load (/home/rocky/lua/lua+0x467fb2) #11 0x41a0ef in luaD_precall (/home/rocky/lua/lua+0x41a0ef) #12 0x448d0a in luaV_execute (/home/rocky/lua/lua+0x448d0a) #13 0x41aed6 in luaD_callnoyield (/home/rocky/lua/lua+0x41aed6) #14 0x4175b9 in luaD_rawrunprotected (/home/rocky/lua/lua+0x4175b9) #15 0x41bd99 in luaD_pcall (/home/rocky/lua/lua+0x41bd99) #16 0x40fea4 in lua_pcallk (/home/rocky/lua/lua+0x40fea4) #17 0x4068b6 in docall (/home/rocky/lua/lua+0x4068b6) #18 0x407965 in pmain (/home/rocky/lua/lua+0x407965) #19 0x41a0ef in luaD_precall (/home/rocky/lua/lua+0x41a0ef) #20 0x41ae9a in luaD_callnoyield (/home/rocky/lua/lua+0x41ae9a) #21 0x4175b9 in luaD_rawrunprotected (/home/rocky/lua/lua+0x4175b9) #22 0x41bd99 in luaD_pcall (/home/rocky/lua/lua+0x41bd99) #23 0x40fea4 in lua_pcallk (/home/rocky/lua/lua+0x40fea4) #24 0x405aa4 in main (/home/rocky/lua/lua+0x405aa4) #25 0x7f487669beaf in __libc_start_call_main (/lib64/libc.so.6+0x3feaf) #26 0x7f487669bf5f in __libc_start_main_alias_1 (/lib64/libc.so.6+0x3ff5f) #27 0x406174 in _start (/home/rocky/lua/lua+0x406174) 0x6020000009a0 is located 0 bytes to the right of 16-byte region [0x602000000990,0x6020000009a0) allocated by thread T0 here: #0 0x7f4876a4cd98 in __interceptor_realloc (/lib64/libasan.so.6+0xb4d98) #1 0x428611 in luaM_malloc_ (/home/rocky/lua/lua+0x428611) SUMMARY: AddressSanitizer: heap-buffer-overflow (/home/rocky/lua/lua+0x443a14) in loadFunction Shadow bytes around the buggy address: 0x0c047fff80e0: fa fa 00 00 fa fa 00 00 fa fa 00 00 fa fa 00 00 0x0c047fff80f0: fa fa fd fd fa fa 00 fa fa fa 00 00 fa fa 00 00 0x0c047fff8100: fa fa 00 00 fa fa 00 00 fa fa 00 fa fa fa 00 00 0x0c047fff8110: fa fa 00 fa fa fa 00 fa fa fa 02 fa fa fa 00 03 0x0c047fff8120: fa fa 00 00 fa fa 00 00 fa fa 00 00 fa fa 00 fa =>0x0c047fff8130: fa fa 00 00[fa]fa 00 00 fa fa 00 00 fa fa 00 fa 0x0c047fff8140: fa fa 00 00 fa fa 00 00 fa fa 00 fa fa fa 00 fa 0x0c047fff8150: fa fa 02 fa fa fa 06 fa fa fa 00 00 fa fa 00 00 0x0c047fff8160: fa fa 00 00 fa fa fa fa fa fa fa fa fa fa fa fa 0x0c047fff8170: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c047fff8180: 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 Shadow gap: cc ==19331==ABORTING ### Output without ASAN enabled: ./lua: test1.lua:28: attempt to perform arithmetic on a table value (global 'coroutine') stack traceback: test1.lua:28: in main chunk [C]: in ? Expected behavior: No heap buffer overflow. Maik Betka |