diff options
| author | Florian Westphal <fw@strlen.de> | 2025-11-25 14:03:33 +0100 |
|---|---|---|
| committer | Florian Westphal <fw@strlen.de> | 2025-12-06 11:24:01 +0100 |
| commit | d181bb815117b6a9f42d965db15227135866830f (patch) | |
| tree | f373a88ed2e64dac54c52a2764ecada2e6134630 | |
| parent | 9ce1e6f998176f1f9c359a7ded89e8b152a98959 (diff) | |
tests: shell: bad_rule_graphs: add chain linked from different hooks
On a kernel with broken (never upstreamed) patch this fails with:
Accepted bad ruleset with jump from filter type to masquerade (3)
and
Accepted bad ruleset with jump from prerouting to masquerade
... because bogus optimisation suppresses re-validation of 'n2', even
though it becomes reachable from an invalid base chain (filter, but n2
has nat-only masquerade expression).
Another broken corner-case is validation of the different hook types:
When it becomes reachable from nat:prerouting in addition to the allowed
nat:postrouting the validation step must fail.
Improve test coverage to ensure future optimisations catch this.
Signed-off-by: Florian Westphal <fw@strlen.de>
3 files changed, 173 insertions, 10 deletions
diff --git a/tests/shell/testcases/transactions/bad_rule_graphs b/tests/shell/testcases/transactions/bad_rule_graphs index 53047c3c..1f36bad8 100755 --- a/tests/shell/testcases/transactions/bad_rule_graphs +++ b/tests/shell/testcases/transactions/bad_rule_graphs @@ -259,4 +259,72 @@ $NFT "add rule t c9 tcp dport 80 tproxy to :20000 meta mark set 1 accept" good_ruleset $? "add tproxy expression to c9" check_bad_expr +$NFT -f - <<EOF +table t { + chain n2 { + meta oifname "ppp*" masquerade + } + + chain n1 { + ip saddr 192.168.0.0/16 jump n2 + } + + chain n0 { type nat hook postrouting priority 0; + jump n1 + } +} +EOF +good_ruleset $? "add nat skeleton" + +$NFT -f - <<EOF +table t { + chain c2 { + jump n2 + } +} +EOF +bad_ruleset $? "jump from filter type to masquerade" + +$NFT flush chain t n2 +$NFT -f - <<EOF +table t { + chain c2 { + jump n2 + } + + chain n2 { meta oifname "ppp0" masquerade; } +} +EOF +bad_ruleset $? "jump from filter type to masquerade (2)" + +$NFT -f - <<EOF +delete chain t c0 +delete chain t c1 +EOF +good_ruleset $? "delete c1/c0" + +$NFT -f - <<EOF +table t { + chain c1 { } + + chain n2 { masquerade; } + chain n1 { goto n2; } + + chain n0 { type nat hook postrouting priority 0; + goto n1 + } + + chain c0 { type filter hook input priority 0; + jump c1 + } +} +EOF +good_ruleset $? "add nat skeleton (2)" + +$NFT add rule t c1 goto n2 +bad_ruleset $? "jump from filter type to masquerade (3)" + +$NFT add chain 't invalid { type nat hook prerouting priority 0; goto n2; }' +bad_ruleset $? "jump from prerouting to masquerade" + exit $? diff --git a/tests/shell/testcases/transactions/dumps/bad_rule_graphs.json-nft b/tests/shell/testcases/transactions/dumps/bad_rule_graphs.json-nft index 30789211..7cc73148 100644 --- a/tests/shell/testcases/transactions/dumps/bad_rule_graphs.json-nft +++ b/tests/shell/testcases/transactions/dumps/bad_rule_graphs.json-nft @@ -50,6 +50,34 @@ "chain": { "family": "ip", "table": "t", + "name": "n2", + "handle": 0 + } + }, + { + "chain": { + "family": "ip", + "table": "t", + "name": "n1", + "handle": 0 + } + }, + { + "chain": { + "family": "ip", + "table": "t", + "name": "n0", + "handle": 0, + "type": "nat", + "hook": "postrouting", + "prio": 0, + "policy": "accept" + } + }, + { + "chain": { + "family": "ip", + "table": "t", "name": "c1", "handle": 0 } @@ -150,13 +178,11 @@ "rule": { "family": "ip", "table": "t", - "chain": "c1", + "chain": "n2", "handle": 0, "expr": [ { - "jump": { - "target": "c2" - } + "masquerade": null } ] } @@ -165,18 +191,74 @@ "rule": { "family": "ip", "table": "t", - "chain": "c1", + "chain": "n1", "handle": 0, "expr": [ { - "vmap": { - "key": { + "match": { + "op": "==", + "left": { "payload": { "protocol": "ip", "field": "saddr" } }, - "data": "@m" + "right": { + "prefix": { + "addr": "192.168.0.0", + "len": 16 + } + } + } + }, + { + "jump": { + "target": "n2" + } + } + ] + } + }, + { + "rule": { + "family": "ip", + "table": "t", + "chain": "n1", + "handle": 0, + "expr": [ + { + "goto": { + "target": "n2" + } + } + ] + } + }, + { + "rule": { + "family": "ip", + "table": "t", + "chain": "n0", + "handle": 0, + "expr": [ + { + "jump": { + "target": "n1" + } + } + ] + } + }, + { + "rule": { + "family": "ip", + "table": "t", + "chain": "n0", + "handle": 0, + "expr": [ + { + "goto": { + "target": "n1" } } ] diff --git a/tests/shell/testcases/transactions/dumps/bad_rule_graphs.nft b/tests/shell/testcases/transactions/dumps/bad_rule_graphs.nft index 3a593650..314809c3 100644 --- a/tests/shell/testcases/transactions/dumps/bad_rule_graphs.nft +++ b/tests/shell/testcases/transactions/dumps/bad_rule_graphs.nft @@ -18,9 +18,22 @@ table ip t { chain c2 { } + chain n2 { + masquerade + } + + chain n1 { + ip saddr 192.168.0.0/16 jump n2 + goto n2 + } + + chain n0 { + type nat hook postrouting priority filter; policy accept; + jump n1 + goto n1 + } + chain c1 { - jump c2 - ip saddr vmap @m } chain c0 { |
