netfilter pull request nf-25-10-08

-----BEGIN PGP SIGNATURE-----
 
 iQJBBAABCAArFiEEgKkgxbID4Gn1hq6fcJGo2a1f9gAFAmjmXroNHGZ3QHN0cmxl
 bi5kZQAKCRBwkajZrV/2AEPmD/wJVaVNhEgmqY0abipD7Sx59ygRIVn6JSLGtimS
 UO8G9S3cr3nT4i2wr1MYNiUQyjs18u4Q73kr8tKalXV99E05OVW1tWAeAztQDeZM
 UNDf44Of1XwwlthIuQa7vyt4aqxmGhQDXKcj1cx2ZHjYQbJ3GshoMAZq90iKKqXN
 Qlbpy216P71KzaN214bKDSgx8ffoWDRxcQwnbY4EWzMErKJqr5I6zLoJo9hMms0X
 JpEqkUaY4PdackQJmBEoOaMphiG9H0u16PtEycfu++YrM/Xf5CJpiCFkp9mjZs+E
 iNpLNF70phCA2ih3mwZFzfgPjYCXNSElOt0lGJFZVTVlGb8HLfBRNxKRMKsaCeZc
 THZSPo2KMPI+UZle5Cyj9WNLWoVeTNtc2BlmMbSiTRRV5BWp1z20zgfymS++t0F7
 hul2wWT7EH0cD87lJ/YUaGcM60nTZuNz7dKchTICwVyWpvCh0W/IhHM1JavfdPg2
 gGCyPPsy1NKwXLCBym/DpKfIIwjR3bqH4s9miZRHt1a2PVX+JWxK72D0RasWPISz
 cNs6bzQhfi6Q2l6gFJ8iGWWVr+L7J5+JmLdp8G4yQaJ+Fa7LggCIVMGOpl4QD7oA
 lILvaXdfi402Oqkcho02gbtC0iDgVA8Grs28r/6KBsVFseejClvh7LQe9YLoFNZT
 Fp7oAQ==
 =u19C
 -----END PGP SIGNATURE-----

Merge tag 'nf-25-10-08' of https://git.kernel.org/pub/scm/linux/kernel/git/netfilter/nf

Florian Westphal says:

====================
netfilter: updates for net

The following patchset contains Netfilter fixes for *net*:

1) Fix crash (call recursion) when nftables synproxy extension is used
   in an object map.  When this feature was added in v5.4 the required
   hook call validation was forgotten.
   Fix from Fernando Fernandez Mancera.
2) bridge br_vlan_fill_forward_path_pvid uses incorrect
   rcu_dereference_protected(); we only have rcu read lock but not
   RTNL.  Fix from Eric Woudstra.

Last two patches address flakes in two existing selftests.

netfilter pull request nf-25-10-08

* tag 'nf-25-10-08' of https://git.kernel.org/pub/scm/linux/kernel/git/netfilter/nf:
  selftests: netfilter: query conntrack state to check for port clash resolution
  selftests: netfilter: nft_fib.sh: fix spurious test failures
  bridge: br_vlan_fill_forward_path_pvid: use br_vlan_group_rcu()
  netfilter: nft_objref: validate objref and objrefmap expressions
====================

Link: https://patch.msgid.link/20251008125942.25056-1-fw@strlen.de
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
This commit is contained in:
Paolo Abeni 2025-10-09 10:07:44 +02:00
commit 2854378a00
4 changed files with 89 additions and 23 deletions

View File

@ -1457,7 +1457,7 @@ void br_vlan_fill_forward_path_pvid(struct net_bridge *br,
if (!br_opt_get(br, BROPT_VLAN_ENABLED))
return;
vg = br_vlan_group(br);
vg = br_vlan_group_rcu(br);
if (idx >= 0 &&
ctx->vlan[idx].proto == br->vlan_proto) {

View File

@ -22,6 +22,35 @@ void nft_objref_eval(const struct nft_expr *expr,
obj->ops->eval(obj, regs, pkt);
}
static int nft_objref_validate_obj_type(const struct nft_ctx *ctx, u32 type)
{
unsigned int hooks;
switch (type) {
case NFT_OBJECT_SYNPROXY:
if (ctx->family != NFPROTO_IPV4 &&
ctx->family != NFPROTO_IPV6 &&
ctx->family != NFPROTO_INET)
return -EOPNOTSUPP;
hooks = (1 << NF_INET_LOCAL_IN) | (1 << NF_INET_FORWARD);
return nft_chain_validate_hooks(ctx->chain, hooks);
default:
break;
}
return 0;
}
static int nft_objref_validate(const struct nft_ctx *ctx,
const struct nft_expr *expr)
{
struct nft_object *obj = nft_objref_priv(expr);
return nft_objref_validate_obj_type(ctx, obj->ops->type->type);
}
static int nft_objref_init(const struct nft_ctx *ctx,
const struct nft_expr *expr,
const struct nlattr * const tb[])
@ -93,6 +122,7 @@ static const struct nft_expr_ops nft_objref_ops = {
.activate = nft_objref_activate,
.deactivate = nft_objref_deactivate,
.dump = nft_objref_dump,
.validate = nft_objref_validate,
.reduce = NFT_REDUCE_READONLY,
};
@ -197,6 +227,14 @@ static void nft_objref_map_destroy(const struct nft_ctx *ctx,
nf_tables_destroy_set(ctx, priv->set);
}
static int nft_objref_map_validate(const struct nft_ctx *ctx,
const struct nft_expr *expr)
{
const struct nft_objref_map *priv = nft_expr_priv(expr);
return nft_objref_validate_obj_type(ctx, priv->set->objtype);
}
static const struct nft_expr_ops nft_objref_map_ops = {
.type = &nft_objref_type,
.size = NFT_EXPR_SIZE(sizeof(struct nft_objref_map)),
@ -206,6 +244,7 @@ static const struct nft_expr_ops nft_objref_map_ops = {
.deactivate = nft_objref_map_deactivate,
.destroy = nft_objref_map_destroy,
.dump = nft_objref_map_dump,
.validate = nft_objref_map_validate,
.reduce = NFT_REDUCE_READONLY,
};

View File

@ -17,9 +17,31 @@ cleanup()
checktool "socat -h" "run test without socat"
checktool "iptables --version" "run test without iptables"
checktool "conntrack --version" "run test without conntrack"
trap cleanup EXIT
connect_done()
{
local ns="$1"
local port="$2"
ip netns exec "$ns" ss -nt -o state established "dport = :$port" | grep -q "$port"
}
check_ctstate()
{
local ns="$1"
local dp="$2"
if ! ip netns exec "$ns" conntrack --get -s 192.168.1.2 -d 192.168.1.1 -p tcp \
--sport 10000 --dport "$dp" --state ESTABLISHED > /dev/null 2>&1;then
echo "FAIL: Did not find expected state for dport $2"
ip netns exec "$ns" bash -c 'conntrack -L; conntrack -S; ss -nt'
ret=1
fi
}
setup_ns ns1 ns2
# Connect the namespaces using a veth pair
@ -44,15 +66,18 @@ socatpid=$!
ip netns exec "$ns2" sysctl -q net.ipv4.ip_local_port_range="10000 10000"
# add a virtual IP using DNAT
ip netns exec "$ns2" iptables -t nat -A OUTPUT -d 10.96.0.1/32 -p tcp --dport 443 -j DNAT --to-destination 192.168.1.1:5201
ip netns exec "$ns2" iptables -t nat -A OUTPUT -d 10.96.0.1/32 -p tcp --dport 443 -j DNAT --to-destination 192.168.1.1:5201 || exit 1
# ... and route it to the other namespace
ip netns exec "$ns2" ip route add 10.96.0.1 via 192.168.1.1
# add a persistent connection from the other namespace
ip netns exec "$ns2" socat -t 10 - TCP:192.168.1.1:5201 > /dev/null &
# listener should be up by now, wait if it isn't yet.
wait_local_port_listen "$ns1" 5201 tcp
sleep 1
# add a persistent connection from the other namespace
sleep 10 | ip netns exec "$ns2" socat -t 10 - TCP:192.168.1.1:5201 > /dev/null &
cpid0=$!
busywait "$BUSYWAIT_TIMEOUT" connect_done "$ns2" "5201"
# ip daddr:dport will be rewritten to 192.168.1.1 5201
# NAT must reallocate source port 10000 because
@ -71,26 +96,25 @@ fi
ip netns exec "$ns1" iptables -t nat -A PREROUTING -p tcp --dport 5202 -j REDIRECT --to-ports 5201
ip netns exec "$ns1" iptables -t nat -A PREROUTING -p tcp --dport 5203 -j REDIRECT --to-ports 5201
sleep 5 | ip netns exec "$ns2" socat -t 5 -u STDIN TCP:192.168.1.1:5202,connect-timeout=5 >/dev/null &
sleep 5 | ip netns exec "$ns2" socat -T 5 -u STDIN TCP:192.168.1.1:5202,connect-timeout=5 >/dev/null &
cpid1=$!
# if connect succeeds, client closes instantly due to EOF on stdin.
# if connect hangs, it will time out after 5s.
echo | ip netns exec "$ns2" socat -t 3 -u STDIN TCP:192.168.1.1:5203,connect-timeout=5 >/dev/null &
sleep 5 | ip netns exec "$ns2" socat -T 5 -u STDIN TCP:192.168.1.1:5203,connect-timeout=5 >/dev/null &
cpid2=$!
time_then=$(date +%s)
wait $cpid2
rv=$?
time_now=$(date +%s)
busywait "$BUSYWAIT_TIMEOUT" connect_done "$ns2" 5202
busywait "$BUSYWAIT_TIMEOUT" connect_done "$ns2" 5203
# Check how much time has elapsed, expectation is for
# 'cpid2' to connect and then exit (and no connect delay).
delta=$((time_now - time_then))
check_ctstate "$ns1" 5202
check_ctstate "$ns1" 5203
if [ $delta -lt 2 ] && [ $rv -eq 0 ]; then
kill $socatpid $cpid0 $cpid1 $cpid2
socatpid=0
if [ $ret -eq 0 ]; then
echo "PASS: could connect to service via redirected ports"
else
echo "FAIL: socat cannot connect to service via redirect ($delta seconds elapsed, returned $rv)"
echo "FAIL: socat cannot connect to service via redirect"
ret=1
fi

View File

@ -256,12 +256,12 @@ test_ping_unreachable() {
local daddr4=$1
local daddr6=$2
if ip netns exec "$ns1" ping -c 1 -w 1 -q "$daddr4" > /dev/null; then
if ip netns exec "$ns1" ping -c 1 -W 0.1 -q "$daddr4" > /dev/null; then
echo "FAIL: ${ns1} could reach $daddr4" 1>&2
return 1
fi
if ip netns exec "$ns1" ping -c 1 -w 1 -q "$daddr6" > /dev/null; then
if ip netns exec "$ns1" ping -c 1 -W 0.1 -q "$daddr6" > /dev/null; then
echo "FAIL: ${ns1} could reach $daddr6" 1>&2
return 1
fi
@ -437,14 +437,17 @@ check_type()
local addr="$3"
local type="$4"
local count="$5"
local lret=0
[ -z "$count" ] && count=1
if ! ip netns exec "$nsrouter" nft get element inet t "$setname" { "$iifname" . "$addr" . "$type" } |grep -q "counter packets $count";then
echo "FAIL: did not find $iifname . $addr . $type in $setname"
echo "FAIL: did not find $iifname . $addr . $type in $setname with $count packets"
ip netns exec "$nsrouter" nft list set inet t "$setname"
ret=1
return 1
# do not fail right away, delete entry if it exists so later test that
# checks for unwanted keys don't get confused by this *expected* key.
lret=1
fi
# delete the entry, this allows to check if anything unexpected appeared
@ -456,7 +459,7 @@ check_type()
return 1
fi
return 0
return $lret
}
check_local()