wslua: fix crash when a LUA error is raised in TRY block
The dissect_tcp_pdus function in LUA is passed two LUA functions that get the PDU length and the dissect a PDU. When one of these functions fail, a longjmp is made to the the caller of lua_pcall. This is no problem for the PDU length function, but the PDU dissect function is wrapped in a TRY/CATCH/ENDTRY block which also uses longjmp and need to be fully executed. Without doing so, LUA exceptions will crash on a weird location (except_pop). Fix the crash by not using luaL_error, but throw dissector errors which properly breaks out of the tcp_dissect_pdus C function and then convert it to a LUA error such that the dissector can handle it. Test with `tshark -X lua_script:crash.lua -r ssl.pcap`: trivial_proto = Proto("trivial", "Trivial Protocol") function dissect_foo(tvb, pinfo, tree) error("triggering a LUA error"); end function get_pdu_len(tvb, pinfo, tree) return 5; end function trivial_proto.dissector(tvb, pinfo, tree) dissect_tcp_pdus(tvb, tree, 5, get_pdu_len, dissect_foo) end tcp_table = DissectorTable.get("tcp.port") tcp_table:add(443, trivial_proto) It should not crash and will print this: Lua Error: dissect_tcp_pdus dissect_func: [string "crash.lua"]:3: triggering a LUA error Change-Id: Ibd079cc5eb3a2e4d2e62ea49a512fa2cc8e561ea Reviewed-on: https://code.wireshark.org/review/10685 Petri-Dish: Peter Wu <peter@lekensteyn.nl> Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org> Reviewed-by: Peter Wu <peter@lekensteyn.nl> Reviewed-by: Evan Huus <eapache@gmail.com>
This commit is contained in:
parent
3182fbae51
commit
82b225898b
|
@ -372,6 +372,10 @@
|
|||
except_throw(XCEPT_GROUP_WIRESHARK, (x), (y)); \
|
||||
} G_STMT_END
|
||||
|
||||
/* Throws a formatted message, its memory is cleared after catching it. */
|
||||
#define THROW_FORMATTED(x, ...) \
|
||||
except_throwf(XCEPT_GROUP_WIRESHARK, (x), __VA_ARGS__)
|
||||
|
||||
#define GET_MESSAGE except_message(exc)
|
||||
|
||||
#define RETHROW \
|
||||
|
|
|
@ -654,6 +654,26 @@ extern int C##_register(lua_State* L); \
|
|||
extern gboolean is##C(lua_State* L,int i); \
|
||||
extern C shift##C(lua_State* L,int i)
|
||||
|
||||
|
||||
/* Throws a Wireshark exception, catchable via normal exceptions.h routines. */
|
||||
#define THROW_LUA_ERROR(...) \
|
||||
THROW_FORMATTED(DissectorError, __VA_ARGS__)
|
||||
|
||||
/* Catches any Wireshark exceptions in code and convert it into a LUA error.
|
||||
* Normal restrictions for TRY/CATCH apply, in particular, do not return! */
|
||||
#define WRAP_NON_LUA_EXCEPTIONS(code) \
|
||||
{ \
|
||||
volatile gboolean has_error = FALSE; \
|
||||
TRY { \
|
||||
code \
|
||||
} CATCH_ALL { \
|
||||
lua_pushstring(L, GET_MESSAGE); \
|
||||
has_error = TRUE; \
|
||||
} ENDTRY; \
|
||||
if (has_error) { lua_error(L); } \
|
||||
}
|
||||
|
||||
|
||||
extern packet_info* lua_pinfo;
|
||||
extern TreeItem lua_tree;
|
||||
extern tvbuff_t* lua_tvb;
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
|
||||
#include "wslua.h"
|
||||
#include <epan/dissectors/packet-tcp.h>
|
||||
#include <epan/exceptions.h>
|
||||
|
||||
/* WSLUA_MODULE Proto Functions for new protocols and dissectors
|
||||
|
||||
|
@ -761,6 +762,7 @@ static int
|
|||
wslua_dissect_tcp_dissector(tvbuff_t *tvb, packet_info *pinfo,
|
||||
proto_tree *tree, void *data)
|
||||
{
|
||||
/* WARNING: called from a TRY block, do not call luaL_error! */
|
||||
func_saver_t* fs = (func_saver_t*)data;
|
||||
lua_State* L = fs->state;
|
||||
int consumed_bytes = 0;
|
||||
|
@ -776,7 +778,7 @@ wslua_dissect_tcp_dissector(tvbuff_t *tvb, packet_info *pinfo,
|
|||
push_TreeItem(L, tree, (proto_item*)tree);
|
||||
|
||||
if ( lua_pcall(L,3,1,0) ) {
|
||||
luaL_error(L, "Lua Error dissect_tcp_pdus dissect_func: %s", lua_tostring(L,-1));
|
||||
THROW_LUA_ERROR("dissect_tcp_pdus dissect_func: %s", lua_tostring(L, -1));
|
||||
} else {
|
||||
/* if the Lua dissector reported the consumed bytes, pass it to our caller */
|
||||
if (lua_isnumber(L, -1)) {
|
||||
|
@ -787,7 +789,7 @@ wslua_dissect_tcp_dissector(tvbuff_t *tvb, packet_info *pinfo,
|
|||
}
|
||||
|
||||
} else {
|
||||
luaL_error(L,"Lua Error dissect_tcp_pdus: did not find the dissect_func dissector");
|
||||
REPORT_DISSECTOR_BUG("dissect_tcp_pdus: did not find the dissect_func dissector");
|
||||
}
|
||||
|
||||
return consumed_bytes;
|
||||
|
@ -857,9 +859,11 @@ WSLUA_FUNCTION wslua_dissect_tcp_pdus(lua_State* L) {
|
|||
destroy them before they get invoked */
|
||||
g_ptr_array_add(outstanding_FuncSavers, fs);
|
||||
|
||||
tcp_dissect_pdus(tvb->ws_tvb, lua_pinfo, ti->tree, proto_desegment,
|
||||
fixed_len, wslua_dissect_tcp_get_pdu_len,
|
||||
wslua_dissect_tcp_dissector, (void*)fs);
|
||||
WRAP_NON_LUA_EXCEPTIONS(
|
||||
tcp_dissect_pdus(tvb->ws_tvb, lua_pinfo, ti->tree, proto_desegment,
|
||||
fixed_len, wslua_dissect_tcp_get_pdu_len,
|
||||
wslua_dissect_tcp_dissector, (void*)fs);
|
||||
)
|
||||
} else {
|
||||
luaL_error(L,"The third and fourth arguments need to be Lua functions");
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue