Skip to content

Commit 898ae76

Browse files
committed
Florian Westphal says: ==================== netfilter: updates for net 1) Fix refcount leaks in nf_conncount, from Fernando Fernandez Mancera. This addresses a recent regression that came in the last -next pull request. 2) Fix a null dereference in route error handling in IPVS, from Slavin Liu. This is an ancient issue dating back to 5.1 days. 3) Always set ifindex in route tuple in the flowtable output path, from Lorenzo Bianconi. This bug came in with the recent output path refactoring. 4) Prefer 'exit $ksft_xfail' over 'exit $ksft_skip' when we fail to trigger a nat race condition to exercise the clash resolution path in selftest infra, $ksft_skip should be reserved for missing tooling, From myself. * tag 'nf-25-12-10' of https://git.kernel.org/pub/scm/linux/kernel/git/netfilter/nf: selftests: netfilter: prefer xfail in case race wasn't triggered netfilter: always set route tuple out ifindex ipvs: fix ipv4 null-ptr-deref in route error path netfilter: nf_conncount: fix leaked ct in error paths ==================== Link: https://patch.msgid.link/20251210110754.22620-1-fw@strlen.de Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2 parents 237c1e1 + b8a81b0 commit 898ae76

4 files changed

Lines changed: 24 additions & 17 deletions

File tree

net/netfilter/ipvs/ip_vs_xmit.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -408,6 +408,9 @@ __ip_vs_get_out_rt(struct netns_ipvs *ipvs, int skb_af, struct sk_buff *skb,
408408
return -1;
409409

410410
err_unreach:
411+
if (!skb->dev)
412+
skb->dev = skb_dst(skb)->dev;
413+
411414
dst_link_failure(skb);
412415
return -1;
413416
}

net/netfilter/nf_conncount.c

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -172,14 +172,14 @@ static int __nf_conncount_add(struct net *net,
172172
struct nf_conn *found_ct;
173173
unsigned int collect = 0;
174174
bool refcounted = false;
175+
int err = 0;
175176

176177
if (!get_ct_or_tuple_from_skb(net, skb, l3num, &ct, &tuple, &zone, &refcounted))
177178
return -ENOENT;
178179

179180
if (ct && nf_ct_is_confirmed(ct)) {
180-
if (refcounted)
181-
nf_ct_put(ct);
182-
return -EEXIST;
181+
err = -EEXIST;
182+
goto out_put;
183183
}
184184

185185
if ((u32)jiffies == list->last_gc)
@@ -231,12 +231,16 @@ static int __nf_conncount_add(struct net *net,
231231
}
232232

233233
add_new_node:
234-
if (WARN_ON_ONCE(list->count > INT_MAX))
235-
return -EOVERFLOW;
234+
if (WARN_ON_ONCE(list->count > INT_MAX)) {
235+
err = -EOVERFLOW;
236+
goto out_put;
237+
}
236238

237239
conn = kmem_cache_alloc(conncount_conn_cachep, GFP_ATOMIC);
238-
if (conn == NULL)
239-
return -ENOMEM;
240+
if (conn == NULL) {
241+
err = -ENOMEM;
242+
goto out_put;
243+
}
240244

241245
conn->tuple = tuple;
242246
conn->zone = *zone;
@@ -249,7 +253,7 @@ static int __nf_conncount_add(struct net *net,
249253
out_put:
250254
if (refcounted)
251255
nf_ct_put(ct);
252-
return 0;
256+
return err;
253257
}
254258

255259
int nf_conncount_add_skb(struct net *net,
@@ -456,11 +460,10 @@ insert_tree(struct net *net,
456460

457461
rb_link_node_rcu(&rbconn->node, parent, rbnode);
458462
rb_insert_color(&rbconn->node, root);
459-
460-
if (refcounted)
461-
nf_ct_put(ct);
462463
}
463464
out_unlock:
465+
if (refcounted)
466+
nf_ct_put(ct);
464467
spin_unlock_bh(&nf_conncount_locks[hash]);
465468
return count;
466469
}

net/netfilter/nf_flow_table_path.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,9 @@ static void nft_dev_forward_path(const struct nft_pktinfo *pkt,
250250
if (nft_dev_fill_forward_path(route, dst, ct, dir, ha, &stack) >= 0)
251251
nft_dev_path_info(&stack, &info, ha, &ft->data);
252252

253+
if (info.outdev)
254+
route->tuple[dir].out.ifindex = info.outdev->ifindex;
255+
253256
if (!info.indev || !nft_flowtable_find_dev(info.indev, ft))
254257
return;
255258

@@ -269,7 +272,6 @@ static void nft_dev_forward_path(const struct nft_pktinfo *pkt,
269272

270273
route->tuple[!dir].in.num_encaps = info.num_encaps;
271274
route->tuple[!dir].in.ingress_vlans = info.ingress_vlans;
272-
route->tuple[dir].out.ifindex = info.outdev->ifindex;
273275

274276
if (info.xmit_type == FLOW_OFFLOAD_XMIT_DIRECT) {
275277
memcpy(route->tuple[dir].out.h_source, info.h_source, ETH_ALEN);

tools/testing/selftests/net/netfilter/conntrack_clash.sh

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ run_one_clash_test()
116116
# not a failure: clash resolution logic did not trigger.
117117
# With right timing, xmit completed sequentially and
118118
# no parallel insertion occurs.
119-
return $ksft_skip
119+
return $ksft_xfail
120120
}
121121

122122
run_clash_test()
@@ -133,12 +133,12 @@ run_clash_test()
133133
if [ $rv -eq 0 ];then
134134
echo "PASS: clash resolution test for $daddr:$dport on attempt $i"
135135
return 0
136-
elif [ $rv -eq $ksft_skip ]; then
136+
elif [ $rv -eq $ksft_xfail ]; then
137137
softerr=1
138138
fi
139139
done
140140

141-
[ $softerr -eq 1 ] && echo "SKIP: clash resolution for $daddr:$dport did not trigger"
141+
[ $softerr -eq 1 ] && echo "XFAIL: clash resolution for $daddr:$dport did not trigger"
142142
}
143143

144144
ip link add veth0 netns "$nsclient1" type veth peer name veth0 netns "$nsrouter"
@@ -167,8 +167,7 @@ load_simple_ruleset "$nsclient2"
167167
run_clash_test "$nsclient2" "$nsclient2" 127.0.0.1 9001
168168

169169
if [ $clash_resolution_active -eq 0 ];then
170-
[ "$ret" -eq 0 ] && ret=$ksft_skip
171-
echo "SKIP: Clash resolution did not trigger"
170+
[ "$ret" -eq 0 ] && ret=$ksft_xfail
172171
fi
173172

174173
exit $ret

0 commit comments

Comments
 (0)