lua-users home
lua-l archive

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




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:
See: https://pgl.yoyo.org/luai/i/pcall

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