]> git.ipfire.org Git - thirdparty/nftables.git/commitdiff
parser: reject zero-length interface names
authorFlorian Westphal <fw@strlen.de>
Mon, 19 Jun 2023 20:43:04 +0000 (22:43 +0200)
committerFlorian Westphal <fw@strlen.de>
Tue, 20 Jun 2023 19:46:13 +0000 (21:46 +0200)
device "" results in an assertion during evaluation.
Before:
nft: expression.c:426: constant_expr_alloc: Assertion `(((len) + (8) - 1) / (8)) > 0' failed.
After:
zero_length_devicename_assert:3:42-49: Error: you cannot set an empty interface name
type filter hook ingress device""lo" priority -1
                         ^^^^^^^^
Signed-off-by: Florian Westphal <fw@strlen.de>
src/parser_bison.y
tests/shell/testcases/bogons/nft-f/zero_length_devicename_assert [new file with mode: 0644]

index f5f6bf04d06439f31a692bf5c10e2e8c8af703ab..9a4204c085dac98ca0fec072d39808b4dca9bf95 100644 (file)
@@ -144,6 +144,33 @@ static bool already_set(const void *attr, const struct location *loc,
        return true;
 }
 
+static struct expr *ifname_expr_alloc(const struct location *location,
+                                     struct list_head *queue,
+                                     const char *name)
+{
+       unsigned int length = strlen(name);
+       struct expr *expr;
+
+       if (length == 0) {
+               xfree(name);
+               erec_queue(error(location, "empty interface name"), queue);
+               return NULL;
+       }
+
+       if (length > 16) {
+               xfree(name);
+               erec_queue(error(location, "interface name too long"), queue);
+               return NULL;
+       }
+
+       expr = constant_expr_alloc(location, &ifname_type, BYTEORDER_HOST_ENDIAN,
+                                  length * BITS_PER_BYTE, name);
+
+       xfree(name);
+
+       return expr;
+}
+
 #define YYLLOC_DEFAULT(Current, Rhs, N)        location_update(&Current, Rhs, N)
 
 #define symbol_value(loc, str) \
@@ -2664,12 +2691,11 @@ int_num                 :       NUM                     { $$ = $1; }
 
 dev_spec               :       DEVICE  string
                        {
-                               struct expr *expr;
+                               struct expr *expr = ifname_expr_alloc(&@$, state->msgs, $2);
+
+                               if (!expr)
+                                       YYERROR;
 
-                               expr = constant_expr_alloc(&@$, &string_type,
-                                                          BYTEORDER_HOST_ENDIAN,
-                                                          strlen($2) * BITS_PER_BYTE, $2);
-                               xfree($2);
                                $$ = compound_expr_alloc(&@$, EXPR_LIST);
                                compound_expr_add($$, expr);
 
diff --git a/tests/shell/testcases/bogons/nft-f/zero_length_devicename_assert b/tests/shell/testcases/bogons/nft-f/zero_length_devicename_assert
new file mode 100644 (file)
index 0000000..84f3307
--- /dev/null
@@ -0,0 +1,5 @@
+table ip x {
+        chain Main_Ingress1 {
+                type filter hook ingress device""lo" priority -1
+       }
+}