mirror of
http://git.haproxy.org/git/haproxy.git/
synced 2025-03-11 05:48:41 +00:00
BUG/MINOR: hlua: prevent LJMP in hlua_traceback()
Function is often used on error paths where no precaution is taken against LJMP. Since the function is used on error paths (which include out-of-memory error paths) the function lua_getinfo() could also raise a memory exception, causing the process to crash or improper error handling if the caller isn't prepared against that eventually. Since the function is only used on rare events (error handling) and is lacking the __LJMP prototype pefix, let's make it safe by protecting the lua_getinfo() call so that hlua_traceback() callers may use it safely now (the function will always succeed, output will be truncated in case of error). This could be backported to all stable versions.
This commit is contained in:
parent
f0e5b825cf
commit
365ee28510
38
src/hlua.c
38
src/hlua.c
@ -848,20 +848,41 @@ void hlua_unref(lua_State *L, int ref)
|
||||
luaL_unref(L, LUA_REGISTRYINDEX, ref);
|
||||
}
|
||||
|
||||
__LJMP const char *hlua_traceback(lua_State *L, const char* sep)
|
||||
__LJMP static int _hlua_traceback(lua_State *L)
|
||||
{
|
||||
lua_Debug *ar = lua_touserdata(L, 1);
|
||||
|
||||
/* Fill fields:
|
||||
* 'S': fills in the fields source, short_src, linedefined, lastlinedefined, and what;
|
||||
* 'l': fills in the field currentline;
|
||||
* 'n': fills in the field name and namewhat;
|
||||
* 't': fills in the field istailcall;
|
||||
*/
|
||||
return lua_getinfo(L, "Slnt", ar);
|
||||
}
|
||||
|
||||
|
||||
/* This function cannot fail (output will simply be truncated upon errors) */
|
||||
const char *hlua_traceback(lua_State *L, const char* sep)
|
||||
{
|
||||
lua_Debug ar;
|
||||
int level = 0;
|
||||
struct buffer *msg = get_trash_chunk();
|
||||
|
||||
while (lua_getstack(L, level++, &ar)) {
|
||||
/* Fill fields:
|
||||
* 'S': fills in the fields source, short_src, linedefined, lastlinedefined, and what;
|
||||
* 'l': fills in the field currentline;
|
||||
* 'n': fills in the field name and namewhat;
|
||||
* 't': fills in the field istailcall;
|
||||
*/
|
||||
lua_getinfo(L, "Slnt", &ar);
|
||||
if (!lua_checkstack(L, 2))
|
||||
goto end; // abort
|
||||
|
||||
lua_pushcfunction(L, _hlua_traceback);
|
||||
lua_pushlightuserdata(L, &ar);
|
||||
|
||||
/* safe getinfo */
|
||||
switch (lua_pcall(L, 1, 1, 0)) {
|
||||
case LUA_OK:
|
||||
break;
|
||||
default:
|
||||
goto end; // abort
|
||||
}
|
||||
|
||||
/* skip these empty entries, usually they come from deep C functions */
|
||||
if (ar.currentline < 0 && *ar.what == 'C' && !*ar.namewhat && !ar.name)
|
||||
@ -902,6 +923,7 @@ __LJMP const char *hlua_traceback(lua_State *L, const char* sep)
|
||||
chunk_appendf(msg, " ...");
|
||||
}
|
||||
|
||||
end:
|
||||
return msg->area;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user