commit
10b44319a53a131ed943e2b6eeb62d197178bf4d upstream.
The existing recursion counter is used by the binop expression to detect
if we've completely followed all the binops.
We can only chain up to NFT_MAX_EXPR_RECURSION binops, but the evaluation
step can perform constant-folding, so we must recurse until we found the
rightmost (last) binop in the chain.
Then we can check the post-eval chain to see if it is something that can
be serialized later (i.e., if we are within the NFT_MAX_EXPR_RECURSION
after constant folding) or not.
Thus we can't reuse the existing ctx->recursion counter for other
expressions; entering the initial expr_evaluate_binop with
ctx->recursion > 0 would break things.
Therefore rename this to an embedded structure.
This allows us to add a new recursion counter in a followup patch.
Signed-off-by: Florian Westphal <fw@strlen.de>
#include <payload.h>
#include <expression.h>
+struct eval_recursion {
+ uint16_t binop;
+};
+
/**
* struct eval_ctx - evaluation context
*
* @set: current set
* @stmt: current statement
* @stmt_len: current statement template length
- * @recursion: expr evaluation recursion counter
+ * @recursion: expr evaluation recursion counters
* @cache: cache context
* @debug_mask: debugging bitmask
* @ectx: expression context
struct set *set;
struct stmt *stmt;
uint32_t stmt_len;
- uint32_t recursion;
+ struct eval_recursion recursion;
struct expr_ctx ectx;
struct proto_ctx pctx;
};
unsigned int max_shift_len = ctx->ectx.len;
int ret = -1;
- if (ctx->recursion >= USHRT_MAX)
+ if (ctx->recursion.binop >= USHRT_MAX)
return expr_binary_error(ctx->msgs, op, NULL,
"Binary operation limit %u reached ",
- ctx->recursion);
- ctx->recursion++;
+ ctx->recursion.binop);
+ ctx->recursion.binop++;
if (expr_evaluate(ctx, &op->left) < 0)
return -1;
}
- if (ctx->recursion == 0)
+ if (ctx->recursion.binop == 0)
BUG("recursion counter underflow");
/* can't check earlier: evaluate functions might do constant-merging + expr_free.
* So once we've evaluate everything check for remaining length of the
* binop chain.
*/
- if (--ctx->recursion == 0) {
+ if (--ctx->recursion.binop == 0) {
unsigned int to_linearize = 0;
op = *expr;