aboutsummaryrefslogtreecommitdiffstats
path: root/src/libserver
diff options
context:
space:
mode:
authorVsevolod Stakhov <vsevolod@highsecure.ru>2019-02-26 16:51:07 +0000
committerVsevolod Stakhov <vsevolod@highsecure.ru>2019-02-26 16:55:58 +0000
commit2c316e86a137b0622863c18b2b6e9f09c693fbc3 (patch)
treee7f64475044f1c0c8cdc426451b7f37f536a4d46 /src/libserver
parent931e181c3202e5a92bcc614ec042fd46f032c4c3 (diff)
downloadrspamd-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.c22
-rw-r--r--src/libserver/dynamic_cfg.c27
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