]> source.dussan.org Git - rspamd.git/commitdiff
[Fix] Fix race-condition leak on processes reload
authorVsevolod Stakhov <vsevolod@highsecure.ru>
Fri, 15 Jun 2018 14:24:48 +0000 (15:24 +0100)
committerVsevolod Stakhov <vsevolod@highsecure.ru>
Fri, 15 Jun 2018 14:24:48 +0000 (15:24 +0100)
src/libserver/rspamd_control.c
src/rspamd.c
src/rspamd.h

index bbfcdafdf3066197b413aa1cf43f54e6051944c4..84c53700ea934eb1a5a3dd2aa71827b07d514766 100644 (file)
@@ -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);
index 307aa52ad5d408f3314d453183c35557dd972ffb..7a2ce2daa7b6801e1f19c7cba448295aaf806f9b 100644 (file)
@@ -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);
                        }
 
index 1365a4b23fce7f2c4c0ce4496b284fd77a0d0fa0..26657129006b3c7e2412cd8aa8d50661cc0552ca 100644 (file)
@@ -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                           */
 };