Re: [PATCH 6.12 189/220] ipv4: start using dst_dev_rcu()

Miguel Gazquez <[email protected]>
Newsgroups dev.linux.lists.patches,org.kernel.vger.stable
Message-ID <[email protected]>
Hi,

I think I made a mistake on my backport :

Le 20/08/2026 à 16:56, Greg Kroah-Hartman a écrit :
> 6.12-stable review patch.  If anyone has any objections, please let me know.
> 
> ------------------
> 
> From: Eric Dumazet <[email protected]>
> 
> [ Upstream commit 6ad8de3cefdb6ffa6708b21c567df0dbf82c43a8 ]
> 
> Change icmpv4_xrlim_allow(), ip_defrag() to prevent possible UAF.
> 
> Change ipmr_prepare_xmit(), ipmr_queue_fwd_xmit(), ip_mr_output(),
> ipv4_neigh_lookup() to use lockdep enabled dst_dev_rcu().
> 
> Fixes: 4a6ce2b6f2ec ("net: introduce a new function dst_dev_put()")
> Signed-off-by: Eric Dumazet <[email protected]>
> Reviewed-by: David Ahern <[email protected]>
> Link: https://patch.msgid.link/[email protected]
> Signed-off-by: Jakub Kicinski <[email protected]>
> [ minor modifications to fix conflict ]
> Signed-off-by: Miguel Gazquez <[email protected]>
> Signed-off-by: Greg Kroah-Hartman <[email protected]>
> ---
>   net/ipv4/icmp.c        |    6 +++---
>   net/ipv4/ip_fragment.c |    6 ++++--
>   net/ipv4/ipmr.c        |    4 ++--
>   net/ipv4/route.c       |    4 ++--
>   4 files changed, 11 insertions(+), 9 deletions(-)
> 
> --- a/net/ipv4/icmp.c
> +++ b/net/ipv4/icmp.c
> @@ -320,17 +320,17 @@ static bool icmpv4_xrlim_allow(struct ne
>   		return true;
>   
>   	/* No rate limit on loopback */
> -	dev = dst_dev(dst);
> +	rcu_read_lock();
> +	dev = dst_dev_rcu(dst);
>   	if (dev && (dev->flags & IFF_LOOPBACK))
>   		goto out;
>   
> -	rcu_read_lock();
>   	peer = inet_getpeer_v4(net->ipv4.peers, fl4->daddr,
>   			       l3mdev_master_ifindex_rcu(dev));
>   	rc = inet_peer_xrlim_allow(peer,
>   				   READ_ONCE(net->ipv4.sysctl_icmp_ratelimit));
> -	rcu_read_unlock();
>   out:
> +	rcu_read_unlock();
>   	if (!rc)
>   		__ICMP_INC_STATS(net, ICMP_MIB_RATELIMITHOST);
>   	else
> --- a/net/ipv4/ip_fragment.c
> +++ b/net/ipv4/ip_fragment.c
> @@ -483,13 +483,15 @@ out_fail:
>   /* Process an incoming IP datagram fragment. */
>   int ip_defrag(struct net *net, struct sk_buff *skb, u32 user)
>   {
> -	struct net_device *dev = skb->dev ? : skb_dst_dev(skb);
> -	int vif = l3mdev_master_ifindex_rcu(dev);
> +	struct net_device *dev;
>   	struct ipq *qp;
> +	int vif;
>   
>   	__IP_INC_STATS(net, IPSTATS_MIB_REASMREQDS);
>   
>   	/* Lookup (or create) queue header */
> +	dev = skb->dev ? : skb_dst_dev_rcu(skb);
> +	vif = l3mdev_master_ifindex_rcu(dev);

Here, the upstream version has a `rcu_read_lock();` that I think should 
be added. I will send an updated version.

>   	qp = ip_find(net, ip_hdr(skb), user, vif);
>   	if (qp) {
>   		int ret;
> --- a/net/ipv4/ipmr.c
> +++ b/net/ipv4/ipmr.c
> @@ -1906,7 +1906,7 @@ static void ipmr_queue_xmit(struct net *
>   		goto out_free;
>   	}
>   
> -	encap += LL_RESERVED_SPACE(dev) + rt->dst.header_len;
> +	encap += LL_RESERVED_SPACE(dst_dev_rcu(&rt->dst)) + rt->dst.header_len;
>   
>   	if (skb_cow(skb, encap)) {
>   		ip_rt_put(rt);
> @@ -1943,7 +1943,7 @@ static void ipmr_queue_xmit(struct net *
>   	 * result in receiving multiple packets.
>   	 */
>   	NF_HOOK(NFPROTO_IPV4, NF_INET_FORWARD,
> -		net, NULL, skb, skb->dev, dev,
> +		net, NULL, skb, skb->dev, dst_dev_rcu(&rt->dst),
>   		ipmr_forward_finish);
>   	return;
>   
> --- a/net/ipv4/route.c
> +++ b/net/ipv4/route.c
> @@ -413,11 +413,11 @@ static struct neighbour *ipv4_neigh_look
>   					   const void *daddr)
>   {
>   	const struct rtable *rt = container_of(dst, struct rtable, dst);
> -	struct net_device *dev = dst_dev(dst);
> +	struct net_device *dev;
>   	struct neighbour *n;
>   
>   	rcu_read_lock();
> -
> +	dev = dst_dev_rcu(dst);
>   	if (likely(rt->rt_gw_family == AF_INET)) {
>   		n = ip_neigh_gw4(dev, rt->rt_gw4);
>   	} else if (rt->rt_gw_family == AF_INET6) {
> 
> 

-- 
Miguel Gazquez, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.