From dc48ac9143e0306ebca2eb780540363b0a9bbef4 Mon Sep 17 00:00:00 2001 From: Vsevolod Stakhov Date: Fri, 5 Feb 2016 12:42:43 +0000 Subject: [PATCH] Fix leaks in lua error paths --- src/libmime/mime_expressions.c | 1 + src/libserver/cfg_rcl.c | 2 +- src/libserver/cfg_utils.c | 2 ++ src/libserver/symbols_cache.c | 1 + src/libserver/task.c | 1 + src/lua/lua_buffer.c | 3 +++ src/lua/lua_classifier.c | 3 +++ src/lua/lua_common.c | 7 +++++-- src/lua/lua_config.c | 6 +++++- src/lua/lua_dns.c | 1 + src/lua/lua_expression.c | 12 ++++++++---- src/lua/lua_http.c | 2 ++ src/lua/lua_mempool.c | 1 + src/lua/lua_redis.c | 2 ++ src/lua/lua_session.c | 11 +++++++++-- src/lua/lua_tcp.c | 2 ++ src/lua/lua_trie.c | 1 + src/lua_worker.c | 2 ++ src/plugins/regexp.c | 3 +++ src/rspamadm/rspamadm.c | 2 +- 20 files changed, 54 insertions(+), 11 deletions(-) diff --git a/src/libmime/mime_expressions.c b/src/libmime/mime_expressions.c index 411c301eb..6a422e82e 100644 --- a/src/libmime/mime_expressions.c +++ b/src/libmime/mime_expressions.c @@ -836,6 +836,7 @@ rspamd_mime_expr_process (gpointer input, rspamd_expression_atom_t *atom) mime_atom->d.lua_function, mime_atom->str, lua_tostring (L, -1)); + lua_pop (L, 1); } else { if (lua_type (L, -1) == LUA_TBOOLEAN) { diff --git a/src/libserver/cfg_rcl.c b/src/libserver/cfg_rcl.c index df9768792..ffc6f9086 100644 --- a/src/libserver/cfg_rcl.c +++ b/src/libserver/cfg_rcl.c @@ -772,7 +772,7 @@ rspamd_rcl_lua_handler (rspamd_mempool_t *pool, const ucl_object_t *obj, lua_src, tb->str); g_string_free (tb, TRUE); - lua_pop (L, 1); + lua_pop (L, 2); if (chdir (cur_dir) == -1) { msg_err_config ("cannot chdir to %s: %s", cur_dir, diff --git a/src/libserver/cfg_utils.c b/src/libserver/cfg_utils.c index 6ecd7b429..66a67fe13 100644 --- a/src/libserver/cfg_utils.c +++ b/src/libserver/cfg_utils.c @@ -379,6 +379,8 @@ rspamd_config_process_var (struct rspamd_config *cfg, const rspamd_ftok_t *var, if (lua_pcall (cfg->lua_state, 0, 1, 0) != 0) { msg_err_config ("error executing lua code: '%T': %s", content, lua_tostring (cfg->lua_state, -1)); + lua_pop (cfg->lua_state, 1); + return FALSE; } diff --git a/src/libserver/symbols_cache.c b/src/libserver/symbols_cache.c index 53c065dfd..50012c1a9 100644 --- a/src/libserver/symbols_cache.c +++ b/src/libserver/symbols_cache.c @@ -1048,6 +1048,7 @@ rspamd_symbols_cache_check_symbol (struct rspamd_task *task, if (lua_pcall (L, 1, 1, 0) != 0) { msg_info_task ("call to condition for %s failed: %s", item->symbol, lua_tostring (L, -1)); + lua_pop (L, 1); } else { check = lua_toboolean (L, -1); diff --git a/src/libserver/task.c b/src/libserver/task.c index 4194ac94c..1220dc4bc 100644 --- a/src/libserver/task.c +++ b/src/libserver/task.c @@ -1076,6 +1076,7 @@ rspamd_task_write_log (struct rspamd_task *task) if (lua_pcall (L, 1, 1, 0) != 0) { msg_err_task ("call to log function failed: %s", lua_tostring (L, -1)); + lua_pop (L, 1); } else { lua_str = lua_tolstring (L, -1, &lua_str_len); diff --git a/src/lua/lua_buffer.c b/src/lua/lua_buffer.c index aaa57f9d4..c644eae7d 100644 --- a/src/lua/lua_buffer.c +++ b/src/lua/lua_buffer.c @@ -90,6 +90,7 @@ lua_io_read_cb (rspamd_ftok_t * in, void *arg) if (lua_pcall (cbdata->L, 2, 1, 0) != 0) { msg_info ("call to session finalizer failed: %s", lua_tostring (cbdata->L, -1)); + lua_pop (cbdata->L, 1); } res = lua_toboolean (cbdata->L, -1); @@ -118,6 +119,7 @@ lua_io_write_cb (void *arg) if (lua_pcall (cbdata->L, 1, 1, 0) != 0) { msg_info ("call to session finalizer failed: %s", lua_tostring (cbdata->L, -1)); + lua_pop (cbdata->L, 1); } res = lua_toboolean (cbdata->L, -1); @@ -144,6 +146,7 @@ lua_io_err_cb (GError * err, void *arg) if (lua_pcall (cbdata->L, 2, 0, 0) != 0) { msg_info ("call to session finalizer failed: %s", lua_tostring (cbdata->L, -1)); + lua_pop (cbdata->L, 1); } /* Unref callbacks */ diff --git a/src/lua/lua_classifier.c b/src/lua/lua_classifier.c index 64edea234..d8add5e4d 100644 --- a/src/lua/lua_classifier.c +++ b/src/lua/lua_classifier.c @@ -90,6 +90,7 @@ call_classifier_pre_callback (struct rspamd_classifier_config *ccf, if (lua_pcall (L, 4, 1, 0) != 0) { msg_warn_task ("error running pre classifier callback %s", lua_tostring (L, -1)); + lua_pop (L, 1); } else { if (lua_istable (L, -1)) { @@ -102,6 +103,7 @@ call_classifier_pre_callback (struct rspamd_classifier_config *ccf, lua_pop (L, 1); } } + lua_pop (L, 1); } return res; @@ -186,6 +188,7 @@ rspamd_lua_call_cls_post_callbacks (struct rspamd_classifier_config *ccf, if (lua_pcall (L, 3, 1, 0) != 0) { msg_warn_task ("error running function %s: %s", cd->name, lua_tostring (L, -1)); + lua_pop (L, 1); } else { if (lua_isnumber (L, 1)) { diff --git a/src/lua/lua_common.c b/src/lua/lua_common.c index 8899dc116..eb3b7de3f 100644 --- a/src/lua/lua_common.c +++ b/src/lua/lua_common.c @@ -344,7 +344,7 @@ rspamd_init_lua_filters (struct rspamd_config *cfg) gint rspamd_lua_call_filter (const gchar *function, struct rspamd_task *task) { - gint result; + gint result = 0; struct rspamd_task **ptask; lua_State *L = task->cfg->lua_state; @@ -361,7 +361,10 @@ rspamd_lua_call_filter (const gchar *function, struct rspamd_task *task) if (!lua_isnumber (L, -1)) { msg_info_task ("function %s must return a number", function); } - result = lua_tonumber (L, -1); + else { + result = lua_tonumber (L, -1); + } + lua_pop (L, 1); /* pop returned value */ return result; diff --git a/src/lua/lua_config.c b/src/lua/lua_config.c index 7abaf3842..815959898 100644 --- a/src/lua/lua_config.c +++ b/src/lua/lua_config.c @@ -636,6 +636,7 @@ rspamd_lua_call_post_filters (struct rspamd_task *task) cd->cb_is_ref ? "local function" : cd->callback.name, lua_tostring (cd->L, -1)); + lua_pop (cd->L, 1); } cur = g_list_next (cur); } @@ -704,6 +705,7 @@ rspamd_lua_call_pre_filters (struct rspamd_task *task) cd->cb_is_ref ? "local function" : cd->callback.name, lua_tostring (cd->L, -1)); + lua_pop (cd->L, 1); } cur = g_list_next (cur); } @@ -965,8 +967,9 @@ lua_metric_symbol_callback (struct rspamd_task *task, gpointer ud) } rspamd_task_insert_result (task, cd->symbol, flag, opts); } + + lua_pop (L, nresults); } - lua_pop (L, nresults); } } @@ -1718,6 +1721,7 @@ lua_map_fin (rspamd_mempool_t * pool, struct map_cb_data *data) if (lua_pcall (cbdata->L, 1, 0, 0) != 0) { msg_info_pool ("call to %s failed: %s", "local function", lua_tostring (cbdata->L, -1)); + lua_pop (cbdata->L, 1); } } } diff --git a/src/lua/lua_dns.c b/src/lua/lua_dns.c index 2f2e54a1a..c52569225 100644 --- a/src/lua/lua_dns.c +++ b/src/lua/lua_dns.c @@ -200,6 +200,7 @@ lua_dns_callback (struct rdns_reply *reply, gpointer arg) if (lua_pcall (cd->L, 5, 0, 0) != 0) { msg_info ("call to dns callback failed: %s", lua_tostring (cd->L, -1)); + lua_pop (cd->L, 1); } /* Unref function */ diff --git a/src/lua/lua_expression.c b/src/lua/lua_expression.c index 5bb7293eb..fe52e929b 100644 --- a/src/lua/lua_expression.c +++ b/src/lua/lua_expression.c @@ -135,6 +135,8 @@ lua_atom_parse (const gchar *line, gsize len, if (lua_pcall (e->L, 1, 1, 0) != 0) { msg_info ("callback call failed: %s", lua_tostring (e->L, -1)); + lua_pop (e->L, 1); + return NULL; } if (lua_type (e->L, -1) != LUA_TSTRING) { @@ -158,7 +160,7 @@ static gint lua_atom_process (gpointer input, rspamd_expression_atom_t *atom) { struct lua_expression *e = (struct lua_expression *)atom->data; - gint ret; + gint ret = 0; lua_rawgeti (e->L, LUA_REGISTRYINDEX, e->process_idx); lua_pushlstring (e->L, atom->str, atom->len); @@ -166,10 +168,12 @@ lua_atom_process (gpointer input, rspamd_expression_atom_t *atom) if (lua_pcall (e->L, 2, 1, 0) != 0) { msg_info ("callback call failed: %s", lua_tostring (e->L, -1)); + lua_pop (e->L, 1); + } + else { + ret = lua_tonumber (e->L, -1); + lua_pop (e->L, 1); } - - ret = lua_tonumber (e->L, -1); - lua_pop (e->L, 1); return ret; } diff --git a/src/lua/lua_http.c b/src/lua/lua_http.c index 07a4cc286..5f2dd2416 100644 --- a/src/lua/lua_http.c +++ b/src/lua/lua_http.c @@ -132,6 +132,7 @@ lua_http_push_error (struct lua_http_cbdata *cbd, const char *err) if (lua_pcall (cbd->L, 1, 0, 0) != 0) { msg_info ("callback call failed: %s", lua_tostring (cbd->L, -1)); + lua_pop (cbd->L, 1); } } @@ -167,6 +168,7 @@ lua_http_finish_handler (struct rspamd_http_connection *conn, } if (lua_pcall (cbd->L, 4, 0, 0) != 0) { msg_info ("callback call failed: %s", lua_tostring (cbd->L, -1)); + lua_pop (cbd->L, 1); } lua_http_maybe_free (cbd); diff --git a/src/lua/lua_mempool.c b/src/lua/lua_mempool.c index d5825d1e3..00c2c24e0 100644 --- a/src/lua/lua_mempool.c +++ b/src/lua/lua_mempool.c @@ -163,6 +163,7 @@ lua_mempool_destructor_func (gpointer p) lua_rawgeti (ud->L, LUA_REGISTRYINDEX, ud->cbref); if (lua_pcall (ud->L, 0, 0, 0) != 0) { msg_info ("call to destructor failed: %s", lua_tostring (ud->L, -1)); + lua_pop (ud->L, 1); } luaL_unref (ud->L, LUA_REGISTRYINDEX, ud->cbref); } diff --git a/src/lua/lua_redis.c b/src/lua/lua_redis.c index 24f3c93af..4e02107f5 100644 --- a/src/lua/lua_redis.c +++ b/src/lua/lua_redis.c @@ -190,6 +190,7 @@ lua_redis_push_error (const gchar *err, lua_pushnil (ud->L); if (lua_pcall (ud->L, 3, 0, 0) != 0) { msg_info ("call to callback failed: %s", lua_tostring (ud->L, -1)); + lua_pop (ud->L, 1); } if (connected) { @@ -251,6 +252,7 @@ lua_redis_push_data (const redisReply *r, struct lua_redis_ctx *ctx) if (lua_pcall (ud->L, 3, 0, 0) != 0) { msg_info ("call to callback failed: %s", lua_tostring (ud->L, -1)); + lua_pop (ud->L, 1); } rspamd_session_remove_event (ud->task->s, lua_redis_fin, ctx); diff --git a/src/lua/lua_session.c b/src/lua/lua_session.c index 3d42bc80e..033ed892b 100644 --- a/src/lua/lua_session.c +++ b/src/lua/lua_session.c @@ -89,9 +89,13 @@ lua_session_finalizer (gpointer ud) if (lua_pcall (cbdata->L, 0, 1, 0) != 0) { msg_info ("call to session finalizer failed: %s", lua_tostring (cbdata->L, -1)); + lua_pop (cbdata->L, 1); } - res = lua_toboolean (cbdata->L, -1); - lua_pop (cbdata->L, 1); + else { + res = lua_toboolean (cbdata->L, -1); + lua_pop (cbdata->L, 1); + } + luaL_unref (cbdata->L, LUA_REGISTRYINDEX, cbdata->cbref_fin); @@ -110,6 +114,7 @@ lua_session_restore (gpointer ud) if (lua_pcall (cbdata->L, 0, 0, 0) != 0) { msg_info ("call to session restorer failed: %s", lua_tostring (cbdata->L, -1)); + lua_pop (cbdata->L, 1); } luaL_unref (cbdata->L, LUA_REGISTRYINDEX, cbdata->cbref_restore); } @@ -127,6 +132,7 @@ lua_session_cleanup (gpointer ud) if (lua_pcall (cbdata->L, 0, 0, 0) != 0) { msg_info ("call to session cleanup failed: %s", lua_tostring (cbdata->L, -1)); + lua_pop (cbdata->L, 1); } luaL_unref (cbdata->L, LUA_REGISTRYINDEX, cbdata->cbref_cleanup); } @@ -224,6 +230,7 @@ lua_event_fin (gpointer ud) if (lua_pcall (cbdata->L, 0, 0, 0) != 0) { msg_info ("call to event finalizer failed: %s", lua_tostring (cbdata->L, -1)); + lua_pop (cbdata->L, 1); } luaL_unref (cbdata->L, LUA_REGISTRYINDEX, cbdata->cbref); } diff --git a/src/lua/lua_tcp.c b/src/lua/lua_tcp.c index efe5cadfa..1745abdc9 100644 --- a/src/lua/lua_tcp.c +++ b/src/lua/lua_tcp.c @@ -127,6 +127,7 @@ lua_tcp_push_error (struct lua_tcp_cbdata *cbd, const char *err) if (lua_pcall (cbd->L, 1, 0, 0) != 0) { msg_info ("callback call failed: %s", lua_tostring (cbd->L, -1)); + lua_pop (cbd->L, 1); } } @@ -147,6 +148,7 @@ lua_tcp_push_data (struct lua_tcp_cbdata *cbd, const gchar *str, gsize len) if (lua_pcall (cbd->L, 2, 0, 0) != 0) { msg_info ("callback call failed: %s", lua_tostring (cbd->L, -1)); + lua_pop (cbd->L, 1); } } diff --git a/src/lua/lua_trie.c b/src/lua/lua_trie.c index 4f60663da..987818608 100644 --- a/src/lua/lua_trie.c +++ b/src/lua/lua_trie.c @@ -156,6 +156,7 @@ lua_trie_callback (int strnum, int textpos, void *context) if (lua_pcall (L, 2, 1, 0) != 0) { msg_info ("call to trie callback has failed: %s", lua_tostring (L, -1)); + lua_pop (L, 1); return 1; } diff --git a/src/lua_worker.c b/src/lua_worker.c index cb0524638..60456b59f 100644 --- a/src/lua_worker.c +++ b/src/lua_worker.c @@ -286,6 +286,7 @@ lua_accept_socket (gint fd, short what, void *arg) if (lua_pcall (L, 4, 0, 0) != 0) { msg_info ("call to worker accept failed: %s", lua_tostring (L, -1)); + lua_pop (L, 1); } rspamd_inet_address_destroy (addr); @@ -402,6 +403,7 @@ start_lua_worker (struct rspamd_worker *worker) if (lua_pcall (L, 1, 0, 0) != 0) { msg_info ("call to worker finalizer failed: %s", lua_tostring (L, -1)); + lua_pop (L, 1); } /* Free resources */ luaL_unref (L, LUA_REGISTRYINDEX, ctx->cbref_fin); diff --git a/src/plugins/regexp.c b/src/plugins/regexp.c index 00c7ec470..7273d87d7 100644 --- a/src/plugins/regexp.c +++ b/src/plugins/regexp.c @@ -343,8 +343,11 @@ rspamd_lua_call_expression_func (struct ucl_lua_funcdata *lua_data, if (lua_pcall (L, nargs + 1, 1, 0) != 0) { msg_info_task ("%s: call to lua function failed: %s", symbol, lua_tostring (L, -1)); + lua_pop (L, 1); + return FALSE; } + pop++; if (lua_type (L, -1) == LUA_TNUMBER) { diff --git a/src/rspamadm/rspamadm.c b/src/rspamadm/rspamadm.c index 37b455788..d91b66304 100644 --- a/src/rspamadm/rspamadm.c +++ b/src/rspamadm/rspamadm.c @@ -248,7 +248,7 @@ rspamadm_execute_lua_ucl_subr (gpointer pL, gint argc, gchar **argv, g_string_free (tb, TRUE); } - lua_pop (L, 1); + lua_pop (L, 2); return FALSE; } -- 2.39.5