]> git.ipfire.org Git - thirdparty/nftables.git/commitdiff
meta: don't crash if meta key isn't known
authorFlorian Westphal <fw@strlen.de>
Wed, 15 Mar 2023 12:57:38 +0000 (13:57 +0100)
committerFlorian Westphal <fw@strlen.de>
Mon, 27 Mar 2023 15:01:58 +0000 (17:01 +0200)
If older nft version is used for dumping, 'key' might be
outside of the range of known templates.

Signed-off-by: Florian Westphal <fw@strlen.de>
src/meta.c
src/netlink_delinearize.c

index 013e8cbaf38a5dbd2d4aa2ce6fad0099c1cec304..dcf971a5dd6274328ce6e624313c1da1faef4605 100644 (file)
@@ -717,12 +717,16 @@ static bool meta_key_is_unqualified(enum nft_meta_keys key)
 
 static void meta_expr_print(const struct expr *expr, struct output_ctx *octx)
 {
-       if (meta_key_is_unqualified(expr->meta.key))
-               nft_print(octx, "%s",
-                         meta_templates[expr->meta.key].token);
+       const char *token = "unknown";
+       uint32_t key = expr->meta.key;
+
+       if (key < array_size(meta_templates))
+               token = meta_templates[key].token;
+
+       if (meta_key_is_unqualified(key))
+               nft_print(octx, "%s", token);
        else
-               nft_print(octx, "meta %s",
-                         meta_templates[expr->meta.key].token);
+               nft_print(octx, "meta %s", token);
 }
 
 static bool meta_expr_cmp(const struct expr *e1, const struct expr *e2)
@@ -918,12 +922,16 @@ struct expr *meta_expr_alloc(const struct location *loc, enum nft_meta_keys key)
 
 static void meta_stmt_print(const struct stmt *stmt, struct output_ctx *octx)
 {
+       const char *token = "unknown";
+       uint32_t key = stmt->meta.key;
+
+       if (key < array_size(meta_templates))
+               token = meta_templates[key].token;
+
        if (meta_key_is_unqualified(stmt->meta.key))
-               nft_print(octx, "%s set ",
-                         meta_templates[stmt->meta.key].token);
+               nft_print(octx, "%s set ", token);
        else
-               nft_print(octx, "meta %s set ",
-                         meta_templates[stmt->meta.key].token);
+               nft_print(octx, "meta %s set ", token);
 
        expr_print(stmt->meta.expr, octx);
 }
@@ -948,8 +956,11 @@ struct stmt *meta_stmt_alloc(const struct location *loc, enum nft_meta_keys key,
 
        stmt = stmt_alloc(loc, &meta_stmt_ops);
        stmt->meta.key  = key;
-       stmt->meta.tmpl = &meta_templates[key];
        stmt->meta.expr = expr;
+
+        if (key < array_size(meta_templates))
+                stmt->meta.tmpl = &meta_templates[key];
+
        return stmt;
 }
 
index 60350cd6cd9606d6a6f7da87804925f0e06c8dc8..d28b545e69d2969aa6dfdf3178a495427fa5ffbd 100644 (file)
@@ -920,7 +920,9 @@ static void netlink_parse_meta_stmt(struct netlink_parse_ctx *ctx,
 
        key  = nftnl_expr_get_u32(nle, NFTNL_EXPR_META_KEY);
        stmt = meta_stmt_alloc(loc, key, expr);
-       expr_set_type(expr, stmt->meta.tmpl->dtype, stmt->meta.tmpl->byteorder);
+
+       if (stmt->meta.tmpl)
+               expr_set_type(expr, stmt->meta.tmpl->dtype, stmt->meta.tmpl->byteorder);
 
        ctx->stmt = stmt;
 }