]> 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)
committerPablo Neira Ayuso <pablo@netfilter.org>
Wed, 22 Jan 2025 21:10:04 +0000 (22:10 +0100)
commit cd2d1fc4e8b114f8526b0ce61cfd5cfce8eacac6 upstream.

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 4a13a9e6f255519bcad64cfc540ee4d4b8eb2bf9..62546397a968ccb53f70118e415d9c37d4746a75 100644 (file)
@@ -722,12 +722,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)
@@ -906,12 +910,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);
 }
@@ -936,8 +944,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 b37ac5fdd964670f892d58ce7ca14f6dc07c09f1..c4eefe1bee3521689a571295e607464a316d65e9 100644 (file)
@@ -832,7 +832,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;
 }