summaryrefslogtreecommitdiffstats
path: root/src/netlink_linearize.c
diff options
context:
space:
mode:
authorFlorian Westphal <fw@strlen.de>2023-12-21 11:25:14 +0100
committerFlorian Westphal <fw@strlen.de>2023-12-22 11:57:46 +0100
commitdcb199544563ded462cb7151134278f82a9e6cfd (patch)
treeb1a1937e32bf5eda4126fb288751fdddb9fbda42 /src/netlink_linearize.c
parentb9e19cc396347df8c7f8cf5d14ba1d6172040f16 (diff)
src: do not allow to chain more than 16 binops
netlink_linearize.c has never supported more than 16 chained binops. Adding more is possible but overwrites the stack in netlink_gen_bitwise(). Add a recursion counter to catch this at eval stage. Its not enough to just abort once the counter hits NFT_MAX_EXPR_RECURSION. This is because there are valid test cases that exceed this. For example, evaluation of 1 | 2 will merge the constans, so even if there are a dozen recursive eval calls this will not end up with large binop chain post-evaluation. v2: allow more than 16 binops iff the evaluation function did constant-merging. Signed-off-by: Florian Westphal <fw@strlen.de>
Diffstat (limited to 'src/netlink_linearize.c')
-rw-r--r--src/netlink_linearize.c7
1 files changed, 5 insertions, 2 deletions
diff --git a/src/netlink_linearize.c b/src/netlink_linearize.c
index d8b41a08..50dbd36c 100644
--- a/src/netlink_linearize.c
+++ b/src/netlink_linearize.c
@@ -695,10 +695,10 @@ static void netlink_gen_bitwise(struct netlink_linearize_ctx *ctx,
const struct expr *expr,
enum nft_registers dreg)
{
+ struct expr *binops[NFT_MAX_EXPR_RECURSION];
struct nftnl_expr *nle;
struct nft_data_linearize nld;
struct expr *left, *i;
- struct expr *binops[16];
mpz_t mask, xor, val, tmp;
unsigned int len;
int n = 0;
@@ -710,8 +710,11 @@ static void netlink_gen_bitwise(struct netlink_linearize_ctx *ctx,
binops[n++] = left = (struct expr *) expr;
while (left->etype == EXPR_BINOP && left->left != NULL &&
- (left->op == OP_AND || left->op == OP_OR || left->op == OP_XOR))
+ (left->op == OP_AND || left->op == OP_OR || left->op == OP_XOR)) {
+ if (n == array_size(binops))
+ BUG("NFT_MAX_EXPR_RECURSION limit reached");
binops[n++] = left = left->left;
+ }
netlink_gen_expr(ctx, binops[--n], dreg);