diff options
author | Vsevolod Stakhov <vsevolod@highsecure.ru> | 2016-08-04 13:03:41 +0100 |
---|---|---|
committer | Vsevolod Stakhov <vsevolod@highsecure.ru> | 2016-08-04 13:03:41 +0100 |
commit | 15d0fdb942c7d7f7a9791c083c72352c99640710 (patch) | |
tree | 70a3d8b4bb85e2d3865bad733ab84a84aa140c14 | |
parent | 9726ea50037730f9ce841bc05512089884804fbc (diff) | |
download | rspamd-15d0fdb942c7d7f7a9791c083c72352c99640710.tar.gz rspamd-15d0fdb942c7d7f7a9791c083c72352c99640710.zip |
[Fix] Do not crash on cyclic depends
-rw-r--r-- | src/libserver/symbols_cache.c | 23 |
1 files changed, 17 insertions, 6 deletions
diff --git a/src/libserver/symbols_cache.c b/src/libserver/symbols_cache.c index 2e32c9c6c..02f45f522 100644 --- a/src/libserver/symbols_cache.c +++ b/src/libserver/symbols_cache.c @@ -167,7 +167,8 @@ static gboolean rspamd_symbols_cache_check_symbol (struct rspamd_task *task, static gboolean rspamd_symbols_cache_check_deps (struct rspamd_task *task, struct symbols_cache *cache, struct cache_item *item, - struct cache_savepoint *checkpoint); + struct cache_savepoint *checkpoint, + guint recursion); static void rspamd_symbols_cache_enable_symbol (struct rspamd_task *task, struct symbols_cache *cache, const gchar *symbol); static void rspamd_symbols_cache_disable_all_symbols (struct rspamd_task *task, @@ -1097,7 +1098,7 @@ rspamd_symbols_cache_watcher_cb (gpointer sessiond, gpointer ud) if (!isset (checkpoint->processed_bits, it->id * 2)) { if (!rspamd_symbols_cache_check_deps (task, cache, it, - checkpoint)) { + checkpoint, 0)) { remain ++; break; } @@ -1215,12 +1216,21 @@ static gboolean rspamd_symbols_cache_check_deps (struct rspamd_task *task, struct symbols_cache *cache, struct cache_item *item, - struct cache_savepoint *checkpoint) + struct cache_savepoint *checkpoint, + guint recursion) { struct cache_dependency *dep; guint i; gboolean ret = TRUE; gdouble pr = rspamd_random_double_fast (); + static const guint max_recursion = 20; + + if (recursion > max_recursion) { + msg_err_task ("cyclic dependencies: maximum check level %ud exceed when " + "checking dependencies for %s", max_recursion, item->symbol); + + return TRUE; + } if (item->deps != NULL && item->deps->len > 0) { for (i = 0; i < item->deps->len; i ++) { @@ -1245,7 +1255,8 @@ rspamd_symbols_cache_check_deps (struct rspamd_task *task, /* Not started */ if (!rspamd_symbols_cache_check_deps (task, cache, dep->item, - checkpoint)) { + checkpoint, + recursion + 1)) { g_ptr_array_add (checkpoint->waitq, item); ret = FALSE; msg_debug_task ("delayed dependency %d for symbol %d", @@ -1518,7 +1529,7 @@ rspamd_symbols_cache_process_symbols (struct rspamd_task * task, if (!isset (checkpoint->processed_bits, item->id * 2)) { if (!rspamd_symbols_cache_check_deps (task, cache, item, - checkpoint)) { + checkpoint, 0)) { msg_debug_task ("blocked execution of %d unless deps are " "resolved", item->id); @@ -1572,7 +1583,7 @@ rspamd_symbols_cache_process_symbols (struct rspamd_task * task, if (!isset (checkpoint->processed_bits, item->id * 2)) { if (!rspamd_symbols_cache_check_deps (task, cache, item, - checkpoint)) { + checkpoint, 0)) { break; } |