diff mbox series

[nft] dynset: avoid errouneous assert with ipv6 concat data

Message ID 20240407124755.1456-1-dinhtrason@gmail.com
State Superseded
Headers show
Series [nft] dynset: avoid errouneous assert with ipv6 concat data | expand

Commit Message

Son Dinh April 7, 2024, 12:47 p.m. UTC
Fix assert bug of map dynset having ipv6 concat data

 nft add rule ip6 table-test chain-1 update @map-X { ip6 saddr : 1000::1 . 5001 }
 nft: src/netlink_linearize.c:873: netlink_gen_expr: Assertion `dreg < ctx->reg_low' failed.
 Aborted (core dumped)

The current code allocates upto 4 registers for map dynset data, but ipv6 concat
data of a dynset requires more than 4 registers, resulting in the assert in
netlink_gen_expr when generating netlink info for the dynset data.

Signed-off-by: Son Dinh <dinhtrason@gmail.com>
---
 src/netlink_linearize.c | 11 ++++++++---
 1 file changed, 8 insertions(+), 3 deletions(-)

Comments

Florian Westphal April 7, 2024, 5:17 p.m. UTC | #1
Son Dinh <dinhtrason@gmail.com> wrote:
> Fix assert bug of map dynset having ipv6 concat data
> 
>  nft add rule ip6 table-test chain-1 update @map-X { ip6 saddr : 1000::1 . 5001 }
>  nft: src/netlink_linearize.c:873: netlink_gen_expr: Assertion `dreg < ctx->reg_low' failed.
>  Aborted (core dumped)
> 
> The current code allocates upto 4 registers for map dynset data, but ipv6 concat
> data of a dynset requires more than 4 registers, resulting in the assert in
> netlink_gen_expr when generating netlink info for the dynset data.

Could you plese either extend an existing test case or add a new one for
this?

> -	sreg_data = get_register(ctx, stmt->map.data);

This line is wrong, this sould be

   	sreg_data = get_register(ctx, stmt->map.data->key);
Son Dinh April 8, 2024, 4:32 a.m. UTC | #2
On Mon, 8 Apr 2024 at 03:17, Florian Westphal <fw@strlen.de> wrote:
>
> Could you plese either extend an existing test case or add a new one for
> this?
>

Sure. I'm working on it.

> > -     sreg_data = get_register(ctx, stmt->map.data);
>
> This line is wrong, this sould be
>
>         sreg_data = get_register(ctx, stmt->map.data->key);

You're correct. Fixing the bug with your suggest is much simpler than
mine if getting registers of ipv6 concat data directly with
"get_register(ctx, stmt->map.data->key);" instead of
"get_register(ctx, stmt->map.data)"
diff mbox series

Patch

diff --git src/netlink_linearize.c src/netlink_linearize.c
index 6204d8fd..11b4bc2d 100644
--- src/netlink_linearize.c
+++ src/netlink_linearize.c
@@ -1588,15 +1588,20 @@  static void netlink_gen_map_stmt(struct netlink_linearize_ctx *ctx,
 	struct nftnl_expr *nle;
 	int num_stmts = 0;
 	struct stmt *this;
+	int regspace = 0;
+	struct expr *expr_data = stmt->map.data;
 
 	sreg_key = get_register(ctx, stmt->map.key->key);
 	netlink_gen_expr(ctx, stmt->map.key->key, sreg_key);
 
-	sreg_data = get_register(ctx, stmt->map.data);
-	netlink_gen_expr(ctx, stmt->map.data, sreg_data);
+	/* Adjust ctx->reg_low to the real size of stmt->map.data */
+	regspace = netlink_register_space(expr_data->map->len);
+	sreg_data = ctx->reg_low;
+	ctx->reg_low += regspace;
+	netlink_gen_expr(ctx, expr_data, sreg_data);
 
+	ctx->reg_low -= regspace;
 	release_register(ctx, stmt->map.key->key);
-	release_register(ctx, stmt->map.data);
 
 	nle = alloc_nft_expr("dynset");
 	netlink_put_register(nle, NFTNL_EXPR_DYNSET_SREG_KEY, sreg_key);