From 42646579a82ab34242ef4dc4a66c6fcaa06595cf Mon Sep 17 00:00:00 2001 From: Victor Julien Date: Sun, 9 Sep 2012 15:46:11 +0200 Subject: [PATCH] luajit: clean up initialization --- src/detect-luajit.c | 239 +++++++++++++++++++++++++++----------------- src/detect-luajit.h | 2 + src/util-error.c | 1 + src/util-error.h | 1 + 4 files changed, 154 insertions(+), 89 deletions(-) diff --git a/src/detect-luajit.c b/src/detect-luajit.c index 8b670a329d..572fce8343 100644 --- a/src/detect-luajit.c +++ b/src/detect-luajit.c @@ -167,7 +167,7 @@ static int DetectLuajitMatch (ThreadVars *tv, DetectEngineThreadCtx *det_ctx, SCReturnInt(0); if ((tluajit->flags & DATATYPE_PACKET) && GET_PKT_LEN(p) == 0) SCReturnInt(0); - if (tluajit->alproto != 0) { + if (tluajit->alproto != ALPROTO_UNKNOWN) { if (p->flow == NULL) SCReturnInt(0); @@ -204,17 +204,20 @@ static int DetectLuajitMatch (ThreadVars *tv, DetectEngineThreadCtx *det_ctx, for ( ; idx < size; idx++) { tx = list_get(htp_state->connp->conn->transactions, idx); - if (tx == NULL || tx->request_uri_normalized == NULL) + if (tx == NULL) continue; - if ((tluajit->flags & DATATYPE_HTTP_URI) && bstr_len(tx->request_uri_normalized) > 0) { + if ((tluajit->flags & DATATYPE_HTTP_URI) && tx->request_uri_normalized != NULL && + bstr_len(tx->request_uri_normalized) > 0) + { lua_pushliteral(tluajit->luastate, "http.uri"); /* stack at -2 */ lua_pushlstring (tluajit->luastate, (const char *)bstr_ptr(tx->request_uri_normalized), bstr_len(tx->request_uri_normalized)); lua_settable(tluajit->luastate, -3); } - if ((tluajit->flags & DATATYPE_HTTP_REQUEST_LINE) && bstr_len(tx->request_line) > 0) { + if ((tluajit->flags & DATATYPE_HTTP_REQUEST_LINE) && tx->request_line != NULL && + bstr_len(tx->request_line) > 0) { lua_pushliteral(tluajit->luastate, "http.request_line"); /* stack at -2 */ lua_pushlstring (tluajit->luastate, (const char *)bstr_ptr(tx->request_line), @@ -282,103 +285,54 @@ static int DetectLuajitMatch (ThreadVars *tv, DetectEngineThreadCtx *det_ctx, } static void *DetectLuajitThreadInit(void *data) { - DetectLuajitThreadData *t = SCMalloc(sizeof(DetectLuajitThreadData)); - if (t != NULL) { - memset(t, 0x00, sizeof(DetectLuajitThreadData)); - - t->luastate = luaL_newstate(); - BUG_ON(t->luastate == NULL); - luaL_openlibs(t->luastate); - - int status = luaL_loadfile(t->luastate, (char *)data); - if (status) { - fprintf(stderr, "Couldn't load file: %s\n", lua_tostring(t->luastate, -1)); - BUG_ON(1); - } - - /* prime the script (or something) */ - if (lua_pcall(t->luastate, 0, 0, 0) != 0) { - fprintf(stderr, "Couldn't prime file: %s\n", lua_tostring(t->luastate, -1)); - BUG_ON(1); - } - - lua_getglobal(t->luastate, "init"); - if (lua_type(t->luastate, -1) != LUA_TFUNCTION) { - SCLogInfo("no init function in script"); - /** \todo proper cleanup */ - return NULL; - } - - lua_newtable(t->luastate); /* stack at -1 */ - if (lua_gettop(t->luastate) == 0 || lua_type(t->luastate, 2) != LUA_TTABLE) { - SCLogInfo("no table setup"); - /** \todo proper cleanup */ - return NULL; - } + DetectLuajitData *luajit = (DetectLuajitData *)data; + BUG_ON(luajit == NULL); - lua_pushliteral(t->luastate, "script_api_ver"); /* stack at -2 */ - lua_pushnumber (t->luastate, 1); /* stack at -3 */ - lua_settable(t->luastate, -3); + DetectLuajitThreadData *t = SCMalloc(sizeof(DetectLuajitThreadData)); + if (t == NULL) { + SCLogError(SC_ERR_LUAJIT_ERROR, "couldn't alloc ctx memory"); + return NULL; + } + memset(t, 0x00, sizeof(DetectLuajitThreadData)); - if (lua_pcall(t->luastate, 1, 1, 0) != 0) { - fprintf(stderr, "Couldn't prime file: %s\n", lua_tostring(t->luastate, -1)); - BUG_ON(1); - } + t->alproto = luajit->alproto; + t->flags = luajit->flags; - /* process returns from script */ - if (lua_gettop(t->luastate) == 0) { - SCLogInfo("init function in script should return table, nothing returned"); - /** \todo proper cleanup */ - return NULL; - } - if (lua_type(t->luastate, 1) != LUA_TTABLE) { - SCLogInfo("init function in script should return table, returned is not table"); - /** \todo proper cleanup */ - return NULL; - } + t->luastate = luaL_newstate(); + if (t->luastate == NULL) { + SCLogError(SC_ERR_LUAJIT_ERROR, "couldn't load file: %s", lua_tostring(t->luastate, -1)); + goto error; + } - lua_pushnil(t->luastate); - const char *k, *v; - while (lua_next(t->luastate, -2)) { - v = lua_tostring(t->luastate, -1); - lua_pop(t->luastate, 1); - k = lua_tostring(t->luastate, -1); - - if (!k || !v) - continue; - - SCLogDebug("k='%s', v='%s'", k, v); - if (strcmp(k, "packet") == 0 && strcmp(v, "true") == 0) { - t->flags |= DATATYPE_PACKET; - } else if (strcmp(k, "payload") == 0 && strcmp(v, "true") == 0) { - t->flags |= DATATYPE_PAYLOAD; - } else if (strncmp(k, "http", 4) == 0 && strcmp(v, "true") == 0) { - /* http types */ - t->alproto = ALPROTO_HTTP; - - if (strcmp(k, "http.uri") == 0) - t->flags |= DATATYPE_HTTP_URI; - else if (strcmp(k, "http.request_line") == 0) - t->flags |= DATATYPE_HTTP_REQUEST_LINE; - else { - SCLogInfo("unsupported http data type %s", k); - } + luaL_openlibs(t->luastate); - } else { - SCLogInfo("unsupported data type %s", k); - } - } + int status = luaL_loadfile(t->luastate, luajit->filename); + if (status) { + SCLogError(SC_ERR_LUAJIT_ERROR, "couldn't load file: %s", lua_tostring(t->luastate, -1)); + goto error; + } - /* pop the table */ - lua_pop(t->luastate, 1); + /* prime the script (or something) */ + if (lua_pcall(t->luastate, 0, 0, 0) != 0) { + SCLogError(SC_ERR_LUAJIT_ERROR, "couldn't prime file: %s", lua_tostring(t->luastate, -1)); + goto error; } + + /* pop the table */ + lua_pop(t->luastate, 1); return (void *)t; + +error: + if (t->luastate) + lua_close(t->luastate); + SCFree(t); + return NULL; } static void DetectLuajitThreadFree(void *ctx) { DetectLuajitThreadData *t = (DetectLuajitThreadData *)ctx; - /** \todo lua state cleanup */ + lua_close(t->luastate); SCFree(t); } @@ -421,6 +375,102 @@ error: return NULL; } +static int DetectLuaSetupPrime(DetectLuajitData *ld) { + lua_State *luastate = luaL_newstate(); + if (luastate == NULL) + goto error; + luaL_openlibs(luastate); + + int status = luaL_loadfile(luastate, ld->filename); + if (status) { + SCLogError(SC_ERR_LUAJIT_ERROR, "couldn't load file: %s", lua_tostring(luastate, -1)); + goto error; + } + + /* prime the script (or something) */ + if (lua_pcall(luastate, 0, 0, 0) != 0) { + SCLogError(SC_ERR_LUAJIT_ERROR, "couldn't prime file: %s", lua_tostring(luastate, -1)); + goto error; + } + + lua_getglobal(luastate, "init"); + if (lua_type(luastate, -1) != LUA_TFUNCTION) { + SCLogError(SC_ERR_LUAJIT_ERROR, "no init function in script"); + goto error; + } + + lua_newtable(luastate); /* stack at -1 */ + if (lua_gettop(luastate) == 0 || lua_type(luastate, 2) != LUA_TTABLE) { + SCLogError(SC_ERR_LUAJIT_ERROR, "no table setup"); + goto error; + } + + lua_pushliteral(luastate, "script_api_ver"); /* stack at -2 */ + lua_pushnumber (luastate, 1); /* stack at -3 */ + lua_settable(luastate, -3); + + if (lua_pcall(luastate, 1, 1, 0) != 0) { + SCLogError(SC_ERR_LUAJIT_ERROR, "couldn't run script 'init' function: %s", lua_tostring(luastate, -1)); + goto error; + } + + /* process returns from script */ + if (lua_gettop(luastate) == 0) { + SCLogError(SC_ERR_LUAJIT_ERROR, "init function in script should return table, nothing returned"); + goto error; + } + if (lua_type(luastate, 1) != LUA_TTABLE) { + SCLogError(SC_ERR_LUAJIT_ERROR, "init function in script should return table, returned is not table"); + goto error; + } + + lua_pushnil(luastate); + const char *k, *v; + while (lua_next(luastate, -2)) { + v = lua_tostring(luastate, -1); + lua_pop(luastate, 1); + k = lua_tostring(luastate, -1); + if (!k || !v) + continue; + + SCLogDebug("k='%s', v='%s'", k, v); + if (strcmp(k, "packet") == 0 && strcmp(v, "true") == 0) { + ld->flags |= DATATYPE_PACKET; + } else if (strcmp(k, "payload") == 0 && strcmp(v, "true") == 0) { + ld->flags |= DATATYPE_PAYLOAD; + } else if (strncmp(k, "http", 4) == 0 && strcmp(v, "true") == 0) { + if (ld->alproto != ALPROTO_UNKNOWN) { + SCLogError(SC_ERR_LUAJIT_ERROR, "can just inspect script against one alproto %s", k); + goto error; + } + + /* http types */ + ld->alproto = ALPROTO_HTTP; + + if (strcmp(k, "http.uri") == 0) + ld->flags |= DATATYPE_HTTP_URI; + else if (strcmp(k, "http.request_line") == 0) + ld->flags |= DATATYPE_HTTP_REQUEST_LINE; + else { + SCLogError(SC_ERR_LUAJIT_ERROR, "unsupported http data type %s", k); + goto error; + } + + } else { + SCLogError(SC_ERR_LUAJIT_ERROR, "unsupported data type %s", k); + goto error; + } + } + + /* pop the table */ + lua_pop(luastate, 1); + lua_close(luastate); + return 0; +error: + lua_close(luastate); + return -1; +} + /** * \brief this function is used to parse luajit options * \brief into the current signature @@ -442,11 +492,22 @@ static int DetectLuajitSetup (DetectEngineCtx *de_ctx, Signature *s, char *str) goto error; luajit->thread_ctx_id = DetectRegisterThreadCtxFuncs(de_ctx, "luajit", - DetectLuajitThreadInit, (void *)luajit->filename, + DetectLuajitThreadInit, (void *)luajit, DetectLuajitThreadFree); if (luajit->thread_ctx_id == -1) goto error; + if (DetectLuaSetupPrime(luajit) == -1) { + goto error; + } + + if (luajit->alproto != ALPROTO_UNKNOWN) { + if (s->alproto != ALPROTO_UNKNOWN && luajit->alproto != s->alproto) { + goto error; + } + s->alproto = luajit->alproto; + } + /* Okay so far so good, lets get this into a SigMatch * and put it in the Signature. */ sm = SigMatchAlloc(); diff --git a/src/detect-luajit.h b/src/detect-luajit.h index 9264a59683..3cca94ec5d 100644 --- a/src/detect-luajit.h +++ b/src/detect-luajit.h @@ -40,6 +40,8 @@ typedef struct DetectLuajitData { int thread_ctx_id; int negated; char *filename; + uint32_t flags; + int alproto; } DetectLuajitData; #endif diff --git a/src/util-error.c b/src/util-error.c index c5b9605f97..1a3dc5a8d0 100644 --- a/src/util-error.c +++ b/src/util-error.c @@ -232,6 +232,7 @@ const char * SCErrorToString(SCError err) CASE_CODE (SC_ERR_NO_MD5_SUPPORT); CASE_CODE (SC_ERR_EVENT_ENGINE); CASE_CODE (SC_ERR_NO_LUAJIT_SUPPORT); + CASE_CODE (SC_ERR_LUAJIT_ERROR); default: return "UNKNOWN_ERROR"; } diff --git a/src/util-error.h b/src/util-error.h index 678d56f74d..4a98533aa1 100644 --- a/src/util-error.h +++ b/src/util-error.h @@ -247,6 +247,7 @@ typedef enum { SC_ERR_NO_MD5_SUPPORT, SC_ERR_EVENT_ENGINE, SC_ERR_NO_LUAJIT_SUPPORT, + SC_ERR_LUAJIT_ERROR, } SCError; const char *SCErrorToString(SCError); -- 2.47.3