]> git.ipfire.org Git - thirdparty/nftables.git/commitdiff
tests: shell: add test case for basechain abort path master
authorFlorian Westphal <fw@strlen.de>
Wed, 25 Feb 2026 11:05:40 +0000 (12:05 +0100)
committerFlorian Westphal <fw@strlen.de>
Sun, 12 Apr 2026 17:28:27 +0000 (19:28 +0200)
Add coverage for failing basechain add.

'inet' has to register both ipv6 and ipv4 rules.
If all ipv6 slots are already taken, the chain add will fail.

As it was already exposed (albeit only for a very short time) to
dumpers and packet path, it must not be free'd before an RCU
grace period has elapsed.  Check for this.

Signed-off-by: Florian Westphal <fw@strlen.de>
tests/shell/testcases/transactions/basechain_add_failure [new file with mode: 0755]
tests/shell/testcases/transactions/dumps/basechain_add_failure.nodump [new file with mode: 0644]

diff --git a/tests/shell/testcases/transactions/basechain_add_failure b/tests/shell/testcases/transactions/basechain_add_failure
new file mode 100755 (executable)
index 0000000..1dae958
--- /dev/null
@@ -0,0 +1,69 @@
+#!/bin/bash
+
+# Test for kernel commit
+# 71e99ee20fc3 ("netfilter: nf_tables: fix use-after-free in nf_tables_addchain()")
+
+duration=10
+p=$(nproc)
+
+[ $p -gt 1 ] && p=$((p-1))
+
+ip link set lo up
+
+$NFT -f - <<EOF
+table inet test {
+       chain test {
+
+       }
+}
+EOF
+[ $? -ne 0 ] && exit 1
+
+( echo 'table ip6 t {' ; for i in $(seq 1 1000); do echo "chain c$i { type filter hook input priority 0; }"; done ; echo "}" ) | $NFT -f -
+[ $? -ne 0 ] && exit 1
+
+for i in $(seq 1000 3000); do
+       $NFT add chain ip6 t c$i "{ type filter hook input priority 0; }" || break
+done
+
+for i in $(seq 1 $p); do
+       timeout $duration ping -q -f 127.0.0.1 > /dev/null 2>&1 &
+done
+
+end=$(date +%s)
+end=$((end + duration))
+
+cnt=0
+while : ; do
+       for i in $(seq 1 $p);do
+               ( $NFT -n --terse list table inet test > /dev/null || exit 1 ) &
+       done
+
+       cnt=$((cnt+1))
+       cnt=$((cnt % 100))
+       if [ $cnt -eq 0 ] ;then
+               wait
+               [ $? -ne 0 ] && exit 1
+
+               now=$(date +%s)
+               [ "$now" -ge "$end" ] && exit 0
+       fi
+done &
+
+cnt=0
+while : ; do
+       # expected to fail due to 1k ip6 hooks.
+       if $NFT add chain inet test c "{ type filter hook input priority 0; }" 2>/dev/null ; then
+               echo "Expected add chain to fail"
+               exit 1
+       fi
+
+       cnt=$((cnt+1))
+       if [ $((cnt % 100)) -eq 0 ] ;then
+               now=$(date +%s)
+               [ "$now" -ge "$end" ] && break
+       fi
+done
+
+wait
+echo "Done, looped $cnt times."
diff --git a/tests/shell/testcases/transactions/dumps/basechain_add_failure.nodump b/tests/shell/testcases/transactions/dumps/basechain_add_failure.nodump
new file mode 100644 (file)
index 0000000..e69de29