aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVsevolod Stakhov <vsevolod@highsecure.ru>2018-06-15 15:24:48 +0100
committerVsevolod Stakhov <vsevolod@highsecure.ru>2018-06-15 15:24:48 +0100
commitcff17e1ac557a878514e8f332afb2e7fdf4be849 (patch)
treef2638a2f87da7d41ad92f2785a8fcb6d4eb9ced8
parent7718fb14602c410dc16a316bb4e9cc87850c0ee4 (diff)
downloadrspamd-cff17e1ac557a878514e8f332afb2e7fdf4be849.tar.gz
rspamd-cff17e1ac557a878514e8f332afb2e7fdf4be849.zip
[Fix] Fix race-condition leak on processes reload
-rw-r--r--src/libserver/rspamd_control.c3
-rw-r--r--src/rspamd.c10
-rw-r--r--src/rspamd.h1
3 files changed, 14 insertions, 0 deletions
diff --git a/src/libserver/rspamd_control.c b/src/libserver/rspamd_control.c
index bbfcdafdf..84c53700e 100644
--- a/src/libserver/rspamd_control.c
+++ b/src/libserver/rspamd_control.c
@@ -835,6 +835,7 @@ rspamd_srv_handler (gint fd, short what, gpointer ud)
rdata->rep.id = cmd.id;
rdata->rep.type = cmd.type;
rdata->fd = -1;
+ worker->tmp_data = rdata;
if (msg.msg_controllen >= CMSG_LEN (sizeof (int))) {
rfd = *(int *) CMSG_DATA(CMSG_FIRSTHDR (&msg));
@@ -921,6 +922,7 @@ rspamd_srv_handler (gint fd, short what, gpointer ud)
else if (what == EV_WRITE) {
rdata = ud;
worker = rdata->worker;
+ worker->tmp_data = NULL; /* Avoid race */
srv = rdata->srv;
memset (&msg, 0, sizeof (msg));
@@ -967,6 +969,7 @@ rspamd_srv_start_watching (struct rspamd_main *srv,
{
g_assert (worker != NULL);
+ worker->tmp_data = NULL;
event_set (&worker->srv_ev, worker->srv_pipe[0], EV_READ | EV_PERSIST,
rspamd_srv_handler, worker);
event_base_set (ev_base, &worker->srv_ev);
diff --git a/src/rspamd.c b/src/rspamd.c
index 307aa52ad..7a2ce2daa 100644
--- a/src/rspamd.c
+++ b/src/rspamd.c
@@ -753,11 +753,17 @@ wait_for_workers (gpointer key, gpointer value, gpointer unused)
nowait ? "with no result available" :
(WTERMSIG (res) == SIGKILL ? "hardly" : "softly"));
if (w->srv_pipe[0] != -1) {
+ /* Ugly workaround */
+ if (w->tmp_data) {
+ g_free (w->tmp_data);
+ }
event_del (&w->srv_ev);
}
+
if (w->finish_actions) {
g_ptr_array_free (w->finish_actions, TRUE);
}
+
REF_RELEASE (w->cf);
g_free (w);
@@ -1059,6 +1065,10 @@ rspamd_cld_handler (gint signo, short what, gpointer arg)
}
if (cur->srv_pipe[0] != -1) {
+ /* Ugly workaround */
+ if (cur->tmp_data) {
+ g_free (cur->tmp_data);
+ }
event_del (&cur->srv_ev);
}
diff --git a/src/rspamd.h b/src/rspamd.h
index 1365a4b23..266571290 100644
--- a/src/rspamd.h
+++ b/src/rspamd.h
@@ -86,6 +86,7 @@ struct rspamd_worker {
main process. [0] - main, [1] - worker */
struct event srv_ev; /**< used by main for read workers' requests */
gpointer control_data; /**< used by control protocol to handle commands */
+ gpointer tmp_data; /**< used to avoid race condition to deal with control messages */
GPtrArray *finish_actions; /**< called when worker is terminated */
};