aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVsevolod Stakhov <vsevolod@highsecure.ru>2016-08-04 13:03:41 +0100
committerVsevolod Stakhov <vsevolod@highsecure.ru>2016-08-04 13:03:41 +0100
commit15d0fdb942c7d7f7a9791c083c72352c99640710 (patch)
tree70a3d8b4bb85e2d3865bad733ab84a84aa140c14
parent9726ea50037730f9ce841bc05512089884804fbc (diff)
downloadrspamd-15d0fdb942c7d7f7a9791c083c72352c99640710.tar.gz
rspamd-15d0fdb942c7d7f7a9791c083c72352c99640710.zip
[Fix] Do not crash on cyclic depends
-rw-r--r--src/libserver/symbols_cache.c23
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;
}