Second stack overflow luaO_pushvfstring

classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

Second stack overflow luaO_pushvfstring

Yongheng Chen

Hi,

 

It seems that the latest commit haven’t completely fix the bug. Here’s the POC:

function errfunc()

    return pcall ^ xpcall(setmetatable({}, {}), errfunc)

end

coroutine.wrap(function() print(xpcall(test, errfunc)) end)()

 

 

Tested on Ubuntu, lua git hash: e1d8770f12542d34a3e32b825c95b93f8a341ee1

 

 

Best,

Yongheng

 

Sent from Mail for Windows 10

 

Reply | Threaded
Open this post in threaded view
|

Re: Second stack overflow luaO_pushvfstring

Andrew Gierth
>>>>> "Yongheng" == Yongheng Chen <[hidden email]> writes:

 Yongheng> Hi, It seems that the latest commit haven’t completely fix
 Yongheng> the bug. Here’s the POC:

Something's underflowing nCcalls - possibly subtracting from it more
than once in between checks for whether it went below the CSTACKERRMARK
redzone?

Obviously hilarity ensues once that happens.

--
Andrew.
Reply | Threaded
Open this post in threaded view
|

Re: Second stack overflow luaO_pushvfstring

Roberto Ierusalimschy
> >>>>> "Yongheng" == Yongheng Chen <[hidden email]> writes:
>
>  Yongheng> Hi, It seems that the latest commit haven’t completely fix
>  Yongheng> the bug. Here’s the POC:
>
> Something's underflowing nCcalls - possibly subtracting from it more
> than once in between checks for whether it went below the CSTACKERRMARK
> redzone?

You are right. In luaD_callnoyield, when there is a possible stack
overflow, it zeros the number of CallInfos to force a check (and
then an error) when calling the function. However, if the "function"
is not a function, the code will raise an error without checking
the stack. Then, the error handling calls luaD_callnoyield again,
doing what you said: nCcalls is decremented twice in a row
without an intervenient stack check. After that, in your words,
"hilarity ensues". (This loop can only happens once, because the
error handler must be a function. But that is enough to cross
the redzone.)

-- Roberto