summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPablo Neira Ayuso <pablo@netfilter.org>2021-11-05 14:43:17 +0100
committerPablo Neira Ayuso <pablo@netfilter.org>2021-11-08 10:59:33 +0100
commitfe4e527ce2a2fb9b6efa982b521e1397f20134af (patch)
tree59bb36beff4d98d6541aad50f4fcd9ac2183ebb3 /src
parentb4b234f5a29e819045679acd95820a7457d4d7de (diff)
evaluate: clone variable expression if there is more than one reference
Clone the expression that defines the variable value if there are multiple references to it in the ruleset. This saves heap memory consumption in case the variable defines a set with a huge number of elements. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Diffstat (limited to 'src')
-rw-r--r--src/evaluate.c11
1 files changed, 10 insertions, 1 deletions
diff --git a/src/evaluate.c b/src/evaluate.c
index a268b3cb..fd7818da 100644
--- a/src/evaluate.c
+++ b/src/evaluate.c
@@ -2187,7 +2187,16 @@ static int expr_evaluate_osf(struct eval_ctx *ctx, struct expr **expr)
static int expr_evaluate_variable(struct eval_ctx *ctx, struct expr **exprp)
{
- struct expr *new = expr_clone((*exprp)->sym->expr);
+ struct symbol *sym = (*exprp)->sym;
+ struct expr *new;
+
+ /* If variable is reused from different locations in the ruleset, then
+ * clone expression.
+ */
+ if (sym->refcnt > 2)
+ new = expr_clone(sym->expr);
+ else
+ new = expr_get(sym->expr);
if (expr_evaluate(ctx, &new) < 0) {
expr_free(new);