diff options
author | Vsevolod Stakhov <vsevolod@highsecure.ru> | 2019-02-26 16:51:07 +0000 |
---|---|---|
committer | Vsevolod Stakhov <vsevolod@highsecure.ru> | 2019-02-26 16:55:58 +0000 |
commit | 2c316e86a137b0622863c18b2b6e9f09c693fbc3 (patch) | |
tree | e7f64475044f1c0c8cdc426451b7f37f536a4d46 /src/libserver | |
parent | 931e181c3202e5a92bcc614ec042fd46f032c4c3 (diff) | |
download | rspamd-2c316e86a137b0622863c18b2b6e9f09c693fbc3.tar.gz rspamd-2c316e86a137b0622863c18b2b6e9f09c693fbc3.zip |
[Fix] Fix maps object update race condition
Issue: #2467
Diffstat (limited to 'src/libserver')
-rw-r--r-- | src/libserver/cfg_utils.c | 22 | ||||
-rw-r--r-- | src/libserver/dynamic_cfg.c | 27 |
2 files changed, 29 insertions, 20 deletions
diff --git a/src/libserver/cfg_utils.c b/src/libserver/cfg_utils.c index 5c6fc6672..af31db849 100644 --- a/src/libserver/cfg_utils.c +++ b/src/libserver/cfg_utils.c @@ -58,7 +58,7 @@ static gchar * rspamd_ucl_read_cb (gchar * chunk, gint len, struct map_cb_data *data, gboolean final); -static void rspamd_ucl_fin_cb (struct map_cb_data *data); +static void rspamd_ucl_fin_cb (struct map_cb_data *data, void **target); static void rspamd_ucl_dtor_cb (struct map_cb_data *data); guint rspamd_config_log_id = (guint)-1; @@ -1358,7 +1358,7 @@ rspamd_ucl_read_cb (gchar * chunk, } static void -rspamd_ucl_fin_cb (struct map_cb_data *data) +rspamd_ucl_fin_cb (struct map_cb_data *data, void **target) { struct rspamd_ucl_map_cbdata *cbdata = data->cur_data, *prev = data->prev_data; @@ -1368,13 +1368,6 @@ rspamd_ucl_fin_cb (struct map_cb_data *data) const ucl_object_t *cur; struct rspamd_config *cfg = data->map->cfg; - if (prev != NULL) { - if (prev->buf != NULL) { - g_string_free (prev->buf, TRUE); - } - g_free (prev); - } - if (cbdata == NULL) { msg_err_config ("map fin error: new data is NULL"); return; @@ -1400,6 +1393,17 @@ rspamd_ucl_fin_cb (struct map_cb_data *data) } ucl_object_unref (obj); } + + if (target) { + *target = data->cur_data; + } + + if (prev != NULL) { + if (prev->buf != NULL) { + g_string_free (prev->buf, TRUE); + } + g_free (prev); + } } static void diff --git a/src/libserver/dynamic_cfg.c b/src/libserver/dynamic_cfg.c index 1e970a17b..984a26697 100644 --- a/src/libserver/dynamic_cfg.c +++ b/src/libserver/dynamic_cfg.c @@ -175,22 +175,12 @@ json_config_read_cb (gchar * chunk, } static void -json_config_fin_cb (struct map_cb_data *data) +json_config_fin_cb (struct map_cb_data *data, void **target) { struct config_json_buf *jb; ucl_object_t *top; struct ucl_parser *parser; - if (data->cur_data && data->prev_data) { - jb = data->prev_data; - /* Clean prev data */ - if (jb->buf) { - g_string_free (jb->buf, TRUE); - } - - g_free (jb); - } - /* Now parse json */ if (data->cur_data) { jb = data->cur_data; @@ -201,6 +191,7 @@ json_config_fin_cb (struct map_cb_data *data) if (jb->buf == NULL) { msg_err ("no data read"); + return; } @@ -225,6 +216,20 @@ json_config_fin_cb (struct map_cb_data *data) ucl_object_unref (jb->cfg->current_dynamic_conf); apply_dynamic_conf (top, jb->cfg); jb->cfg->current_dynamic_conf = top; + + if (target) { + *target = data->cur_data; + } + + if (data->prev_data) { + jb = data->prev_data; + /* Clean prev data */ + if (jb->buf) { + g_string_free (jb->buf, TRUE); + } + + g_free (jb); + } } static void |