From: Florian Westphal <fw@strlen.de>
To: <netfilter-devel@vger.kernel.org>
Cc: Florian Westphal <fw@strlen.de>
Subject: [PATCH nft 4/4] expression: expr_build_udata_recurse should recurse
Date: Thu, 27 Feb 2025 15:52:10 +0100 [thread overview]
Message-ID: <20250227145214.27730-5-fw@strlen.de> (raw)
In-Reply-To: <20250227145214.27730-1-fw@strlen.de>
If we see EXPR_BINOP, recurse: ->left can be another EXPR_BINOP.
This is irrelevant for 'typeof' named sets, but for anonymous sets, the
key is derived from the concat expression that builds the lookup key for
the anonymous set.
tcp option mptcp subtype . ip daddr { mp-join. 10.0.0.1, ..
needs two binops back-to-back:
[ exthdr load tcpopt 1b @ 30 + 2 => reg 1 ]
[ bitwise reg 1 = ( reg 1 & 0x000000f0 ) ^ 0x00000000 ]
[ bitwise reg 1 = ( reg 1 >> 0x00000004 ) ]
This bug prevents concat_expr_build_udata() from creating the userdata key
at load time.
When listing the rules, we get an assertion:
nft: src/mergesort.c:23: concat_expr_msort_value: Assertion `ilen > 0' failed.
because the set has a key with 0-length integers.
Signed-off-by: Florian Westphal <fw@strlen.de>
---
src/expression.c | 2 +-
tests/py/any/tcpopt.t | 1 +
tests/py/any/tcpopt.t.json | 77 +++++++++++++++++++++++++++++++++++
tests/py/any/tcpopt.t.payload | 13 ++++++
4 files changed, 92 insertions(+), 1 deletion(-)
diff --git a/src/expression.c b/src/expression.c
index d2fa46509262..8a90e09dd1c5 100644
--- a/src/expression.c
+++ b/src/expression.c
@@ -1078,7 +1078,7 @@ static struct expr *expr_build_udata_recurse(struct expr *e)
{
switch (e->etype) {
case EXPR_BINOP:
- return e->left;
+ return expr_build_udata_recurse(e->left);
default:
break;
}
diff --git a/tests/py/any/tcpopt.t b/tests/py/any/tcpopt.t
index 79699e23a4b1..3d46c0efc231 100644
--- a/tests/py/any/tcpopt.t
+++ b/tests/py/any/tcpopt.t
@@ -54,6 +54,7 @@ tcp option mptcp exists;ok
tcp option mptcp subtype mp-capable;ok
tcp option mptcp subtype 1;ok;tcp option mptcp subtype mp-join
tcp option mptcp subtype { mp-capable, mp-join, remove-addr, mp-prio, mp-fail, mp-fastclose, mp-tcprst };ok
+tcp option mptcp subtype . tcp dport { mp-capable . 10, mp-join . 100, add-addr . 200, remove-addr . 300, mp-prio . 400, mp-fail . 500, mp-fastclose . 600, mp-tcprst . 700 };ok
reset tcp option mptcp;ok
reset tcp option 2;ok;reset tcp option maxseg
diff --git a/tests/py/any/tcpopt.t.json b/tests/py/any/tcpopt.t.json
index a02e71b66c36..e712a5e0ed56 100644
--- a/tests/py/any/tcpopt.t.json
+++ b/tests/py/any/tcpopt.t.json
@@ -591,6 +591,83 @@
}
]
+# tcp option mptcp subtype . tcp dport { mp-capable . 10, mp-join . 100, add-addr . 200, remove-addr . 300, mp-prio . 400, mp-fail . 500, mp-fastclose . 600, mp-tcprst . 700 }
+[
+ {
+ "match": {
+ "left": {
+ "concat": [
+ {
+ "tcp option": {
+ "field": "subtype",
+ "name": "mptcp"
+ }
+ },
+ {
+ "payload": {
+ "field": "dport",
+ "protocol": "tcp"
+ }
+ }
+ ]
+ },
+ "op": "==",
+ "right": {
+ "set": [
+ {
+ "concat": [
+ "mp-capable",
+ 10
+ ]
+ },
+ {
+ "concat": [
+ "remove-addr",
+ 300
+ ]
+ },
+ {
+ "concat": [
+ "mp-fastclose",
+ 600
+ ]
+ },
+ {
+ "concat": [
+ "mp-join",
+ 100
+ ]
+ },
+ {
+ "concat": [
+ "mp-prio",
+ 400
+ ]
+ },
+ {
+ "concat": [
+ "mp-tcprst",
+ 700
+ ]
+ },
+ {
+ "concat": [
+ "add-addr",
+ 200
+ ]
+ },
+ {
+ "concat": [
+ "mp-fail",
+ 500
+ ]
+ }
+ ]
+ }
+ }
+ }
+]
+
# reset tcp option mptcp
[
{
diff --git a/tests/py/any/tcpopt.t.payload b/tests/py/any/tcpopt.t.payload
index af8c4317e567..437e073aae1c 100644
--- a/tests/py/any/tcpopt.t.payload
+++ b/tests/py/any/tcpopt.t.payload
@@ -189,6 +189,19 @@ ip test-ip4 input
[ bitwise reg 1 = ( reg 1 & 0x000000f0 ) ^ 0x00000000 ]
[ lookup reg 1 set __set%d ]
+# tcp option mptcp subtype . tcp dport { mp-capable . 10, mp-join . 100, add-addr . 200, remove-addr . 300, mp-prio . 400, mp-fail . 500, mp-fastclose . 600, mp-tcprst . 700 }
+__set%d test-ip4 3
+__set%d test-ip4 0
+ element 00000000 00000a00 : 0 [end] element 00000001 00006400 : 0 [end] element 00000003 0000c800 : 0 [end] element 00000004 00002c01 : 0 [end] element 00000005 00009001 : 0 [end] element 00000006 0000f401 : 0 [end] element 00000007 00005802 : 0 [end] element 00000008 0000bc02 : 0 [end]
+ip test-ip4 input
+ [ meta load l4proto => reg 1 ]
+ [ cmp eq reg 1 0x00000006 ]
+ [ exthdr load tcpopt 1b @ 30 + 2 => reg 1 ]
+ [ bitwise reg 1 = ( reg 1 & 0x000000f0 ) ^ 0x00000000 ]
+ [ bitwise reg 1 = ( reg 1 >> 0x00000004 ) ]
+ [ payload load 2b @ transport header + 2 => reg 9 ]
+ [ lookup reg 1 set __set%d ]
+
# reset tcp option mptcp
ip test-ip4 input
[ exthdr reset tcpopt 30 ]
--
2.45.3
next prev parent reply other threads:[~2025-02-27 14:53 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-02-27 14:52 [PATCH nft 0/4] add mptcp suboption mnemonics Florian Westphal
2025-02-27 14:52 ` [PATCH nft 1/4] tcpopt: add symbol table for mptcp suboptions Florian Westphal
2025-02-27 14:52 ` [PATCH nft 2/4] expression: propagate key datatype for anonymous sets Florian Westphal
2025-02-27 14:52 ` [PATCH nft 3/4] netlink_delinearize: also consider exthdr type when trimming binops Florian Westphal
2025-02-27 14:52 ` Florian Westphal [this message]
2025-03-05 21:03 ` [PATCH nft 0/4] add mptcp suboption mnemonics Pablo Neira Ayuso
2025-03-05 22:40 ` Pablo Neira Ayuso
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20250227145214.27730-5-fw@strlen.de \
--to=fw@strlen.de \
--cc=netfilter-devel@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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.