lua-users home
lua-l archive

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


This crash is detected with address sanitizer applied. Example codes do not crash under normally compiled Lua, since uaf may or may not cause program to crash.

I was wondering if this could be a potential vulnerability in Lua interpreter.

Although Lua interpreter ends with printing out error message, it can be ignored by wrapping co in line 10 with pcall(), and additional code can be written, like below

> 1 co = coroutine.wrap(
> 2 function()
> 3 local pcall <close> = setmetatable(
> 4 {}, {__close = function() return pcall(co) end}
> 5 )
> 6 pcall()
> 7 end
> 8 )
> 9 pcall(co)

2021년 10월 30일 (토) 오후 9:41, Ranier Vilela <ranier.vf@gmail.com>님이 작성:


Em sáb., 30 de out. de 2021 às 05:20, MinSeok Kang <maple19out@gmail.com> escreveu:
Hi,

I found an interesting crash on Lua interpreter.
(Ubuntu 20.04 LTS / glibc 2.3.1 / Lua 5.4.4 commit hash 0e5071b5fbcc244d9f8c4bae82e327ad59bccc3f)

Code below generates use after read crash with address-sanitizer applied.
---------------------------------------------------------------------------------------------------
1 co = coroutine.wrap(
2   function()
3     local pcall <close> = setmetatable(
4       {}, {__close = function() pcall(co) end}
5     )
6     pcall()
7   end
8 )
9 co()
Windows 10 (64 bits)
MSVC 2019 (64 bits)
latest lua git:
Lua 5.4.4  Copyright (C) 1994-2021 Lua.org, PUC-Rio
>  co = coroutine.wrap(
>>    function()
>>      local pcall <close> = setmetatable(
>>        {}, {__close = function() pcall(co) end}
>>      )
>>      pcall()
>>    end
>>  )
> co()
stdin:1: stdin:6: attempt to call a table value (local 'pcall')
stack traceback:
        [C]: in function 'co'
        stdin:1: in main chunk
        [C]: in ?
>

C:\dll\lua\git>lua crash2.lua
lua: \dll\xclipper\xbin\lsql\crash2.lua:9: \dll\xclipper\xbin\lsql\crash2.lua:6: attempt to call a table value (local 'pcall')
stack traceback:
        [C]: in function 'co'
        \dll\xclipper\xbin\lsql\crash2.lua:9: in main chunk
        [C]: in ?

 Similarly, code below generates use after write crash.
---------------------------------------------------------------------------------------------------
1 co = coroutine.wrap(
2   function()
3    local pcall <close> = setmetatable(
4      {}, {__close = function() return pcall(co) end}
5     )
6     pcall()
7   end
8 )
9 co()
Lua 5.4.4  Copyright (C) 1994-2021 Lua.org, PUC-Rio
> co = coroutine.wrap(
>>    function()
>>     local pcall <close> = setmetatable(
>>       {}, {__close = function() return pcall(co) end}
>>      )
>>      pcall()
>>    end
>>  )
> co()
stdin:1: stdin:6: attempt to call a table value (local 'pcall')
stack traceback:
        [C]: in function 'co'
        stdin:1: in main chunk
        [C]: in ?
>

C:\dll\lua\git>lua crash3.lua
lua: \dll\xclipper\xbin\lsql\crash3.lua:9: \dll\xclipper\xbin\lsql\crash3.lua:6: attempt to call a table value (local 'pcall')
stack traceback:
        [C]: in function 'co'
        \dll\xclipper\xbin\lsql\crash3.lua:9: in main chunk
        [C]: in ?
 
Am I missing something?

Anyway pcall() and pcall(1), should be illegal:

There is a bug with pcall().

lbaselib.c:
static int luaB_pcall (lua_State *L) {
  int status;
  luaL_checkany(L, 1);
  lua_pushboolean(L, 1);  /* first result if no errors */
  lua_insert(L, 1);  /* put it in place */
  status = lua_pcallk(L, lua_gettop(L) - 2, LUA_MULTRET, 0, 0, finishpcall);
  return finishpcall(L, status, 0);
}

Should be:
static int luaB_pcall (lua_State *L) {
  int status;
  luaL_checktype(L, 1, LUA_TFUNCTION);
  lua_pushboolean(L, 1);  /* first result if no errors */
  lua_insert(L, 1);  /* put it in place */
  status = lua_pcallk(L, lua_gettop(L) - 2, LUA_MULTRET, 0, 0, finishpcall);
  return finishpcall(L, status, 0);
}

regards,
Ranier Vilela