commit 6eafa83: [Project] Fix virtual symbols processing in settings

Vsevolod Stakhov vsevolod at highsecure.ru
Fri Jun 14 19:00:26 UTC 2019


Author: Vsevolod Stakhov
Date: 2019-06-14 19:58:28 +0100
URL: https://github.com/rspamd/rspamd/commit/6eafa83752e1fe4afbb466eb20bd96ff4bd1dc9f

[Project] Fix virtual symbols processing in settings

---
 src/libmime/filter.c            |  4 +--
 src/libserver/rspamd_symcache.c | 74 ++++++++++++++++++++++++++++++-----------
 src/libserver/rspamd_symcache.h |  4 ++-
 3 files changed, 59 insertions(+), 23 deletions(-)

diff --git a/src/libmime/filter.c b/src/libmime/filter.c
index 39d073b05..dfc2b5d05 100644
--- a/src/libmime/filter.c
+++ b/src/libmime/filter.c
@@ -210,7 +210,7 @@ insert_metric_result (struct rspamd_task *task,
 	else {
 		if (sdef->cache_item) {
 			/* Check if we can insert this symbol at all */
-			if (!rspamd_symcache_is_item_allowed (task, sdef->cache_item)) {
+			if (!rspamd_symcache_is_item_allowed (task, sdef->cache_item, FALSE)) {
 				return NULL;
 			}
 		}
@@ -441,7 +441,7 @@ rspamd_task_insert_result_full (struct rspamd_task *task,
 			flags);
 
 	/* Process cache item */
-	if (task->cfg->cache && s->sym) {
+	if (s && task->cfg->cache && s->sym) {
 		rspamd_symcache_inc_frequency (task->cfg->cache, s->sym->cache_item);
 	}
 
diff --git a/src/libserver/rspamd_symcache.c b/src/libserver/rspamd_symcache.c
index d6377eff2..d1d56ec11 100644
--- a/src/libserver/rspamd_symcache.c
+++ b/src/libserver/rspamd_symcache.c
@@ -132,6 +132,8 @@ struct rspamd_symcache_item {
 	gint frequency_peaks;
 	/* Settings ids */
 	struct rspamd_symcache_id_list allowed_ids;
+	/* Allows execution but not symbols insertion */
+	struct rspamd_symcache_id_list exec_only_ids;
 	struct rspamd_symcache_id_list forbidden_ids;
 
 	/* Dependencies */
@@ -1425,8 +1427,11 @@ rspamd_symcache_check_id_list (const struct rspamd_symcache_id_list *ls, guint32
 
 gboolean
 rspamd_symcache_is_item_allowed (struct rspamd_task *task,
-								 struct rspamd_symcache_item *item)
+								 struct rspamd_symcache_item *item,
+								 gboolean exec_only)
 {
+	const gchar *what = "execution";
+
 	/* Static checks */
 	if (!item->enabled ||
 		(RSPAMD_TASK_IS_EMPTY (task) && !(item->type & SYMBOL_TYPE_EMPTY)) ||
@@ -1445,6 +1450,10 @@ rspamd_symcache_is_item_allowed (struct rspamd_task *task,
 		return FALSE;
 	}
 
+	if (!exec_only) {
+		what = "symbol insertion";
+	}
+
 	/* Settings checks */
 	if (task->settings_elt != 0) {
 		guint32 id = task->settings_elt->id;
@@ -1452,8 +1461,9 @@ rspamd_symcache_is_item_allowed (struct rspamd_task *task,
 		if (item->forbidden_ids.st[0] != 0 &&
 			rspamd_symcache_check_id_list (&item->forbidden_ids,
 					id)) {
-			msg_debug_cache_task ("deny execution of %s as it is forbidden for "
+			msg_debug_cache_task ("deny %s of %s as it is forbidden for "
 						 "settings id %ud",
+						 what,
 						 item->symbol,
 						 id);
 			return FALSE;
@@ -1463,22 +1473,35 @@ rspamd_symcache_is_item_allowed (struct rspamd_task *task,
 			if (item->allowed_ids.st[0] == 0 ||
 				!rspamd_symcache_check_id_list (&item->allowed_ids,
 						id)) {
-				msg_debug_cache_task ("deny execution of %s as it is not listed "
+
+				if (exec_only) {
+					/*
+					 * Special case if any of our virtual children are enabled
+					 */
+					if (rspamd_symcache_check_id_list (&item->exec_only_ids, id)) {
+						return TRUE;
+					}
+				}
+
+				msg_debug_cache_task ("deny %s of %s as it is not listed "
 									  "as allowed for settings id %ud",
+						what,
 						item->symbol,
 						id);
 				return FALSE;
 			}
 		}
 		else {
-			msg_debug_cache_task ("allow execution of %s for "
+			msg_debug_cache_task ("allow %s of %s for "
 								  "settings id %ud as it can be only disabled explicitly",
+					what,
 					item->symbol,
 					id);
 		}
 	}
 	else if (item->type & SYMBOL_TYPE_EXPLICIT_ENABLE) {
-		msg_debug_cache_task ("deny execution of %s as it must be explicitly enabled",
+		msg_debug_cache_task ("deny %s of %s as it must be explicitly enabled",
+				what,
 				item->symbol);
 		return FALSE;
 	}
@@ -1525,7 +1548,7 @@ rspamd_symcache_check_symbol (struct rspamd_task *task,
 	/* Check has been started */
 	SET_START_BIT (checkpoint, dyn_item);
 
-	if (!rspamd_symcache_is_item_allowed (task, item)) {
+	if (!rspamd_symcache_is_item_allowed (task, item, TRUE)) {
 		check = FALSE;
 	}
 	else if (item->specific.normal.condition_cb != -1) {
@@ -2612,7 +2635,7 @@ rspamd_symcache_is_symbol_enabled (struct rspamd_task *task,
 
 		if (item) {
 
-			if (!rspamd_symcache_is_item_allowed (task, item)) {
+			if (!rspamd_symcache_is_item_allowed (task, item, TRUE)) {
 				ret = FALSE;
 			}
 			else {
@@ -3218,7 +3241,7 @@ rspamd_symcache_process_settings_elt (struct rspamd_symcache *cache,
 {
 	guint32 id = elt->id;
 	ucl_object_iter_t iter;
-	struct rspamd_symcache_item *item;
+	struct rspamd_symcache_item *item, *parent;
 	const ucl_object_t *cur;
 
 
@@ -3262,21 +3285,32 @@ rspamd_symcache_process_settings_elt (struct rspamd_symcache *cache,
 		while ((cur = ucl_object_iterate (elt->symbols_enabled, &iter, true)) != NULL) {
 			/* Here, we resolve parent and explicitly allow it */
 			const gchar *sym = ucl_object_key (cur);
-			item = rspamd_symcache_find_filter (cache, sym, true);
+			item = rspamd_symcache_find_filter (cache, sym, false);
 
 			if (item) {
-				if (elt->symbols_disabled &&
-					ucl_object_lookup (elt->symbols_disabled, item->symbol)) {
-					msg_err_cache ("conflict in %s: cannot enable disabled symbol %s, "
-								   "wanted to enable symbol %s",
-							elt->name, item->symbol, sym);
-				}
-				else {
-					rspamd_symcache_add_id_to_list (cache->static_pool,
-							&item->allowed_ids, id);
-					msg_debug_cache ("allow execution of symbol %s for settings %ud (%s)",
-							sym, id, elt->name);
+				if (item->is_virtual) {
+					parent = rspamd_symcache_find_filter (cache, sym, true);
+
+					if (parent) {
+						if (elt->symbols_disabled &&
+							ucl_object_lookup (elt->symbols_disabled, parent->symbol)) {
+							msg_err_cache ("conflict in %s: cannot enable disabled symbol %s, "
+										   "wanted to enable symbol %s",
+									elt->name, parent->symbol, sym);
+							continue;
+						}
+
+						rspamd_symcache_add_id_to_list (cache->static_pool,
+								&parent->exec_only_ids, id);
+						msg_debug_cache ("allow just execution of symbol %s for settings %ud (%s)",
+								parent->symbol, id, elt->name);
+					}
 				}
+
+				rspamd_symcache_add_id_to_list (cache->static_pool,
+						&item->allowed_ids, id);
+				msg_debug_cache ("allow execution of symbol %s for settings %ud (%s)",
+						sym, id, elt->name);
 			}
 			else {
 				msg_warn_cache ("cannot find a symbol to enable %s "
diff --git a/src/libserver/rspamd_symcache.h b/src/libserver/rspamd_symcache.h
index b063109a4..ef022b730 100644
--- a/src/libserver/rspamd_symcache.h
+++ b/src/libserver/rspamd_symcache.h
@@ -486,9 +486,11 @@ void rspamd_symcache_process_settings_elt (struct rspamd_symcache *cache,
  * condition scripts to be checked (so it is intended to be fast).
  * @param task
  * @param item
+ * @param exec_only
  * @return
  */
 gboolean rspamd_symcache_is_item_allowed (struct rspamd_task *task,
-										  struct rspamd_symcache_item *item);
+										  struct rspamd_symcache_item *item,
+										  gboolean exec_only);
 
 #endif


More information about the Commits mailing list