lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


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.


Best regards,

Maik Betka