From 825617333396f105391b293914a1fb081040141b Mon Sep 17 00:00:00 2001 From: Vsevolod Stakhov Date: Tue, 24 Dec 2019 17:00:56 +0000 Subject: [PATCH] [Project] Implement slow rules sanity protection --- src/libserver/async_session.c | 4 ++- src/libserver/rspamd_symcache.c | 58 ++++++++++++++++++++++++++++----- 2 files changed, 53 insertions(+), 9 deletions(-) diff --git a/src/libserver/async_session.c b/src/libserver/async_session.c index cec2963aa..1bd4c77e9 100644 --- a/src/libserver/async_session.c +++ b/src/libserver/async_session.c @@ -240,7 +240,9 @@ rspamd_session_remove_event_full (struct rspamd_async_session *session, kh_del (rspamd_events_hash, session->events, k); /* Remove event */ - fin (ud); + if (fin) { + fin (ud); + } rspamd_session_pending (session); } diff --git a/src/libserver/rspamd_symcache.c b/src/libserver/rspamd_symcache.c index 31bba1386..499d58c28 100644 --- a/src/libserver/rspamd_symcache.c +++ b/src/libserver/rspamd_symcache.c @@ -2072,6 +2072,11 @@ rspamd_symcache_process_symbols (struct rspamd_task *task, if (!CHECK_START_BIT (checkpoint, dyn_item) && !CHECK_FINISH_BIT (checkpoint, dyn_item)) { + + if (checkpoint->has_slow) { + /* Delay */ + return FALSE; + } /* Check priorities */ if (saved_priority == G_MININT) { saved_priority = item->priority; @@ -2111,6 +2116,11 @@ rspamd_symcache_process_symbols (struct rspamd_task *task, if (!CHECK_START_BIT (checkpoint, dyn_item) && !CHECK_FINISH_BIT (checkpoint, dyn_item)) { /* Check priorities */ + if (checkpoint->has_slow) { + /* Delay */ + return FALSE; + } + if (saved_priority == G_MININT) { saved_priority = item->priority; } @@ -2163,6 +2173,11 @@ rspamd_symcache_process_symbols (struct rspamd_task *task, rspamd_symcache_check_symbol (task, cache, item, checkpoint); + + if (checkpoint->has_slow) { + /* Delay */ + return FALSE; + } } if (!(item->type & SYMBOL_TYPE_FINE)) { @@ -2197,6 +2212,11 @@ rspamd_symcache_process_symbols (struct rspamd_task *task, /* Check priorities */ all_done = FALSE; + if (checkpoint->has_slow) { + /* Delay */ + return FALSE; + } + if (saved_priority == G_MININT) { saved_priority = item->priority; } @@ -2230,6 +2250,11 @@ rspamd_symcache_process_symbols (struct rspamd_task *task, if (!CHECK_START_BIT (checkpoint, dyn_item) && !CHECK_FINISH_BIT (checkpoint, dyn_item)) { /* Check priorities */ + if (checkpoint->has_slow) { + /* Delay */ + return FALSE; + } + if (saved_priority == G_MININT) { saved_priority = item->priority; } @@ -2993,6 +3018,7 @@ rspamd_symcache_set_cur_item (struct rspamd_task *task, struct rspamd_symcache_delayed_cbdata { struct rspamd_symcache_item *item; struct rspamd_task *task; + struct rspamd_async_event *event; struct ev_timer tm; }; @@ -3037,6 +3063,8 @@ rspamd_symcache_delayed_item_cb (EV_P_ ev_timer *w, int what) } } } + + rspamd_session_remove_event (task->s, NULL, cbd); } static void @@ -3113,14 +3141,28 @@ rspamd_symcache_finalize_item (struct rspamd_task *task, /* Add timer to allow something else to be executed */ ev_timer *tm = &cbd->tm; - ev_timer_init (tm, rspamd_symcache_delayed_item_cb, 0.1, 0.0); - ev_set_priority (tm, EV_MINPRI); - rspamd_mempool_add_destructor (task->task_pool, - rspamd_delayed_timer_dtor, cbd); - cbd->task = task; - cbd->item = item; - tm->data = cbd; - ev_timer_start (task->event_loop, tm); + cbd->event = rspamd_session_add_event (task->s, NULL, cbd, + "symcache"); + + /* + * If no event could be added, then we are already in the destruction + * phase. So the main issue is to deal with has slow here + */ + if (cbd->event) { + ev_timer_init (tm, rspamd_symcache_delayed_item_cb, 0.1, 0.0); + ev_set_priority (tm, EV_MINPRI); + rspamd_mempool_add_destructor (task->task_pool, + rspamd_delayed_timer_dtor, cbd); + + cbd->task = task; + cbd->item = item; + tm->data = cbd; + ev_timer_start (task->event_loop, tm); + } + else { + /* Just reset as no timer is added */ + checkpoint->has_slow = FALSE; + } return; } -- 2.39.5