From: Florian Westphal Date: Mon, 21 Jul 2025 11:36:03 +0000 (+0200) Subject: parser_json: fix assert due to empty interface name X-Git-Tag: v1.0.6.1~27 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=9d422f87420df734d0fd9adbe782fd2b1deb5693;p=thirdparty%2Fnftables.git parser_json: fix assert due to empty interface name commit 26f6ac378a49b3151a8c7e4bb0a94211b54708cc upstream. Before: nft: src/mnl.c:744: nft_dev_add: Assertion `ifname_len > 0' failed. After: internal:0:0-0: Error: empty interface name Bison checks this upfront, do same in json. Signed-off-by: Florian Westphal Reviewed-by: Pablo Neira Ayuso --- diff --git a/src/parser_json.c b/src/parser_json.c index f49c2619..d5cdc442 100644 --- a/src/parser_json.c +++ b/src/parser_json.c @@ -3006,6 +3006,25 @@ static struct expr *parse_policy(const char *policy) sizeof(int) * BITS_PER_BYTE, &policy_num); } +static struct expr *ifname_expr_alloc(struct json_ctx *ctx, + const char *name) +{ + size_t length = strlen(name); + + if (length == 0) { + json_error(ctx, "empty interface name"); + return NULL; + } + + if (length >= IFNAMSIZ) { + json_error(ctx, "Device name %s too long", name); + return NULL; + } + + return constant_expr_alloc(int_loc, &ifname_type, BYTEORDER_HOST_ENDIAN, + length * BITS_PER_BYTE, name); +} + static struct expr *json_parse_devs(struct json_ctx *ctx, json_t *root) { struct expr *tmp, *expr = compound_expr_alloc(int_loc, EXPR_LIST); @@ -3014,15 +3033,12 @@ static struct expr *json_parse_devs(struct json_ctx *ctx, json_t *root) size_t index; if (!json_unpack(root, "s", &dev)) { - if (strlen(dev) >= IFNAMSIZ) { - json_error(ctx, "Device name %s too long", dev); + tmp = ifname_expr_alloc(ctx, dev); + if (!tmp) { expr_free(expr); return NULL; } - tmp = constant_expr_alloc(int_loc, &ifname_type, - BYTEORDER_HOST_ENDIAN, - strlen(dev) * BITS_PER_BYTE, dev); compound_expr_add(expr, tmp); return expr; } @@ -3039,15 +3055,11 @@ static struct expr *json_parse_devs(struct json_ctx *ctx, json_t *root) return NULL; } - if (strlen(dev) >= IFNAMSIZ) { - json_error(ctx, "Device name %s too long at index %zu", dev, index); + tmp = ifname_expr_alloc(ctx, dev); + if (!tmp) { expr_free(expr); return NULL; } - - tmp = constant_expr_alloc(int_loc, &ifname_type, - BYTEORDER_HOST_ENDIAN, - strlen(dev) * BITS_PER_BYTE, dev); compound_expr_add(expr, tmp); } return expr; diff --git a/tests/shell/testcases/bogons/nft-j-f/mnl_nft_dev_add_ifname_len_0_assert b/tests/shell/testcases/bogons/nft-j-f/mnl_nft_dev_add_ifname_len_0_assert new file mode 100644 index 00000000..3be394c1 --- /dev/null +++ b/tests/shell/testcases/bogons/nft-j-f/mnl_nft_dev_add_ifname_len_0_assert @@ -0,0 +1,19 @@ +{ + "nftables": [ + { + "table": { "family": "netdev", "name": "test", "ha": 0, + "flags": "dormant" } }, +{ + "chain": { + "family": "netdev", + "table": "test", +"name": "ingress", + "le": 0, +"dev": "", "ha": 0, + "flags": "dormy1", "type": "fi", + "hook": "ingress", + "prio": 0, "policy": "drop" + } + } + ] +}