From: Benjamin Wilkins Date: Wed, 20 Oct 2021 20:21:08 +0000 (-0400) Subject: lua: Fix SCRule functions for match scripts X-Git-Tag: suricata-7.0.0-beta1~1189 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e21a50fee605561e0034adb6e7644ed96a1a4c7a;p=thirdparty%2Fsuricata.git lua: Fix SCRule functions for match scripts Save Signature structure to lua register so SCRule functions can work in match scripts, where no PacketAlert is present Resolves Feature #2450 --- diff --git a/src/detect-lua-extensions.c b/src/detect-lua-extensions.c index aaeb0ce156..d03c022b70 100644 --- a/src/detect-lua-extensions.c +++ b/src/detect-lua-extensions.c @@ -481,8 +481,8 @@ static int LuaDecrFlowint(lua_State *luastate) } -void LuaExtensionsMatchSetup(lua_State *lua_state, DetectLuaData *ld, DetectEngineThreadCtx *det_ctx, - Flow *f, Packet *p, uint8_t flags) +void LuaExtensionsMatchSetup(lua_State *lua_state, DetectLuaData *ld, + DetectEngineThreadCtx *det_ctx, Flow *f, Packet *p, const Signature *s, uint8_t flags) { SCLogDebug("det_ctx %p, f %p", det_ctx, f); @@ -491,6 +491,8 @@ void LuaExtensionsMatchSetup(lua_State *lua_state, DetectLuaData *ld, DetectEngi lua_pushlightuserdata(lua_state, (void *)ld); lua_settable(lua_state, LUA_REGISTRYINDEX); + LuaStateSetSignature(lua_state, s); + LuaStateSetFlow(lua_state, f); if (det_ctx->tx_id_set) { diff --git a/src/detect-lua-extensions.h b/src/detect-lua-extensions.h index 54a465783e..efd9416f1b 100644 --- a/src/detect-lua-extensions.h +++ b/src/detect-lua-extensions.h @@ -27,9 +27,8 @@ #ifdef HAVE_LUA int LuaRegisterExtensions(lua_State *); -void LuaExtensionsMatchSetup(lua_State *lua_state, - DetectLuaData *, DetectEngineThreadCtx *det_ctx, - Flow *f, Packet *p, uint8_t flags); +void LuaExtensionsMatchSetup(lua_State *lua_state, DetectLuaData *, DetectEngineThreadCtx *det_ctx, + Flow *f, Packet *p, const Signature *s, uint8_t flags); #endif /* HAVE_LUA */ #endif diff --git a/src/detect-lua.c b/src/detect-lua.c index 673256709f..89bec7efc2 100644 --- a/src/detect-lua.c +++ b/src/detect-lua.c @@ -231,8 +231,7 @@ int DetectLuaMatchBuffer(DetectEngineThreadCtx *det_ctx, if (tlua == NULL) SCReturnInt(0); - LuaExtensionsMatchSetup(tlua->luastate, lua, det_ctx, - f, /* no packet in the ctx */NULL, 0); + LuaExtensionsMatchSetup(tlua->luastate, lua, det_ctx, f, /* no packet in the ctx */ NULL, s, 0); /* prepare data to pass to script */ lua_getglobal(tlua->luastate, "match"); @@ -347,8 +346,7 @@ static int DetectLuaMatch (DetectEngineThreadCtx *det_ctx, LuaStateSetThreadVars(tlua->luastate, det_ctx->tv); - LuaExtensionsMatchSetup(tlua->luastate, lua, det_ctx, - p->flow, p, flags); + LuaExtensionsMatchSetup(tlua->luastate, lua, det_ctx, p->flow, p, s, flags); if ((tlua->flags & DATATYPE_PAYLOAD) && p->payload_len == 0) SCReturnInt(0); @@ -480,8 +478,7 @@ static int DetectLuaAppMatchCommon (DetectEngineThreadCtx *det_ctx, SCReturnInt(0); /* setup extension data for use in lua c functions */ - LuaExtensionsMatchSetup(tlua->luastate, lua, det_ctx, - f, NULL, flags); + LuaExtensionsMatchSetup(tlua->luastate, lua, det_ctx, f, NULL, s, flags); if (tlua->alproto != ALPROTO_UNKNOWN) { int alproto = f->alproto; diff --git a/src/util-lua-common.c b/src/util-lua-common.c index 0d46efad67..671904e0e5 100644 --- a/src/util-lua-common.c +++ b/src/util-lua-common.c @@ -548,54 +548,61 @@ static int LuaCallbackFlowId(lua_State *luastate) } /** \internal - * \brief fill lua stack with alert info + * \brief fill lua stack with signature info * \param luastate the lua state - * \param pa pointer to packet alert struct + * \param s pointer to signature struct * \retval cnt number of data items placed on the stack * * Places: sid (number), rev (number), gid (number) */ -static int LuaCallbackRuleIdsPushToStackFromPacketAlert(lua_State *luastate, const PacketAlert *pa) +static int LuaCallbackRuleIdsPushToStackFromSignature(lua_State *luastate, const Signature *s) { - lua_pushinteger(luastate, pa->s->id); - lua_pushinteger(luastate, pa->s->rev); - lua_pushinteger(luastate, pa->s->gid); + lua_pushinteger(luastate, s->id); + lua_pushinteger(luastate, s->rev); + lua_pushinteger(luastate, s->gid); return 3; } /** \internal * \brief Wrapper for getting tuple info into a lua script * \retval cnt number of items placed on the stack + * + * Info is pulled from PacketAlert if it exists in lua registry (true for logging scripts) + * otherwise pulled from Signature in lua registry (for match scripts) */ static int LuaCallbackRuleIds(lua_State *luastate) { + const Signature *s = NULL; const PacketAlert *pa = LuaStateGetPacketAlert(luastate); - if (pa == NULL) - return LuaCallbackError(luastate, "internal error: no packet"); - - return LuaCallbackRuleIdsPushToStackFromPacketAlert(luastate, pa); + if (pa != NULL) { + s = pa->s; + } else { + s = LuaStateGetSignature(luastate); + if (s == NULL) + return LuaCallbackError(luastate, "internal error: no packet alert or signature"); + } + return LuaCallbackRuleIdsPushToStackFromSignature(luastate, s); } /** \internal - * \brief fill lua stack with alert info + * \brief fill lua stack with signature info * \param luastate the lua state - * \param pa pointer to packet alert struct + * \param s pointer to signature struct * \retval cnt number of data items placed on the stack * * Places: action (string) */ -static int LuaCallbackRuleActionPushToStackFromPacketAlert( - lua_State *luastate, const PacketAlert *pa) +static int LuaCallbackRuleActionPushToStackFromSignature(lua_State *luastate, const Signature *s) { const char *action = ""; - if (pa->s->action & ACTION_PASS) { + if (s->action & ACTION_PASS) { action = "pass"; - } else if ((pa->s->action & ACTION_REJECT) || (pa->s->action & ACTION_REJECT_BOTH) || - (pa->s->action & ACTION_REJECT_DST)) { + } else if ((s->action & ACTION_REJECT) || (s->action & ACTION_REJECT_BOTH) || + (s->action & ACTION_REJECT_DST)) { action = "reject"; - } else if (pa->s->action & ACTION_DROP) { + } else if (s->action & ACTION_DROP) { action = "drop"; - } else if (pa->s->action & ACTION_ALERT) { + } else if (s->action & ACTION_ALERT) { action = "alert"; } lua_pushstring(luastate, action); @@ -605,69 +612,93 @@ static int LuaCallbackRuleActionPushToStackFromPacketAlert( /** \internal * \brief Wrapper for getting tuple info into a lua script * \retval cnt number of items placed on the stack + * + * Info is pulled from PacketAlert if it exists in lua registry (true for logging scripts) + * otherwise pulled from Signature in lua registry (for match scripts) */ static int LuaCallbackRuleAction(lua_State *luastate) { + const Signature *s = NULL; const PacketAlert *pa = LuaStateGetPacketAlert(luastate); - if (pa == NULL) - return LuaCallbackError(luastate, "internal error: no packet"); - - return LuaCallbackRuleActionPushToStackFromPacketAlert(luastate, pa); + if (pa != NULL) { + s = pa->s; + } else { + s = LuaStateGetSignature(luastate); + if (s == NULL) + return LuaCallbackError(luastate, "internal error: no packet alert or signature"); + } + return LuaCallbackRuleActionPushToStackFromSignature(luastate, s); } /** \internal - * \brief fill lua stack with alert info + * \brief fill lua stack with signature info * \param luastate the lua state - * \param pa pointer to packet alert struct + * \param s pointer to signature struct * \retval cnt number of data items placed on the stack * * Places: msg (string) */ -static int LuaCallbackRuleMsgPushToStackFromPacketAlert(lua_State *luastate, const PacketAlert *pa) +static int LuaCallbackRuleMsgPushToStackFromSignature(lua_State *luastate, const Signature *s) { - lua_pushstring (luastate, pa->s->msg); + lua_pushstring(luastate, s->msg); return 1; } /** \internal * \brief Wrapper for getting tuple info into a lua script * \retval cnt number of items placed on the stack + * + * Info is pulled from PacketAlert if it exists in lua registry (true for logging scripts) + * otherwise pulled from Signature in lua registry (for match scripts) */ static int LuaCallbackRuleMsg(lua_State *luastate) { + const Signature *s = NULL; const PacketAlert *pa = LuaStateGetPacketAlert(luastate); - if (pa == NULL) - return LuaCallbackError(luastate, "internal error: no packet"); - - return LuaCallbackRuleMsgPushToStackFromPacketAlert(luastate, pa); + if (pa != NULL) { + s = pa->s; + } else { + s = LuaStateGetSignature(luastate); + if (s == NULL) + return LuaCallbackError(luastate, "internal error: no packet alert or signature"); + } + return LuaCallbackRuleMsgPushToStackFromSignature(luastate, s); } /** \internal - * \brief fill lua stack with alert info + * \brief fill lua stack with signature info * \param luastate the lua state - * \param pa pointer to packet alert struct + * \param s pointer to signature struct * \retval cnt number of data items placed on the stack * * Places: class (string), prio (number) */ -static int LuaCallbackRuleClassPushToStackFromPacketAlert(lua_State *luastate, const PacketAlert *pa) +static int LuaCallbackRuleClassPushToStackFromSignature(lua_State *luastate, const Signature *s) { - lua_pushstring (luastate, pa->s->class_msg); - lua_pushnumber (luastate, pa->s->prio); + lua_pushstring(luastate, s->class_msg); + lua_pushinteger(luastate, s->prio); return 2; } /** \internal * \brief Wrapper for getting tuple info into a lua script * \retval cnt number of items placed on the stack + * + * Info is pulled from PacketAlert if it exists in lua registry (true for logging scripts) + * otherwise pulled from Signature in lua registry (for match scripts) */ static int LuaCallbackRuleClass(lua_State *luastate) { + const Signature *s = NULL; const PacketAlert *pa = LuaStateGetPacketAlert(luastate); - if (pa == NULL) - return LuaCallbackError(luastate, "internal error: no packet"); - - return LuaCallbackRuleClassPushToStackFromPacketAlert(luastate, pa); + if (pa != NULL) { + s = pa->s; + } else { + s = LuaStateGetSignature(luastate); + if (s == NULL) + return LuaCallbackError(luastate, "internal error: no packet alert or signature"); + } + return LuaCallbackRuleClassPushToStackFromSignature(luastate, s); } static int LuaCallbackLogPath(lua_State *luastate) diff --git a/src/util-lua.c b/src/util-lua.c index f03216f85a..86969348f9 100644 --- a/src/util-lua.c +++ b/src/util-lua.c @@ -97,6 +97,8 @@ const char lua_ext_key_direction[] = "suricata:lua:direction"; /* key for pa (packet alert) pointer */ const char lua_ext_key_pa[] = "suricata:lua:pkt:alert:ptr"; +/* key for s (signature) pointer */ +const char lua_ext_key_s[] = "suricata:lua:signature:ptr"; /* key for file pointer */ const char lua_ext_key_file[] = "suricata:lua:file:ptr"; /* key for streaming buffer pointer */ @@ -195,6 +197,22 @@ void LuaStateSetPacketAlert(lua_State *luastate, PacketAlert *pa) lua_settable(luastate, LUA_REGISTRYINDEX); } +/** \brief get signature pointer from the lua state */ +Signature *LuaStateGetSignature(lua_State *luastate) +{ + lua_pushlightuserdata(luastate, (void *)&lua_ext_key_s); + lua_gettable(luastate, LUA_REGISTRYINDEX); + void *s = lua_touserdata(luastate, -1); + return (Signature *)s; +} + +void LuaStateSetSignature(lua_State *luastate, const Signature *s) +{ + lua_pushlightuserdata(luastate, (void *)&lua_ext_key_s); + lua_pushlightuserdata(luastate, (void *)s); + lua_settable(luastate, LUA_REGISTRYINDEX); +} + /** \brief get file pointer from the lua state */ File *LuaStateGetFile(lua_State *luastate) { diff --git a/src/util-lua.h b/src/util-lua.h index 7d655a6aab..273b786eae 100644 --- a/src/util-lua.h +++ b/src/util-lua.h @@ -63,6 +63,8 @@ Flow *LuaStateGetFlow(lua_State *luastate); PacketAlert *LuaStateGetPacketAlert(lua_State *luastate); +Signature *LuaStateGetSignature(lua_State *luastate); + /** \brief get file pointer from the lua state */ File *LuaStateGetFile(lua_State *luastate); @@ -83,6 +85,8 @@ void LuaStateSetFlow(lua_State *luastate, Flow *f); void LuaStateSetPacketAlert(lua_State *luastate, PacketAlert *pa); +void LuaStateSetSignature(lua_State *luastate, const Signature *s); + void LuaStateSetFile(lua_State *luastate, File *file); void LuaStateSetThreadVars(lua_State *luastate, ThreadVars *tv);