From 7d40df5184f0aa6facde77e088d0751d4c475c6a Mon Sep 17 00:00:00 2001 From: Vsevolod Stakhov Date: Tue, 17 Jan 2017 19:19:47 +0000 Subject: [PATCH] [Fix] Various reload leak fixing --- src/fuzzy_storage.c | 14 ++++++++++---- src/libmime/mime_expressions.c | 14 ++++++++------ src/libserver/cfg_rcl.c | 12 ++++++------ src/lua/lua_common.c | 28 ++++++++++++++++++++++++++++ src/lua/lua_common.h | 9 +++++++++ src/plugins/dkim_check.c | 12 ++++++++++++ src/plugins/spf.c | 1 + src/rspamd_proxy.c | 14 ++++++++------ 8 files changed, 82 insertions(+), 22 deletions(-) diff --git a/src/fuzzy_storage.c b/src/fuzzy_storage.c index 01f00fe58..bfa3f3abf 100644 --- a/src/fuzzy_storage.c +++ b/src/fuzzy_storage.c @@ -1971,9 +1971,9 @@ fuzzy_parse_keypair (rspamd_mempool_t *pool, return FALSE; } - key = g_slice_alloc (sizeof (*key)); + key = rspamd_mempool_alloc0 (pool, sizeof (*key)); key->key = kp; - keystat = g_slice_alloc0 (sizeof (*keystat)); + keystat = rspamd_mempool_alloc0 (pool, sizeof (*keystat)); /* Hash of ip -> fuzzy_key_stat */ keystat->last_ips = rspamd_lru_hash_new_full (1024, (GDestroyNotify)rspamd_inet_address_destroy, fuzzy_key_stat_dtor, @@ -2027,12 +2027,20 @@ init_fuzzy (struct rspamd_config *cfg) ctx->keypair_cache_size = DEFAULT_KEYPAIR_CACHE_SIZE; ctx->keys = g_hash_table_new_full (fuzzy_kp_hash, fuzzy_kp_equal, NULL, fuzzy_key_dtor); + rspamd_mempool_add_destructor (cfg->cfg_pool, + (rspamd_mempool_destruct_t)g_hash_table_unref, ctx->keys); ctx->master_flags = g_hash_table_new (g_direct_hash, g_direct_equal); + rspamd_mempool_add_destructor (cfg->cfg_pool, + (rspamd_mempool_destruct_t)g_hash_table_unref, ctx->master_flags); ctx->errors_ips = rspamd_lru_hash_new_full (1024, (GDestroyNotify) rspamd_inet_address_destroy, g_free, rspamd_inet_address_hash, rspamd_inet_address_equal); + rspamd_mempool_add_destructor (cfg->cfg_pool, + (rspamd_mempool_destruct_t)rspamd_lru_hash_destroy, ctx->errors_ips); ctx->cfg = cfg; ctx->mirrors = g_ptr_array_new (); + rspamd_mempool_add_destructor (cfg->cfg_pool, + (rspamd_mempool_destruct_t)rspamd_ptr_array_free_hard, ctx->mirrors); ctx->updates_maxfail = DEFAULT_UPDATES_MAXFAIL; rspamd_rcl_register_worker_option (cfg, @@ -2417,8 +2425,6 @@ start_fuzzy (struct rspamd_worker *worker) rspamd_keypair_cache_destroy (ctx->keypair_cache); } - rspamd_lru_hash_destroy (ctx->errors_ips); - g_hash_table_unref (ctx->keys); REF_RELEASE (ctx->cfg); diff --git a/src/libmime/mime_expressions.c b/src/libmime/mime_expressions.c index 47dda6c05..ad5be8c0c 100644 --- a/src/libmime/mime_expressions.c +++ b/src/libmime/mime_expressions.c @@ -456,7 +456,7 @@ rspamd_mime_expr_parse_regexp_atom (rspamd_mempool_t * pool, const gchar *line, } struct rspamd_function_atom * -rspamd_mime_expr_parse_function_atom (const gchar *input) +rspamd_mime_expr_parse_function_atom (rspamd_mempool_t *pool, const gchar *input) { const gchar *obrace, *ebrace, *p, *c; gchar t, *databuf; @@ -477,10 +477,11 @@ rspamd_mime_expr_parse_function_atom (const gchar *input) g_assert (obrace != NULL && ebrace != NULL); - res = g_slice_alloc0 (sizeof (*res)); - res->name = g_malloc (obrace - input + 1); + res = rspamd_mempool_alloc0 (pool, sizeof (*res)); + res->name = rspamd_mempool_alloc (pool, obrace - input + 1); rspamd_strlcpy (res->name, input, obrace - input + 1); res->args = g_array_new (FALSE, FALSE, sizeof (struct expression_argument)); + rspamd_mempool_add_destructor (pool, rspamd_array_free_hard, res->args); p = obrace + 1; c = p; @@ -514,7 +515,7 @@ rspamd_mime_expr_parse_function_atom (const gchar *input) } else if (t == ',' || p == ebrace) { len = p - c + 1; - databuf = g_malloc (len); + databuf = rspamd_mempool_alloc (pool, len); rspamd_strlcpy (databuf, c, len); arg.type = EXPRESSION_ARGUMENT_REGEXP; arg.data = rspamd_regexp_cache_create (NULL, databuf, NULL, &err); @@ -549,7 +550,7 @@ rspamd_mime_expr_parse_function_atom (const gchar *input) len = p - c + 1; } - databuf = g_malloc (len); + databuf = rspamd_mempool_alloc (pool, len); rspamd_strlcpy (databuf, c, len); arg.type = EXPRESSION_ARGUMENT_NORMAL; arg.data = databuf; @@ -772,7 +773,8 @@ set: lua_pop (cfg->lua_state, 1); } else { - mime_atom->d.func = rspamd_mime_expr_parse_function_atom (mime_atom->str); + mime_atom->d.func = rspamd_mime_expr_parse_function_atom (pool, + mime_atom->str); if (mime_atom->d.func == NULL) { g_set_error (err, rspamd_mime_expr_quark(), 200, "cannot parse function '%s'", mime_atom->str); diff --git a/src/libserver/cfg_rcl.c b/src/libserver/cfg_rcl.c index ee54be39b..c36ad9408 100644 --- a/src/libserver/cfg_rcl.c +++ b/src/libserver/cfg_rcl.c @@ -1628,14 +1628,14 @@ rspamd_rcl_add_section (struct rspamd_rcl_section **top, } else { parent_doc = (*top)->doc_ref; - new->doc_ref = rspamd_rcl_add_doc_obj (parent_doc, + new->doc_ref = ucl_object_ref (rspamd_rcl_add_doc_obj (parent_doc, NULL, name, type, NULL, 0, NULL, - 0); + 0)); } HASH_ADD_KEYPTR (hh, *top, new->name, strlen (new->name), new); @@ -1658,14 +1658,14 @@ rspamd_rcl_add_section_doc (struct rspamd_rcl_section **top, new->type = type; new->strict_type = strict_type; - new->doc_ref = rspamd_rcl_add_doc_obj (doc_target, + new->doc_ref = ucl_object_ref (rspamd_rcl_add_doc_obj (doc_target, doc_string, name, type, NULL, 0, NULL, - 0); + 0)); HASH_ADD_KEYPTR (hh, *top, new->name, strlen (new->name), new); return new; @@ -3715,7 +3715,7 @@ rspamd_rcl_add_doc_obj (ucl_object_t *doc_target, ucl_object_insert_key (doc_target, doc_obj, doc_name, 0, true); - return ucl_object_ref (doc_obj); + return doc_obj; } ucl_object_t * @@ -3786,7 +3786,7 @@ rspamd_rcl_add_doc_by_path (struct rspamd_config *cfg, } } - return rspamd_rcl_add_doc_obj ((ucl_object_t *) cur, + return rspamd_rcl_add_doc_obj (ucl_object_ref (cur), doc_string, doc_name, type, diff --git a/src/lua/lua_common.c b/src/lua/lua_common.c index b9eabe790..7f4cea7b7 100644 --- a/src/lua/lua_common.c +++ b/src/lua/lua_common.c @@ -1264,3 +1264,31 @@ lua_worker_get_pid (lua_State *L) return 1; } + +struct rspamd_lua_ref_cbdata { + lua_State *L; + gint cbref; +}; + +static void +rspamd_lua_ref_dtor (gpointer p) +{ + struct rspamd_lua_ref_cbdata *cbdata = p; + + luaL_unref (cbdata->L, LUA_REGISTRYINDEX, cbdata->cbref); +} + +void +rspamd_lua_add_ref_dtor (lua_State *L, rspamd_mempool_t *pool, + gint ref) +{ + struct rspamd_lua_ref_cbdata *cbdata; + + if (ref != -1) { + cbdata = rspamd_mempool_alloc (pool, sizeof (*cbdata)); + cbdata->cbref = ref; + cbdata->L = L; + + rspamd_mempool_add_destructor (pool, rspamd_lua_ref_dtor, cbdata); + } +} diff --git a/src/lua/lua_common.h b/src/lua/lua_common.h index dbb46c822..ecf46d32e 100644 --- a/src/lua/lua_common.h +++ b/src/lua/lua_common.h @@ -360,5 +360,14 @@ void lua_call_finish_script (lua_State *L, struct gboolean rspamd_lua_run_postloads (lua_State *L, struct rspamd_config *cfg, struct event_base *ev_base, struct rspamd_worker *w); +/** + * Adds new destructor for a local function for specific pool + * @param L + * @param pool + * @param ref + */ +void rspamd_lua_add_ref_dtor (lua_State *L, rspamd_mempool_t *pool, + gint ref); + #endif /* WITH_LUA */ #endif /* RSPAMD_LUA_H */ diff --git a/src/plugins/dkim_check.c b/src/plugins/dkim_check.c index 6b10b2aa9..aa2da3bfe 100644 --- a/src/plugins/dkim_check.c +++ b/src/plugins/dkim_check.c @@ -502,6 +502,9 @@ dkim_module_config (struct rspamd_config *cfg) if (lua_type (cfg->lua_state, -1) == LUA_TFUNCTION) { dkim_module_ctx->sign_condition_ref = luaL_ref (cfg->lua_state, LUA_REGISTRYINDEX); + rspamd_lua_add_ref_dtor (cfg->lua_state, + dkim_module_ctx->dkim_pool, + dkim_module_ctx->sign_condition_ref); dkim_module_ctx->dkim_sign_hash = rspamd_lru_hash_new ( 128, @@ -631,10 +634,19 @@ dkim_module_reconfig (struct rspamd_config *cfg) saved_ctx = dkim_module_ctx->ctx; rspamd_mempool_delete (dkim_module_ctx->dkim_pool); radix_destroy_compressed (dkim_module_ctx->whitelist_ip); + if (dkim_module_ctx->dkim_domains) { g_hash_table_destroy (dkim_module_ctx->dkim_domains); } + if (dkim_module_ctx->dkim_hash) { + rspamd_lru_hash_destroy (dkim_module_ctx->dkim_hash); + } + + if (dkim_module_ctx->dkim_sign_hash) { + rspamd_lru_hash_destroy (dkim_module_ctx->dkim_sign_hash); + } + memset (dkim_module_ctx, 0, sizeof (*dkim_module_ctx)); dkim_module_ctx->ctx = saved_ctx; dkim_module_ctx->dkim_pool = rspamd_mempool_new (rspamd_mempool_suggest_size (), "dkim"); diff --git a/src/plugins/spf.c b/src/plugins/spf.c index 15ebdab31..a3103d699 100644 --- a/src/plugins/spf.c +++ b/src/plugins/spf.c @@ -332,6 +332,7 @@ spf_module_reconfig (struct rspamd_config *cfg) saved_ctx = spf_module_ctx->ctx; rspamd_mempool_delete (spf_module_ctx->spf_pool); + rspamd_lru_hash_destroy (spf_module_ctx->spf_hash); radix_destroy_compressed (spf_module_ctx->whitelist_ip); memset (spf_module_ctx, 0, sizeof (*spf_module_ctx)); spf_module_ctx->ctx = saved_ctx; diff --git a/src/rspamd_proxy.c b/src/rspamd_proxy.c index df92dab1c..33ac428af 100644 --- a/src/rspamd_proxy.c +++ b/src/rspamd_proxy.c @@ -296,9 +296,7 @@ rspamd_proxy_parse_upstream (rspamd_mempool_t *pool, return FALSE; } - up = g_malloc0 (sizeof (*up)); - rspamd_mempool_add_destructor (pool, - (rspamd_mempool_destruct_t)g_free, up); + up = rspamd_mempool_alloc0 (pool, sizeof (*up)); up->parser_from_ref = -1; up->parser_to_ref = -1; up->name = rspamd_mempool_strdup (pool, ucl_object_tostring (elt)); @@ -365,6 +363,9 @@ rspamd_proxy_parse_upstream (rspamd_mempool_t *pool, &up->parser_to_ref, err)) { goto err; } + + rspamd_lua_add_ref_dtor (L, pool, up->parser_from_ref); + rspamd_lua_add_ref_dtor (L, pool, up->parser_to_ref); } double_to_tv (up->timeout, &up->io_tv); @@ -408,9 +409,7 @@ rspamd_proxy_parse_mirror (rspamd_mempool_t *pool, return FALSE; } - up = g_malloc0 (sizeof (*up)); - rspamd_mempool_add_destructor (pool, - (rspamd_mempool_destruct_t)g_free, up); + up = rspamd_mempool_alloc0 (pool, sizeof (*up)); up->name = rspamd_mempool_strdup (pool, ucl_object_tostring (elt)); up->parser_to_ref = -1; up->parser_from_ref = -1; @@ -480,6 +479,9 @@ rspamd_proxy_parse_mirror (rspamd_mempool_t *pool, &up->parser_to_ref, err)) { goto err; } + + rspamd_lua_add_ref_dtor (L, pool, up->parser_from_ref); + rspamd_lua_add_ref_dtor (L, pool, up->parser_to_ref); } elt = ucl_object_lookup_any (obj, "settings", "settings_id", NULL); -- 2.39.5