All of lore.kernel.org
 help / color / mirror / Atom feed
* [nft PATCH] datatype: fix ether address parsing of integer values
@ 2026-01-26  6:17 Brian Witte
  2026-01-26 12:08 ` Florian Westphal
  0 siblings, 1 reply; 3+ messages in thread
From: Brian Witte @ 2026-01-26  6:17 UTC (permalink / raw)
  To: netfilter-devel

When parsing "ether daddr 0x64", integer_expr converts the hex value
to decimal string "100". lladdr_type_parse then interprets this as
hex, yielding 0x100 = 256 which exceeds the single-byte limit.

Values below 0x64 (100) worked because their decimal representation
happens to be valid hex under 256.

Fix by detecting integer strings (no colons, known size) and parsing
as base-0 to handle both decimal and hex input correctly.

Bugzilla: https://bugzilla.netfilter.org/show_bug.cgi?id=1824
Signed-off-by: Brian Witte <brianwitte@mailfence.com>
---
 src/datatype.c                                | 17 ++++++++
 .../testcases/nft-f/0033ether_addr_hex_0      | 42 +++++++++++++++++++
 2 files changed, 59 insertions(+)
 create mode 100755 tests/shell/testcases/nft-f/0033ether_addr_hex_0

diff --git a/src/datatype.c b/src/datatype.c
index 18973851..d7817ef2 100644
--- a/src/datatype.c
+++ b/src/datatype.c
@@ -581,6 +581,23 @@ static struct error_record *lladdr_type_parse(struct parse_ctx *ctx,
 	const char *s = sym->identifier;
 	unsigned int len, n;
 
+	if (sym->dtype->size && !strchr(s, ':')) {
+		unsigned int size = sym->dtype->size / BITS_PER_BYTE;
+		uint64_t val;
+
+		errno = 0;
+		val = strtoull(s, &p, 0);
+		if (!errno && !*p && !(val >> (size * 8))) {
+			for (n = 0; n < size; n++)
+				buf[size - n - 1] = (val >> (n * 8)) & 0xff;
+
+			*res = constant_expr_alloc(&sym->location, sym->dtype,
+						   BYTEORDER_BIG_ENDIAN,
+						   sym->dtype->size, buf);
+			return NULL;
+		}
+	}
+
 	for (len = 0;;) {
 		n = strtoul(s, &p, 16);
 		if (s == p || n > 0xff)
diff --git a/tests/shell/testcases/nft-f/0033ether_addr_hex_0 b/tests/shell/testcases/nft-f/0033ether_addr_hex_0
new file mode 100755
index 00000000..149b8f52
--- /dev/null
+++ b/tests/shell/testcases/nft-f/0033ether_addr_hex_0
@@ -0,0 +1,42 @@
+#!/bin/bash
+
+set -e
+
+RULESET="table inet t {
+	chain c {
+		ether daddr 0x0 accept
+		ether daddr 0x64 accept
+		ether daddr 0xff accept
+		ether daddr 0x100 accept
+		ether daddr 0xffffffffffff accept
+		ether daddr aa accept
+		ether saddr de:ad:be:ef:00:01 accept
+	}
+}"
+
+EXPECTED="table inet t {
+	chain c {
+		ether daddr 00:00:00:00:00:00 accept
+		ether daddr 00:00:00:00:00:64 accept
+		ether daddr 00:00:00:00:00:ff accept
+		ether daddr 00:00:00:00:01:00 accept
+		ether daddr ff:ff:ff:ff:ff:ff accept
+		ether daddr 00:00:00:00:00:aa accept
+		ether saddr de:ad:be:ef:00:01 accept
+	}
+}"
+
+$NFT -f - <<< "$RULESET"
+
+GET="$($NFT list ruleset)"
+
+if [ "$EXPECTED" != "$GET" ] ; then
+	$DIFF -u <(echo "$EXPECTED") <(echo "$GET")
+	exit 1
+fi
+
+# overflow must fail
+if $NFT add rule inet t c ether daddr 0x1000000000000 accept 2>/dev/null; then
+	echo "FAIL: overflow not rejected" >&2
+	exit 1
+fi
-- 
2.47.3


^ permalink raw reply related	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2026-01-26 17:38 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-01-26  6:17 [nft PATCH] datatype: fix ether address parsing of integer values Brian Witte
2026-01-26 12:08 ` Florian Westphal
2026-01-26 17:38   ` Brian Witte

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.