From c8ac53c95b63223cdcaf0be911760c9150fe59fb Mon Sep 17 00:00:00 2001 From: Lukas Sismis Date: Fri, 14 Aug 2026 13:12:49 +0200 Subject: [PATCH] lua: type-check userdata in flow, packet and dataset methods The flow, packet and dataset methods fetched their object argument with lua_touserdata(), which does not validate the userdata type. A script could pass any userdata as the method's "self", and it would be dereferenced, immediately crashing the engine from inside the Lua sandbox. Ticket: 8882 --- src/util-lua-dataset.c | 12 +++--------- src/util-lua-flowlib.c | 34 +++++++++++++++++----------------- src/util-lua-packetlib.c | 38 +++++++++++++++++++------------------- 3 files changed, 39 insertions(+), 45 deletions(-) diff --git a/src/util-lua-dataset.c b/src/util-lua-dataset.c index e9e3fe9e7f..d4062ffa8e 100644 --- a/src/util-lua-dataset.c +++ b/src/util-lua-dataset.c @@ -41,7 +41,7 @@ struct LuaDataset { static int LuaDatasetGC(lua_State *luastate) { SCLogDebug("gc:start"); - struct LuaDataset *s = (struct LuaDataset *)lua_touserdata(luastate, 1); + struct LuaDataset *s = (struct LuaDataset *)luaL_testudata(luastate, 1, "dataset::metatable"); if (s != NULL && s->set != NULL) { SCLogDebug("deref %s", s->set->name); s->set = NULL; @@ -53,10 +53,7 @@ static int LuaDatasetGC(lua_State *luastate) static int LuaDatasetGetRef(lua_State *luastate) { SCLogDebug("get"); - struct LuaDataset *s = (struct LuaDataset *)lua_touserdata(luastate, 1); - if (s == NULL) { - LUA_ERROR("dataset is not initialized"); - } + struct LuaDataset *s = (struct LuaDataset *)luaL_checkudata(luastate, 1, "dataset::metatable"); const char *name = lua_tostring(luastate, 2); if (name == NULL) { @@ -74,10 +71,7 @@ static int LuaDatasetGetRef(lua_State *luastate) static int LuaDatasetAdd(lua_State *luastate) { SCLogDebug("add:start"); - struct LuaDataset *s = (struct LuaDataset *)lua_touserdata(luastate, 1); - if (s == NULL) { - LUA_ERROR("dataset is not initialized"); - } + struct LuaDataset *s = (struct LuaDataset *)luaL_checkudata(luastate, 1, "dataset::metatable"); if (!lua_isstring(luastate, 2)) { LUA_ERROR("1st arg is not a string"); } diff --git a/src/util-lua-flowlib.c b/src/util-lua-flowlib.c index 49887c2c7e..f4ea25814e 100644 --- a/src/util-lua-flowlib.c +++ b/src/util-lua-flowlib.c @@ -44,7 +44,7 @@ struct LuaFlow { static int LuaFlowGC(lua_State *luastate) { SCLogDebug("gc:start"); - struct LuaFlow *s = (struct LuaFlow *)lua_touserdata(luastate, 1); + struct LuaFlow *s = (struct LuaFlow *)luaL_testudata(luastate, 1, suricata_flow); if (s != NULL) { SCLogDebug("flow %p", s->f); s->f = NULL; @@ -62,8 +62,8 @@ static int LuaFlowGC(lua_State *luastate) */ static int LuaFlowId(lua_State *luastate) { - struct LuaFlow *s = (struct LuaFlow *)lua_touserdata(luastate, 1); - if (s == NULL || s->f == NULL) { + struct LuaFlow *s = (struct LuaFlow *)luaL_checkudata(luastate, 1, suricata_flow); + if (s->f == NULL) { LUA_ERROR("failed to get flow"); } @@ -85,8 +85,8 @@ static int LuaFlowId(lua_State *luastate) */ static int LuaFlowAppLayerProto(lua_State *luastate) { - struct LuaFlow *s = (struct LuaFlow *)lua_touserdata(luastate, 1); - if (s == NULL || s->f == NULL) { + struct LuaFlow *s = (struct LuaFlow *)luaL_checkudata(luastate, 1, suricata_flow); + if (s->f == NULL) { LUA_ERROR("failed to get flow"); } @@ -108,8 +108,8 @@ static int LuaFlowAppLayerProto(lua_State *luastate) */ static int LuaFlowHasAlerts(lua_State *luastate) { - struct LuaFlow *s = (struct LuaFlow *)lua_touserdata(luastate, 1); - if (s == NULL || s->f == NULL) { + struct LuaFlow *s = (struct LuaFlow *)luaL_checkudata(luastate, 1, suricata_flow); + if (s->f == NULL) { LUA_ERROR("failed to get flow"); } @@ -127,8 +127,8 @@ static int LuaFlowHasAlerts(lua_State *luastate) */ static int LuaFlowStats(lua_State *luastate) { - struct LuaFlow *s = (struct LuaFlow *)lua_touserdata(luastate, 1); - if (s == NULL || s->f == NULL) { + struct LuaFlow *s = (struct LuaFlow *)luaL_checkudata(luastate, 1, suricata_flow); + if (s->f == NULL) { LUA_ERROR("failed to get flow"); } @@ -150,8 +150,8 @@ static int LuaFlowStats(lua_State *luastate) */ static int LuaFlowTimestamps(lua_State *luastate) { - struct LuaFlow *s = (struct LuaFlow *)lua_touserdata(luastate, 1); - if (s == NULL || s->f == NULL) { + struct LuaFlow *s = (struct LuaFlow *)luaL_checkudata(luastate, 1, suricata_flow); + if (s->f == NULL) { LUA_ERROR("failed to get flow"); } @@ -165,8 +165,8 @@ static int LuaFlowTimestamps(lua_State *luastate) static int LuaFlowTimestringIso8601(lua_State *luastate) { - struct LuaFlow *s = (struct LuaFlow *)lua_touserdata(luastate, 1); - if (s == NULL || s->f == NULL) { + struct LuaFlow *s = (struct LuaFlow *)luaL_checkudata(luastate, 1, suricata_flow); + if (s->f == NULL) { LUA_ERROR("failed to get flow"); } @@ -182,8 +182,8 @@ static int LuaFlowTimestringIso8601(lua_State *luastate) */ static int LuaFlowTimestringLegacy(lua_State *luastate) { - struct LuaFlow *s = (struct LuaFlow *)lua_touserdata(luastate, 1); - if (s == NULL || s->f == NULL) { + struct LuaFlow *s = (struct LuaFlow *)luaL_checkudata(luastate, 1, suricata_flow); + if (s->f == NULL) { LUA_ERROR("failed to get flow"); } @@ -204,8 +204,8 @@ static int LuaFlowTimestringLegacy(lua_State *luastate) */ static int LuaFlowTuple(lua_State *luastate) { - struct LuaFlow *s = (struct LuaFlow *)lua_touserdata(luastate, 1); - if (s == NULL || s->f == NULL) { + struct LuaFlow *s = (struct LuaFlow *)luaL_checkudata(luastate, 1, suricata_flow); + if (s->f == NULL) { LUA_ERROR("failed to get flow"); } Flow *f = s->f; diff --git a/src/util-lua-packetlib.c b/src/util-lua-packetlib.c index 32780147e5..2a619a5112 100644 --- a/src/util-lua-packetlib.c +++ b/src/util-lua-packetlib.c @@ -44,7 +44,7 @@ struct LuaPacket { static int LuaPacketGC(lua_State *luastate) { SCLogDebug("gc:start"); - struct LuaPacket *s = (struct LuaPacket *)lua_touserdata(luastate, 1); + struct LuaPacket *s = (struct LuaPacket *)luaL_testudata(luastate, 1, suricata_packet); if (s != NULL) { SCLogDebug("packet %p", s->p); s->p = NULL; @@ -55,8 +55,8 @@ static int LuaPacketGC(lua_State *luastate) static int LuaPacketPayload(lua_State *luastate) { - struct LuaPacket *s = (struct LuaPacket *)lua_touserdata(luastate, 1); - if (s == NULL || s->p == NULL) { + struct LuaPacket *s = (struct LuaPacket *)luaL_checkudata(luastate, 1, suricata_packet); + if (s->p == NULL) { LUA_ERROR("failed to get packet"); } @@ -66,8 +66,8 @@ static int LuaPacketPayload(lua_State *luastate) static int LuaPacketPacket(lua_State *luastate) { - struct LuaPacket *s = (struct LuaPacket *)lua_touserdata(luastate, 1); - if (s == NULL || s->p == NULL) { + struct LuaPacket *s = (struct LuaPacket *)luaL_checkudata(luastate, 1, suricata_packet); + if (s->p == NULL) { LUA_ERROR("failed to get packet"); } @@ -77,8 +77,8 @@ static int LuaPacketPacket(lua_State *luastate) static int LuaPacketPcapCnt(lua_State *luastate) { - struct LuaPacket *s = (struct LuaPacket *)lua_touserdata(luastate, 1); - if (s == NULL || s->p == NULL) { + struct LuaPacket *s = (struct LuaPacket *)luaL_checkudata(luastate, 1, suricata_packet); + if (s->p == NULL) { LUA_ERROR("failed to get packet"); } @@ -91,8 +91,8 @@ static int LuaPacketPcapCnt(lua_State *luastate) */ static int LuaPacketTimestringLegacy(lua_State *luastate) { - struct LuaPacket *s = (struct LuaPacket *)lua_touserdata(luastate, 1); - if (s == NULL || s->p == NULL) { + struct LuaPacket *s = (struct LuaPacket *)luaL_checkudata(luastate, 1, suricata_packet); + if (s->p == NULL) { LUA_ERROR("failed to get packet"); } @@ -104,8 +104,8 @@ static int LuaPacketTimestringLegacy(lua_State *luastate) static int LuaPacketTimestringIso8601(lua_State *luastate) { - struct LuaPacket *s = (struct LuaPacket *)lua_touserdata(luastate, 1); - if (s == NULL || s->p == NULL) { + struct LuaPacket *s = (struct LuaPacket *)luaL_checkudata(luastate, 1, suricata_packet); + if (s->p == NULL) { LUA_ERROR("failed to get packet"); } @@ -117,8 +117,8 @@ static int LuaPacketTimestringIso8601(lua_State *luastate) static int LuaPacketTimestamp(lua_State *luastate) { - struct LuaPacket *s = (struct LuaPacket *)lua_touserdata(luastate, 1); - if (s == NULL || s->p == NULL) { + struct LuaPacket *s = (struct LuaPacket *)luaL_checkudata(luastate, 1, suricata_packet); + if (s->p == NULL) { LUA_ERROR("failed to get packet"); } @@ -137,8 +137,8 @@ static int LuaPacketTimestamp(lua_State *luastate) */ static int LuaPacketTuple(lua_State *luastate) { - struct LuaPacket *s = (struct LuaPacket *)lua_touserdata(luastate, 1); - if (s == NULL || s->p == NULL) { + struct LuaPacket *s = (struct LuaPacket *)luaL_checkudata(luastate, 1, suricata_packet); + if (s->p == NULL) { LUA_ERROR("failed to get packet"); } Packet *p = s->p; @@ -188,8 +188,8 @@ static int LuaPacketTuple(lua_State *luastate) */ static int LuaPacketSport(lua_State *luastate) { - struct LuaPacket *s = (struct LuaPacket *)lua_touserdata(luastate, 1); - if (s == NULL || s->p == NULL) { + struct LuaPacket *s = (struct LuaPacket *)luaL_checkudata(luastate, 1, suricata_packet); + if (s->p == NULL) { LUA_ERROR("failed to get packet"); } Packet *p = s->p; @@ -213,8 +213,8 @@ static int LuaPacketSport(lua_State *luastate) */ static int LuaPacketDport(lua_State *luastate) { - struct LuaPacket *s = (struct LuaPacket *)lua_touserdata(luastate, 1); - if (s == NULL || s->p == NULL) { + struct LuaPacket *s = (struct LuaPacket *)luaL_checkudata(luastate, 1, suricata_packet); + if (s->p == NULL) { LUA_ERROR("failed to get packet"); } Packet *p = s->p;