]> git.ipfire.org Git - thirdparty/nftables.git/commitdiff
parser_json: fix assert due to empty interface name
authorFlorian Westphal <fw@strlen.de>
Mon, 21 Jul 2025 11:36:03 +0000 (13:36 +0200)
committerFlorian Westphal <fw@strlen.de>
Tue, 22 Jul 2025 12:38:37 +0000 (14:38 +0200)
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 <fw@strlen.de>
Reviewed-by: Pablo Neira Ayuso <pablo@netfilter.org>
src/parser_json.c
tests/shell/testcases/bogons/nft-j-f/mnl_nft_dev_add_ifname_len_0_assert [new file with mode: 0644]

index a6f142c68756083b2ff23a78075ce7910065e47d..be0de69837d8b5d1ec686fc1d155f3581665debb 100644 (file)
@@ -2959,6 +2959,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);
@@ -2967,15 +2986,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;
        }
@@ -2992,15 +3008,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 (file)
index 0000000..3be394c
--- /dev/null
@@ -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"
+  }
+    }
+  ]
+}