diff options
author | Florian Westphal <fw@strlen.de> | 2023-12-21 11:25:14 +0100 |
---|---|---|
committer | Florian Westphal <fw@strlen.de> | 2023-12-22 11:57:46 +0100 |
commit | dcb199544563ded462cb7151134278f82a9e6cfd (patch) | |
tree | b1a1937e32bf5eda4126fb288751fdddb9fbda42 /src/netlink_linearize.c | |
parent | b9e19cc396347df8c7f8cf5d14ba1d6172040f16 (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.c | 7 |
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); |