mirror of
https://github.com/torvalds/linux.git
synced 2026-10-11 21:07:03 +02:00
netfilter pull request 26-09-18
-----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEEjF9xRqF1emXiQiqU1w0aZmrPKyEFAmqtHzMACgkQ1w0aZmrP KyGtkQ//bMKQGEudQKCMCtQmPqaHyW1ajmAo17aumfczaE/nSjqrsGY5Ahw7OKlQ 4otcdPvI4qpV9sLTg41KFaIHIC5sozxt4Q3m3RNB2TbyCkGn9xpSpZxM5IpHybvE 83tVjSA0wpfIqxBEqKUqk8Z9AXtBLo/JocdfYry+6JUyj4PM76X2ViKpzaPbpoMU 1mndfLAYtADIIvs3805CmfdJmOkoSV6XCEsiNutPrJhiRfN4xJZ9leP9xb1zA0IQ cnqiaw1xkTcFyWCicu4MqOkEALRknr9SL2yX1S9wx5Q6WHwU9JXUeQTlvfv7OoVP uxuMlNr3WcbwHC9e1GfOHapzjrYgnvEe2Z79i2GFh51Ci+5L9Yr9XCQ/fc6G5NNZ 3W52kh35s3lXq32hll9Tkr7pf4cKLBA+IAJ19VNlRfMrPB0cz4EqbIZ6xNNuLqdh DbEb3VgTT2dHwuGxEshJVmSfzfR+VeHBG2ZRlRmZElfhViHEwgPaAxkaJhNpPyub qmHbZCXK0BVp/UrGHDm5rmHJtdkwprXY9YceZBRfW8Fr2Ler4rWQvy+uo9sRRFgN oF9B6qzSl78THBv3UDB3U+aWuDv0I+VlDub0DKf0k9iWg8OoMlM9yw6OE9ULHt3m LRvSAfF0LnF/z7byzumUYMVjpVuIVueDzasGrEZjWbHHE7MCsp0= =RfSQ -----END PGP SIGNATURE----- Merge tag 'nf-26-09-18' of git://git.kernel.org/pub/scm/linux/kernel/git/netfilter/nf Pablo Neira Ayuso says: ==================== Netfilter/IPVS fixes for net The following patchset contains Netfilter/IPVS fixes for net, they are: 1) Set on HW_DEAD after HW_PENDING is cleared in the flowtable offload to ensure GC does not zap it, from Jérémy Jean. 2) Hold the nfnetlink_queue mutex while removing the queue instance from the netlink notifier that handles NETLINK_URELEASE to fix a possible race with the UNBIND command. From Florian Westphal. 3) Reject route with NULL rt6i_idev in ip6t_rpfilter. From Weiming Shi. 4) Reject rtinfo->addrnr set to zero from ip6t_rt .checkentry path. This also fortifies the datapath loop as per Florian's request. From Luxiao Xu. 5) Fix checksuming in nft_synproxy for IPv6, from Karl Mehltretter. 6) Revalidate ihl before calling icmp_send() in IPVS, from Julian Anastasov. 7) Fix suspicious RCU usage splat in ctnetlink with expectations. 8) Check for expired catchall elements in the insert and deactivate path. From Aohan Mei. * tag 'nf-26-09-18' of git://git.kernel.org/pub/scm/linux/kernel/git/netfilter/nf: netfilter: nf_tables: skip expired catchall elements on insert and delete netfilter: ctnetlink: fix suspicious RCU usage in expect_iter_name ipvs: revalidate ihl before icmp_send netfilter: nft_synproxy: use the family-aware checksum helper netfilter: ip6t_rt: fix zero-address non-strict match out-of-bounds read netfilter: ip6t_rpfilter: reject routes without inet6_dev netfilter: nfnetlink_queue: hold nfnl mutex in event notifier netfilter: flowtable: publish HW_DEAD after worker is done ==================== Link: https://patch.msgid.link/20260918112844.194503-1-pablo@netfilter.org Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
commit
12fec40907
|
|
@ -61,7 +61,7 @@ static bool rpfilter_lookup_reverse6(struct net *net, const struct sk_buff *skb,
|
|||
fl6.flowi6_oif = dev->ifindex;
|
||||
|
||||
rt = (void *)ip6_route_lookup(net, &fl6, skb, lookup_flags);
|
||||
if (rt->dst.error)
|
||||
if (rt->dst.error || !rt->rt6i_idev)
|
||||
goto out;
|
||||
|
||||
if (rt->rt6i_flags & (RTF_REJECT|RTF_ANYCAST))
|
||||
|
|
|
|||
|
|
@ -96,7 +96,8 @@ static bool rt_mt6(const struct sk_buff *skb, struct xt_action_param *par)
|
|||
unsigned int i = 0;
|
||||
|
||||
for (temp = 0;
|
||||
temp < (unsigned int)((hdrlen - 8) / 16);
|
||||
temp < (unsigned int)((hdrlen - 8) / 16) &&
|
||||
i < rtinfo->addrnr;
|
||||
temp++) {
|
||||
ap = skb_header_pointer(skb,
|
||||
ptr
|
||||
|
|
@ -112,8 +113,6 @@ static bool rt_mt6(const struct sk_buff *skb, struct xt_action_param *par)
|
|||
|
||||
if (ipv6_addr_equal(ap, &rtinfo->addrs[i]))
|
||||
i++;
|
||||
if (i == rtinfo->addrnr)
|
||||
break;
|
||||
}
|
||||
if (i == rtinfo->addrnr)
|
||||
return ret;
|
||||
|
|
@ -162,6 +161,12 @@ static int rt_mt6_check(const struct xt_mtchk_param *par)
|
|||
pr_info_ratelimited("too many addresses specified\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if ((rtinfo->flags & IP6T_RT_FST_MASK) && !rtinfo->addrnr) {
|
||||
pr_info_ratelimited("address list match requested but addrnr is 0\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if ((rtinfo->flags & (IP6T_RT_RES | IP6T_RT_FST_MASK)) &&
|
||||
(!(rtinfo->flags & IP6T_RT_TYP) ||
|
||||
(rtinfo->rt_type != 0) ||
|
||||
|
|
|
|||
|
|
@ -1960,6 +1960,12 @@ ip_vs_in_icmp(struct netns_ipvs *ipvs, struct sk_buff *skb, int *related,
|
|||
/* Ensure the IP header is present in headroom */
|
||||
if (!pskb_may_pull(skb, hlen_orig))
|
||||
goto ignore_tunnel;
|
||||
skb_set_transport_header(skb, hlen_orig);
|
||||
/* Before now we may used ihl from skb frag, revalidate it after
|
||||
* copying it into skb head to prevent out-of-bounds access
|
||||
*/
|
||||
if (ip_hdr(skb)->ihl * 4 != hlen_orig)
|
||||
goto ignore_tunnel;
|
||||
IP_VS_DBG(12, "Sending ICMP for %pI4->%pI4: t=%u, c=%u, i=%u\n",
|
||||
&ip_hdr(skb)->saddr, &ip_hdr(skb)->daddr,
|
||||
type, code, ntohl(info));
|
||||
|
|
|
|||
|
|
@ -3392,7 +3392,8 @@ static bool expect_iter_name(struct nf_conntrack_expect *exp, void *data)
|
|||
struct nf_conntrack_helper *helper;
|
||||
const char *name = data;
|
||||
|
||||
helper = rcu_dereference(exp->helper);
|
||||
helper = rcu_dereference_protected(exp->helper,
|
||||
lockdep_is_held(&nf_conntrack_expect_lock));
|
||||
if (!helper)
|
||||
return false;
|
||||
|
||||
|
|
|
|||
|
|
@ -995,7 +995,6 @@ static void flow_offload_work_del(struct flow_offload_work *offload)
|
|||
flow_offload_tuple_del(offload, FLOW_OFFLOAD_DIR_ORIGINAL);
|
||||
if (test_bit(NF_FLOW_HW_BIDIRECTIONAL, &offload->flow->flags))
|
||||
flow_offload_tuple_del(offload, FLOW_OFFLOAD_DIR_REPLY);
|
||||
set_bit(NF_FLOW_HW_DEAD, &offload->flow->flags);
|
||||
}
|
||||
|
||||
static void flow_offload_tuple_stats(struct flow_offload_work *offload,
|
||||
|
|
@ -1059,6 +1058,12 @@ static void flow_offload_work_handler(struct work_struct *work)
|
|||
}
|
||||
|
||||
clear_bit(NF_FLOW_HW_PENDING, &offload->flow->flags);
|
||||
if (offload->cmd == FLOW_CLS_DESTROY) {
|
||||
/* Publish after the worker's last flow access. */
|
||||
smp_mb__before_atomic();
|
||||
set_bit(NF_FLOW_HW_DEAD, &offload->flow->flags);
|
||||
}
|
||||
|
||||
kfree(offload);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -6995,11 +6995,14 @@ static int nft_setelem_catchall_insert(const struct net *net,
|
|||
{
|
||||
struct nft_set_elem_catchall *catchall;
|
||||
u8 genmask = nft_genmask_next(net);
|
||||
u64 tstamp = nft_net_tstamp(net);
|
||||
struct nft_set_ext *ext;
|
||||
|
||||
list_for_each_entry(catchall, &set->catchall_list, list) {
|
||||
ext = nft_set_elem_ext(set, catchall->elem);
|
||||
if (nft_set_elem_active(ext, genmask)) {
|
||||
if (nft_set_elem_active(ext, genmask) &&
|
||||
!__nft_set_elem_expired(ext, tstamp) &&
|
||||
!nft_set_elem_is_dead(ext)) {
|
||||
*priv = catchall->elem;
|
||||
return -EEXIST;
|
||||
}
|
||||
|
|
@ -7092,11 +7095,14 @@ static int nft_setelem_catchall_deactivate(const struct net *net,
|
|||
struct nft_set_elem *elem)
|
||||
{
|
||||
struct nft_set_elem_catchall *catchall;
|
||||
u64 tstamp = nft_net_tstamp(net);
|
||||
struct nft_set_ext *ext;
|
||||
|
||||
list_for_each_entry(catchall, &set->catchall_list, list) {
|
||||
ext = nft_set_elem_ext(set, catchall->elem);
|
||||
if (!nft_is_active_next(net, ext))
|
||||
if (!nft_is_active_next(net, ext) ||
|
||||
__nft_set_elem_expired(ext, tstamp) ||
|
||||
nft_set_elem_is_dead(ext))
|
||||
continue;
|
||||
|
||||
kfree(elem->priv);
|
||||
|
|
|
|||
|
|
@ -1593,6 +1593,7 @@ nfqnl_rcv_nl_event(struct notifier_block *this,
|
|||
if (event == NETLINK_URELEASE && n->protocol == NETLINK_NETFILTER) {
|
||||
int i;
|
||||
|
||||
nfnl_lock(NFNL_SUBSYS_QUEUE);
|
||||
/* destroy all instances for this portid */
|
||||
spin_lock(&q->instances_lock);
|
||||
for (i = 0; i < INSTANCE_BUCKETS; i++) {
|
||||
|
|
@ -1606,6 +1607,7 @@ nfqnl_rcv_nl_event(struct notifier_block *this,
|
|||
}
|
||||
}
|
||||
spin_unlock(&q->instances_lock);
|
||||
nfnl_unlock(NFNL_SUBSYS_QUEUE);
|
||||
}
|
||||
return NOTIFY_DONE;
|
||||
}
|
||||
|
|
@ -1925,9 +1927,9 @@ static int nfqnl_recv_config(struct sk_buff *skb, const struct nfnl_info *info,
|
|||
|
||||
/* Lookup queue under RCU. After peer_portid check (or for new queue
|
||||
* in BIND case), the queue is owned by the socket sending this message.
|
||||
* A socket cannot simultaneously send a message and close, so while
|
||||
* processing this CONFIG message, nfqnl_rcv_nl_event() (triggered by
|
||||
* socket close) cannot destroy this queue. Safe to use without RCU.
|
||||
* nfqnl_rcv_nl_event() will block on the nfnl subsys mutex that is
|
||||
* held by the caller, so the queue cannot be destroyed in parallel,
|
||||
* even after we drop the RCU read lock.
|
||||
*/
|
||||
rcu_read_lock();
|
||||
queue = instance_lookup(q, queue_num);
|
||||
|
|
|
|||
|
|
@ -118,7 +118,8 @@ static void nft_synproxy_do_eval(const struct nft_synproxy *priv,
|
|||
return;
|
||||
}
|
||||
|
||||
if (nf_ip_checksum(skb, nft_hook(pkt), thoff, IPPROTO_TCP)) {
|
||||
if (nf_checksum(skb, nft_hook(pkt), thoff, IPPROTO_TCP,
|
||||
nft_pf(pkt))) {
|
||||
regs->verdict.code = NF_DROP;
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user