]> source.dussan.org Git - rspamd.git/commitdiff
[Fix] Do not crash on cyclic depends
authorVsevolod Stakhov <vsevolod@highsecure.ru>
Thu, 4 Aug 2016 12:03:41 +0000 (13:03 +0100)
committerVsevolod Stakhov <vsevolod@highsecure.ru>
Thu, 4 Aug 2016 12:03:41 +0000 (13:03 +0100)
src/libserver/symbols_cache.c

index 2e32c9c6c055fff404793b1f5ca7cf76a73e4663..02f45f522ee08147b9d53c4d4c8cbfb14a2dd752 100644 (file)
@@ -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;
                                }