diff options
author | Florian Westphal <fw@strlen.de> | 2023-03-15 13:57:38 +0100 |
---|---|---|
committer | Florian Westphal <fw@strlen.de> | 2023-03-27 17:01:58 +0200 |
commit | cd2d1fc4e8b114f8526b0ce61cfd5cfce8eacac6 (patch) | |
tree | 809a0be5813bb5bda8ec51d804a4675381a31b74 | |
parent | fe623a50949203fa979a79adc8f8af35b74b534c (diff) |
meta: don't crash if meta key isn't known
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>
-rw-r--r-- | src/meta.c | 31 | ||||
-rw-r--r-- | src/netlink_delinearize.c | 4 |
2 files changed, 24 insertions, 11 deletions
@@ -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; } diff --git a/src/netlink_delinearize.c b/src/netlink_delinearize.c index 60350cd6..d28b545e 100644 --- a/src/netlink_delinearize.c +++ b/src/netlink_delinearize.c @@ -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; } |