From nobody Mon Sep 28 12:34:51 2026 Received: from smtpout-02.galae.net (smtpout-02.galae.net [185.246.84.56]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 69666322A1F; Fri, 21 Aug 2026 13:34:14 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.246.84.56 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787319256; cv=none; b=esbRvJJMFuwUmdRW3mfkplUBBH0x8/5sqKEuivVkpB0XKH1gDoCXc4sYRmPEf3dFAINsbsoof9xgfoCEWTrAspfScosQEsHCMnTeT3sfoAwmTDufrcHEObNSXO154zxQCeYUBs1nV6iNohfRSdjRZe7dhfFvDGzN2NMU0lHHrpk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787319256; c=relaxed/simple; bh=eJwkd6Wf/JlgnzBtFXQ9jU2Z76oo3Li1j9yTtVz69ss=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=CyfaKD4hfQgIuvZaIJAlx2hlit1vrXKExd1t+ovQ93EF7y8ax4AV4iJMFFRjBKBEtkbITWNk24L3iYAvzg6U866oz6ICxV5vKri5HwWSy1+7OnEE2UyfMz1mY8WBZziYCTTKEY2B/oQqmhqEEpOV7SfkKbCs0RsppOj3dl9dHrk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com; spf=pass smtp.mailfrom=bootlin.com; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b=wUrxfGQD; arc=none smtp.client-ip=185.246.84.56 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=bootlin.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b="wUrxfGQD" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-02.galae.net (Postfix) with ESMTPS id BA6981A1761; Fri, 21 Aug 2026 13:34:12 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id 8DD95604AA; Fri, 21 Aug 2026 13:34:12 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id B4AE311C761FC; Fri, 21 Aug 2026 15:34:05 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1787319247; h=from:subject:date:message-id:to:cc:mime-version:content-type: content-transfer-encoding:in-reply-to:references; bh=piDDRH0HRHEj8bTwRtfQXJHGVjbPNgdGz7J6LRzfb4Y=; b=wUrxfGQD1/35gRgpuFyt+59v+KqXPqDDuLbNESls96PEoqkBlQx/2KGZry8hhTmMHiejCk VBLUn8PKAaJoLYIcieOWgYPOn5Px4KIZ9vYss3F1aa6HayvDw7m9/KadpEfTXBBR4qiymN /r2Ue457oLA/0qD65sMISEBGorPevlKHJmTxEYeucmpTpyYAwJ7RDxOcC7e8fLCzyaixdm x7Us6p2qSvuxG9xh31pM8tz1YeiGiGehzPUXxRbraO+1EnSje9F2sgejz8g4ASLxEcW0uZ YOOqV9edQ1/1puwSpUPEm9KPbH1C9DbLc54kZPRi2K6H/XCC10mud3SlF9qeMw== From: "Miguel Gazquez (Schneider Electric)" Date: Fri, 21 Aug 2026 15:33:35 +0200 Subject: [PATCH v6.1.y 1/4] net: dst: add four helpers to annotate data-races around dst->dev Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260821-cve-2025-40074-6-1-v1-1-cad5cf499b76@bootlin.com> References: <20260821-cve-2025-40074-6-1-v1-0-cad5cf499b76@bootlin.com> In-Reply-To: <20260821-cve-2025-40074-6-1-v1-0-cad5cf499b76@bootlin.com> To: stable@vger.kernel.org, "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Wei Wang , Martin KaFai Lau , Hideaki YOSHIFUJI , David Ahern , Steffen Klassert , Herbert Xu , Pablo Neira Ayuso , Jozsef Kadlecsik , Florian Westphal Cc: Thomas Petazzoni , netdev@vger.kernel.org, linux-kernel@vger.kernel.org, netfilter-devel@vger.kernel.org, coreteam@netfilter.org, Miguel Gazquez , Kuniyuki Iwashima X-Mailer: b4 0.15.2 X-Developer-Signature: v=1; a=ed25519-sha256; t=1787319234; l=4582; i=miguel.gazquez@bootlin.com; s=20250708; h=from:subject:message-id; bh=H7jKVfoP1pzgjHPWNvNmP1bd0X3iN9gcZ7Dv1H35JkY=; b=WAQs98iyWBJgMny/8jeK4xkQ2VmHDpLxsrIbneVrNijKHwKfmqJJeYqK7/9CJIiYaIRbQslpV GLnJ9Knen2MBTSA7g1HwdW1ZHRPFy/yoFfaA/CGTJyoHnjIZ7qtz8Tc X-Developer-Key: i=miguel.gazquez@bootlin.com; a=ed25519; pk=k/2KI9jkmayaF0ghZ8QYUH9Wm/kFHDhl8QoZ0RHbr4w= X-Last-TLS-Session-Version: TLSv1.3 From: Eric Dumazet [ Upstream commit 88fe14253e181878c2ddb51a298ae8c468a63010 ] dst->dev is read locklessly in many contexts, and written in dst_dev_put(). Fixing all the races is going to need many changes. We probably will have to add full RCU protection. Add three helpers to ease this painful process. static inline struct net_device *dst_dev(const struct dst_entry *dst) { return READ_ONCE(dst->dev); } static inline struct net_device *skb_dst_dev(const struct sk_buff *skb) { return dst_dev(skb_dst(skb)); } static inline struct net *skb_dst_dev_net(const struct sk_buff *skb) { return dev_net(skb_dst_dev(skb)); } static inline struct net *skb_dst_dev_net_rcu(const struct sk_buff *skb) { return dev_net_rcu(skb_dst_dev(skb)); } Fixes: 4a6ce2b6f2ec ("net: introduce a new function dst_dev_put()") Signed-off-by: Eric Dumazet Reviewed-by: Kuniyuki Iwashima Link: https://patch.msgid.link/20250630121934.3399505-7-edumazet@google.com Signed-off-by: Jakub Kicinski [ minor modifications to fix conflict ] Signed-off-by: Miguel Gazquez --- include/net/dst.h | 20 ++++++++++++++++++++ net/core/dst.c | 4 ++-- net/core/sock.c | 6 +++--- 3 files changed, 25 insertions(+), 5 deletions(-) diff --git a/include/net/dst.h b/include/net/dst.h index 20a76e532afb..7c0cf856154d 100644 --- a/include/net/dst.h +++ b/include/net/dst.h @@ -555,6 +555,11 @@ static inline void skb_dst_update_pmtu_no_confirm(stru= ct sk_buff *skb, u32 mtu) dst->ops->update_pmtu(dst, NULL, skb, mtu, false); } =20 +static inline struct net_device *dst_dev(const struct dst_entry *dst) +{ + return READ_ONCE(dst->dev); +} + static inline struct net_device *dst_dev_rcu(const struct dst_entry *dst) { /* In the future, use rcu_dereference(dst->dev) */ @@ -562,11 +567,26 @@ static inline struct net_device *dst_dev_rcu(const st= ruct dst_entry *dst) return READ_ONCE(dst->dev); } =20 +static inline struct net_device *skb_dst_dev(const struct sk_buff *skb) +{ + return dst_dev(skb_dst(skb)); +} + static inline struct net_device *skb_dst_dev_rcu(const struct sk_buff *skb) { return dst_dev_rcu(skb_dst(skb)); } =20 +static inline struct net *skb_dst_dev_net(const struct sk_buff *skb) +{ + return dev_net(skb_dst_dev(skb)); +} + +static inline struct net *skb_dst_dev_net_rcu(const struct sk_buff *skb) +{ + return dev_net_rcu(skb_dst_dev(skb)); +} + struct dst_entry *dst_blackhole_check(struct dst_entry *dst, u32 cookie); void dst_blackhole_update_pmtu(struct dst_entry *dst, struct sock *sk, struct sk_buff *skb, u32 mtu, bool confirm_neigh); diff --git a/net/core/dst.c b/net/core/dst.c index 8db87258d145..24a1cc3d2a08 100644 --- a/net/core/dst.c +++ b/net/core/dst.c @@ -151,7 +151,7 @@ void dst_dev_put(struct dst_entry *dst) dst->ops->ifdown(dst, dev, true); dst->input =3D dst_discard; dst->output =3D dst_discard_out; - dst->dev =3D blackhole_netdev; + WRITE_ONCE(dst->dev, blackhole_netdev); netdev_ref_replace(dev, blackhole_netdev, &dst->dev_tracker, GFP_ATOMIC); } @@ -272,7 +272,7 @@ unsigned int dst_blackhole_mtu(const struct dst_entry *= dst) { unsigned int mtu =3D dst_metric_raw(dst, RTAX_MTU); =20 - return mtu ? : dst->dev->mtu; + return mtu ? : dst_dev(dst)->mtu; } EXPORT_SYMBOL_GPL(dst_blackhole_mtu); =20 diff --git a/net/core/sock.c b/net/core/sock.c index 2a701e0b052b..64f9d77bfaec 100644 --- a/net/core/sock.c +++ b/net/core/sock.c @@ -2397,7 +2397,7 @@ void sk_setup_caps(struct sock *sk, struct dst_entry = *dst) { u32 max_segs =3D 1; =20 - sk->sk_route_caps =3D dst->dev->features; + sk->sk_route_caps =3D dst_dev(dst)->features; if (sk_is_tcp(sk)) sk->sk_route_caps |=3D NETIF_F_GSO; if (sk->sk_route_caps & NETIF_F_GSO) @@ -2410,11 +2410,11 @@ void sk_setup_caps(struct sock *sk, struct dst_entr= y *dst) } else { sk->sk_route_caps |=3D NETIF_F_SG | NETIF_F_HW_CSUM; /* pairs with the WRITE_ONCE() in netif_set_gso_max_size() */ - sk->sk_gso_max_size =3D READ_ONCE(dst->dev->gso_max_size); + sk->sk_gso_max_size =3D READ_ONCE(dst_dev(dst)->gso_max_size); sk_trim_gso_size(sk); sk->sk_gso_max_size -=3D (MAX_TCP_HEADER + 1); /* pairs with the WRITE_ONCE() in netif_set_gso_max_segs() */ - max_segs =3D max_t(u32, READ_ONCE(dst->dev->gso_max_segs), 1); + max_segs =3D max_t(u32, READ_ONCE(dst_dev(dst)->gso_max_segs), 1); } } sk->sk_gso_max_segs =3D max_segs; --=20 2.55.0 From nobody Mon Sep 28 12:34:51 2026 Received: from smtpout-02.galae.net (smtpout-02.galae.net [185.246.84.56]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 6C35B322A1F; Fri, 21 Aug 2026 13:34:20 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.246.84.56 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787319262; cv=none; b=oSdfTUb35FsFT8VrkMSHSfXUp0j6Nzo0eeVaQrixIDKxnTECscrmFkv1G1Qb/IbSwgbdp+JLSuBPTx5L3FtFR87AHuEvDw9SLTqHihI+4J0R38sfsTm4cNSBRk/443AN3QyhI5aC+tiNab1SRL7myY0CIHD4Tjy404hVd9qmfEI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787319262; c=relaxed/simple; bh=9RmWmG6TCAK3Qc3e5Fz0iYlxuYN74qkU8jzdClOZC7U=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=Ws7QdgAKi/iYKXul8zU3pX82Jokk84NjjwA9N8FsjLaaLeVCb/6DbrxrSQeGFugUvV4+V63ZqNIlyMB6xHVc6XSoF0Vj0U59eX2PDFE3FdPZ0HSf8v0oBnQ4F8k3GDtPfROASUqELSEAyLiW4JagsWLVGLaS9A4Gjq/QhXUaztw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com; spf=pass smtp.mailfrom=bootlin.com; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b=aJbiLYJj; arc=none smtp.client-ip=185.246.84.56 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=bootlin.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b="aJbiLYJj" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-02.galae.net (Postfix) with ESMTPS id CB46E1A1761; Fri, 21 Aug 2026 13:34:18 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id 9D8EC604AA; Fri, 21 Aug 2026 13:34:18 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id DBE9311C7714B; Fri, 21 Aug 2026 15:34:11 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1787319253; h=from:subject:date:message-id:to:cc:mime-version:content-type: content-transfer-encoding:in-reply-to:references; bh=INNS0HrYZ668pkp9FS3gsEOdefJAhBkILcgEHBCAIrA=; b=aJbiLYJjc4mMJUmYheb67z+jQuQ3kjLyW6aXPETak/ev8jv6KVvWSGG7YRHu6vKwqibqYU KWCWIegAGFh2IcQyuLH3syeaDO4VJQwJpt5TU9yEQTtM9gwwswLAu5dum2AeJ/DKHsOT/r iBX0FG7iin6cwQklx6Y6CGbfArfX0TKO7X+3FrQ8SPrbW9Boq6j+yEqKHcGeIMBKS6zmYW fFiLdOsnsQb8JkOE0Krts66JQOpZQjJceAAhKG/4P3OFYhJENizUZ6N+Hvw4dTm66vK7nJ QnkrqLZnWc6gxfDSVUIFgd/Kgdo273CC+GL6KZD3QB6TqJfVu+2TeKsAeconuA== From: "Miguel Gazquez (Schneider Electric)" Date: Fri, 21 Aug 2026 15:33:36 +0200 Subject: [PATCH v6.1.y 2/4] ipv4: adopt dst_dev, skb_dst_dev and skb_dst_dev_net[_rcu] Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260821-cve-2025-40074-6-1-v1-2-cad5cf499b76@bootlin.com> References: <20260821-cve-2025-40074-6-1-v1-0-cad5cf499b76@bootlin.com> In-Reply-To: <20260821-cve-2025-40074-6-1-v1-0-cad5cf499b76@bootlin.com> To: stable@vger.kernel.org, "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Wei Wang , Martin KaFai Lau , Hideaki YOSHIFUJI , David Ahern , Steffen Klassert , Herbert Xu , Pablo Neira Ayuso , Jozsef Kadlecsik , Florian Westphal Cc: Thomas Petazzoni , netdev@vger.kernel.org, linux-kernel@vger.kernel.org, netfilter-devel@vger.kernel.org, coreteam@netfilter.org, Miguel Gazquez , Kuniyuki Iwashima X-Mailer: b4 0.15.2 X-Developer-Signature: v=1; a=ed25519-sha256; t=1787319234; l=14405; i=miguel.gazquez@bootlin.com; s=20250708; h=from:subject:message-id; bh=A8sC6YP7637wm/fpcRHTREvRbqLDf8K4cyF2KRvHF9Y=; b=tvr3EUE0AkBLZXJmHT6Vl7WSEREPcVxiH9KcQWa69+EpyS8NsYs61YN/cBUZbPR3vqLqQF20L 8R6Zcr5kiUTBhZhCNaQFnnBRCjtlMIvqSuLpF+vBnghk7LSTENVSKO8 X-Developer-Key: i=miguel.gazquez@bootlin.com; a=ed25519; pk=k/2KI9jkmayaF0ghZ8QYUH9Wm/kFHDhl8QoZ0RHbr4w= X-Last-TLS-Session-Version: TLSv1.3 From: Eric Dumazet [ Upstream commit a74fc62eec155ca5a6da8ff3856f3dc87fe24558 ] Use the new helpers as a first step to deal with potential dst->dev races. Signed-off-by: Eric Dumazet Reviewed-by: Kuniyuki Iwashima Link: https://patch.msgid.link/20250630121934.3399505-8-edumazet@google.com Signed-off-by: Jakub Kicinski [ minor modifications to fix conflict ] Signed-off-by: Miguel Gazquez --- include/net/inet_hashtables.h | 2 +- include/net/ip.h | 11 ++++++----- include/net/route.h | 2 +- net/ipv4/icmp.c | 24 +++++++++++++----------- net/ipv4/igmp.c | 2 +- net/ipv4/ip_fragment.c | 2 +- net/ipv4/ip_output.c | 4 ++-- net/ipv4/ip_vti.c | 4 ++-- net/ipv4/netfilter.c | 4 ++-- net/ipv4/route.c | 8 ++++---- net/ipv4/tcp_fastopen.c | 4 +++- net/ipv4/tcp_ipv4.c | 3 ++- net/ipv4/tcp_metrics.c | 8 ++++---- net/ipv4/xfrm4_output.c | 2 +- 14 files changed, 43 insertions(+), 37 deletions(-) diff --git a/include/net/inet_hashtables.h b/include/net/inet_hashtables.h index ce58cf10ecb4..ac85405308c9 100644 --- a/include/net/inet_hashtables.h +++ b/include/net/inet_hashtables.h @@ -470,7 +470,7 @@ static inline struct sock *__inet_lookup_skb(struct ine= t_hashinfo *hashinfo, if (sk) return sk; =20 - return __inet_lookup(dev_net(skb_dst(skb)->dev), hashinfo, skb, + return __inet_lookup(skb_dst_dev_net(skb), hashinfo, skb, doff, iph->saddr, sport, iph->daddr, dport, inet_iif(skb), sdif, refcounted); diff --git a/include/net/ip.h b/include/net/ip.h index 1b0722e9b55e..fe0ceb3fd6e6 100644 --- a/include/net/ip.h +++ b/include/net/ip.h @@ -452,7 +452,7 @@ static inline unsigned int ip_dst_mtu_maybe_forward(con= st struct dst_entry *dst, bool forwarding) { const struct rtable *rt =3D container_of(dst, struct rtable, dst); - struct net *net =3D dev_net(dst->dev); + struct net *net =3D dev_net(dst_dev(dst)); unsigned int mtu; =20 if (READ_ONCE(net->ipv4.sysctl_ip_fwd_use_pmtu) || @@ -468,7 +468,7 @@ static inline unsigned int ip_dst_mtu_maybe_forward(con= st struct dst_entry *dst, if (mtu) goto out; =20 - mtu =3D READ_ONCE(dst->dev->mtu); + mtu =3D READ_ONCE(dst_dev(dst)->mtu); =20 if (unlikely(ip_mtu_locked(dst))) { if (rt->rt_uses_gateway && mtu > 576) @@ -484,16 +484,17 @@ static inline unsigned int ip_dst_mtu_maybe_forward(c= onst struct dst_entry *dst, static inline unsigned int ip_skb_dst_mtu(struct sock *sk, const struct sk_buff *skb) { + const struct dst_entry *dst =3D skb_dst(skb); unsigned int mtu; =20 if (!sk || !sk_fullsock(sk) || ip_sk_use_pmtu(sk)) { bool forwarding =3D IPCB(skb)->flags & IPSKB_FORWARDED; =20 - return ip_dst_mtu_maybe_forward(skb_dst(skb), forwarding); + return ip_dst_mtu_maybe_forward(dst, forwarding); } =20 - mtu =3D min(READ_ONCE(skb_dst(skb)->dev->mtu), IP_MAX_MTU); - return mtu - lwtunnel_headroom(skb_dst(skb)->lwtstate, mtu); + mtu =3D min(READ_ONCE(dst_dev(dst)->mtu), IP_MAX_MTU); + return mtu - lwtunnel_headroom(dst->lwtstate, mtu); } =20 struct dst_metrics *ip_fib_metrics_init(struct net *net, struct nlattr *fc= _mx, diff --git a/include/net/route.h b/include/net/route.h index 4fa45dda2bb3..ce608f883040 100644 --- a/include/net/route.h +++ b/include/net/route.h @@ -362,7 +362,7 @@ static inline int ip4_dst_hoplimit(const struct dst_ent= ry *dst) const struct net *net; =20 rcu_read_lock(); - net =3D dev_net_rcu(dst->dev); + net =3D dev_net_rcu(dst_dev(dst)); hoplimit =3D READ_ONCE(net->ipv4.sysctl_ip_default_ttl); rcu_read_unlock(); } diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c index e8c59c2051c2..7763a98ddc96 100644 --- a/net/ipv4/icmp.c +++ b/net/ipv4/icmp.c @@ -313,18 +313,20 @@ static bool icmpv4_xrlim_allow(struct net *net, struc= t rtable *rt, { struct dst_entry *dst =3D &rt->dst; struct inet_peer *peer; + struct net_device *dev; bool rc =3D true; =20 if (!apply_ratelimit) return true; =20 /* No rate limit on loopback */ - if (dst->dev && (dst->dev->flags&IFF_LOOPBACK)) + dev =3D dst_dev(dst); + if (dev && (dev->flags & IFF_LOOPBACK)) goto out; =20 rcu_read_lock(); peer =3D inet_getpeer_v4(net->ipv4.peers, fl4->daddr, - l3mdev_master_ifindex_rcu(dst->dev)); + l3mdev_master_ifindex_rcu(dev)); rc =3D inet_peer_xrlim_allow(peer, READ_ONCE(net->ipv4.sysctl_icmp_ratelimit)); rcu_read_unlock(); @@ -472,13 +474,13 @@ static void icmp_reply(struct icmp_bxm *icmp_param, s= truct sk_buff *skb) */ static struct net_device *icmp_get_route_lookup_dev(struct sk_buff *skb) { - struct net_device *route_lookup_dev =3D NULL; + struct net_device *dev =3D skb->dev; + const struct dst_entry *dst; =20 - if (skb->dev) - route_lookup_dev =3D skb->dev; - else if (skb_dst(skb)) - route_lookup_dev =3D skb_dst(skb)->dev; - return route_lookup_dev; + if (dev) + return dev; + dst =3D skb_dst(skb); + return dst ? dst_dev(dst) : NULL; } =20 static struct rtable *icmp_route_lookup(struct net *net, struct flowi4 *fl= 4, @@ -905,7 +907,7 @@ static enum skb_drop_reason icmp_unreach(struct sk_buff= *skb) struct net *net; u32 info =3D 0; =20 - net =3D dev_net_rcu(skb_dst(skb)->dev); + net =3D skb_dst_dev_net_rcu(skb); =20 /* * Incomplete header ? @@ -1048,7 +1050,7 @@ static enum skb_drop_reason icmp_echo(struct sk_buff = *skb) struct icmp_bxm icmp_param; struct net *net; =20 - net =3D dev_net_rcu(skb_dst(skb)->dev); + net =3D skb_dst_dev_net_rcu(skb); /* should there be an ICMP stat for ignored echos? */ if (READ_ONCE(net->ipv4.sysctl_icmp_echo_ignore_all)) return SKB_NOT_DROPPED_YET; @@ -1225,7 +1227,7 @@ static enum skb_drop_reason icmp_timestamp(struct sk_= buff *skb) return SKB_NOT_DROPPED_YET; =20 out_err: - __ICMP_INC_STATS(dev_net_rcu(skb_dst(skb)->dev), ICMP_MIB_INERRORS); + __ICMP_INC_STATS(skb_dst_dev_net_rcu(skb), ICMP_MIB_INERRORS); return SKB_DROP_REASON_PKT_TOO_SMALL; } =20 diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c index fd12b256e05d..bd1726b8ae88 100644 --- a/net/ipv4/igmp.c +++ b/net/ipv4/igmp.c @@ -424,7 +424,7 @@ static int igmpv3_sendpack(struct sk_buff *skb) =20 pig->csum =3D ip_compute_csum(igmp_hdr(skb), igmplen); =20 - return ip_local_out(dev_net(skb_dst(skb)->dev), skb->sk, skb); + return ip_local_out(skb_dst_dev_net(skb), skb->sk, skb); } =20 static int grec_size(struct ip_mc_list *pmc, int type, int gdel, int sdel) diff --git a/net/ipv4/ip_fragment.c b/net/ipv4/ip_fragment.c index 0ed999fdca2d..a70ede523297 100644 --- a/net/ipv4/ip_fragment.c +++ b/net/ipv4/ip_fragment.c @@ -481,7 +481,7 @@ static int ip_frag_reasm(struct ipq *qp, struct sk_buff= *skb, /* Process an incoming IP datagram fragment. */ int ip_defrag(struct net *net, struct sk_buff *skb, u32 user) { - struct net_device *dev =3D skb->dev ? : skb_dst(skb)->dev; + struct net_device *dev =3D skb->dev ? : skb_dst_dev(skb); int vif =3D l3mdev_master_ifindex_rcu(dev); struct ipq *qp; =20 diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c index 778214137e4a..5e1c368132de 100644 --- a/net/ipv4/ip_output.c +++ b/net/ipv4/ip_output.c @@ -113,7 +113,7 @@ int __ip_local_out(struct net *net, struct sock *sk, st= ruct sk_buff *skb) skb->protocol =3D htons(ETH_P_IP); =20 return nf_hook(NFPROTO_IPV4, NF_INET_LOCAL_OUT, - net, sk, skb, NULL, skb_dst(skb)->dev, + net, sk, skb, NULL, skb_dst_dev(skb), dst_output); } =20 @@ -195,7 +195,7 @@ static int ip_finish_output2(struct net *net, struct so= ck *sk, struct sk_buff *s { struct dst_entry *dst =3D skb_dst(skb); struct rtable *rt =3D (struct rtable *)dst; - struct net_device *dev =3D dst->dev; + struct net_device *dev =3D dst_dev(dst); unsigned int hh_len =3D LL_RESERVED_SPACE(dev); struct neighbour *neigh; bool is_v6gw =3D false; diff --git a/net/ipv4/ip_vti.c b/net/ipv4/ip_vti.c index 7daf01af6295..2e07592d8b96 100644 --- a/net/ipv4/ip_vti.c +++ b/net/ipv4/ip_vti.c @@ -226,7 +226,7 @@ static netdev_tx_t vti_xmit(struct sk_buff *skb, struct= net_device *dev, goto tx_error_icmp; } =20 - tdev =3D dst->dev; + tdev =3D dst_dev(dst); =20 if (tdev =3D=3D dev) { dst_release(dst); @@ -256,7 +256,7 @@ static netdev_tx_t vti_xmit(struct sk_buff *skb, struct= net_device *dev, xmit: skb_scrub_packet(skb, !net_eq(tunnel->net, dev_net(dev))); skb_dst_set(skb, dst); - skb->dev =3D skb_dst(skb)->dev; + skb->dev =3D skb_dst_dev(skb); =20 err =3D dst_output(tunnel->net, skb->sk, skb); if (net_xmit_eval(err) =3D=3D 0) diff --git a/net/ipv4/netfilter.c b/net/ipv4/netfilter.c index bd135165482a..c450509d6efd 100644 --- a/net/ipv4/netfilter.c +++ b/net/ipv4/netfilter.c @@ -19,12 +19,12 @@ /* route_me_harder function, used by iptable_nat, iptable_mangle + ip_queu= e */ int ip_route_me_harder(struct net *net, struct sock *sk, struct sk_buff *s= kb, unsigned int addr_type) { + struct net_device *dev =3D skb_dst_dev(skb); const struct iphdr *iph =3D ip_hdr(skb); struct rtable *rt; struct flowi4 fl4 =3D {}; __be32 saddr =3D iph->saddr; __u8 flags; - struct net_device *dev =3D skb_dst(skb)->dev; struct flow_keys flkeys; unsigned int hh_len; =20 @@ -73,7 +73,7 @@ int ip_route_me_harder(struct net *net, struct sock *sk, = struct sk_buff *skb, un #endif =20 /* Change in oif may mean change in hh_len. */ - hh_len =3D skb_dst(skb)->dev->hard_header_len; + hh_len =3D skb_dst_dev(skb)->hard_header_len; if (skb_headroom(skb) < hh_len && pskb_expand_head(skb, HH_DATA_ALIGN(hh_len - skb_headroom(skb)), 0, GFP_ATOMIC)) diff --git a/net/ipv4/route.c b/net/ipv4/route.c index 783460ebfc47..a2985265c792 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c @@ -416,7 +416,7 @@ static struct neighbour *ipv4_neigh_lookup(const struct= dst_entry *dst, const void *daddr) { const struct rtable *rt =3D container_of(dst, struct rtable, dst); - struct net_device *dev =3D dst->dev; + struct net_device *dev =3D dst_dev(dst); struct neighbour *n; =20 rcu_read_lock(); @@ -443,7 +443,7 @@ static struct neighbour *ipv4_neigh_lookup(const struct= dst_entry *dst, static void ipv4_confirm_neigh(const struct dst_entry *dst, const void *da= ddr) { const struct rtable *rt =3D container_of(dst, struct rtable, dst); - struct net_device *dev =3D dst->dev; + struct net_device *dev =3D dst_dev(dst); const __be32 *pkey =3D daddr; =20 if (rt->rt_gw_family =3D=3D AF_INET) { @@ -1069,7 +1069,7 @@ static void __ip_rt_update_pmtu(struct rtable *rt, st= ruct flowi4 *fl4, u32 mtu) return; =20 rcu_read_lock(); - net =3D dev_net_rcu(dst->dev); + net =3D dev_net_rcu(dst_dev(dst)); if (mtu < net->ipv4.ip_rt_min_pmtu) { lock =3D true; mtu =3D min(old_mtu, net->ipv4.ip_rt_min_pmtu); @@ -1367,7 +1367,7 @@ static unsigned int ipv4_default_advmss(const struct = dst_entry *dst) struct net *net; =20 rcu_read_lock(); - net =3D dev_net_rcu(dst->dev); + net =3D dev_net_rcu(dst_dev(dst)); advmss =3D max_t(unsigned int, ipv4_mtu(dst) - header_size, net->ipv4.ip_rt_min_advmss); rcu_read_unlock(); diff --git a/net/ipv4/tcp_fastopen.c b/net/ipv4/tcp_fastopen.c index cbce1306bb08..b295e2e555bb 100644 --- a/net/ipv4/tcp_fastopen.c +++ b/net/ipv4/tcp_fastopen.c @@ -558,6 +558,7 @@ bool tcp_fastopen_active_should_disable(struct sock *sk) void tcp_fastopen_active_disable_ofo_check(struct sock *sk) { struct tcp_sock *tp =3D tcp_sk(sk); + struct net_device *dev; struct dst_entry *dst; struct sk_buff *skb; =20 @@ -575,7 +576,8 @@ void tcp_fastopen_active_disable_ofo_check(struct sock = *sk) } else if (tp->syn_fastopen_ch && atomic_read(&sock_net(sk)->ipv4.tfo_active_disable_times)) { dst =3D sk_dst_get(sk); - if (!(dst && dst->dev && (dst->dev->flags & IFF_LOOPBACK))) + dev =3D dst ? dst_dev(dst) : NULL; + if (!(dev && (dev->flags & IFF_LOOPBACK))) atomic_set(&sock_net(sk)->ipv4.tfo_active_disable_times, 0); dst_release(dst); } diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index 753a881ce3cd..f72e7a5856d0 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c @@ -733,7 +733,8 @@ static void tcp_v4_send_reset(const struct sock *sk, st= ruct sk_buff *skb) arg.iov[0].iov_base =3D (unsigned char *)&rep; arg.iov[0].iov_len =3D sizeof(rep.th); =20 - net =3D sk ? sock_net(sk) : dev_net(skb_dst(skb)->dev); + net =3D sk ? sock_net(sk) : skb_dst_dev_net(skb); + #ifdef CONFIG_TCP_MD5SIG rcu_read_lock(); hash_location =3D tcp_parse_md5sig_option(th); diff --git a/net/ipv4/tcp_metrics.c b/net/ipv4/tcp_metrics.c index a4e03a7a2c03..8bf1118e04c6 100644 --- a/net/ipv4/tcp_metrics.c +++ b/net/ipv4/tcp_metrics.c @@ -166,11 +166,11 @@ static struct tcp_metrics_block *tcpm_new(struct dst_= entry *dst, unsigned int hash) { struct tcp_metrics_block *tm; - struct net *net; bool reclaim =3D false; + struct net *net; =20 spin_lock_bh(&tcp_metrics_lock); - net =3D dev_net(dst->dev); + net =3D dev_net(dst_dev(dst)); =20 /* While waiting for the spin-lock the cache might have been populated * with this entry and so we have to check again. @@ -273,7 +273,7 @@ static struct tcp_metrics_block *__tcp_get_metrics_req(= struct request_sock *req, return NULL; } =20 - net =3D dev_net(dst->dev); + net =3D dev_net(dst_dev(dst)); hash ^=3D net_hash_mix(net); hash =3D hash_32(hash, tcp_metrics_hash_log); =20 @@ -318,7 +318,7 @@ static struct tcp_metrics_block *tcp_get_metrics(struct= sock *sk, else return NULL; =20 - net =3D dev_net(dst->dev); + net =3D dev_net(dst_dev(dst)); hash ^=3D net_hash_mix(net); hash =3D hash_32(hash, tcp_metrics_hash_log); =20 diff --git a/net/ipv4/xfrm4_output.c b/net/ipv4/xfrm4_output.c index 3cff51ba72bb..0ae67d537499 100644 --- a/net/ipv4/xfrm4_output.c +++ b/net/ipv4/xfrm4_output.c @@ -31,7 +31,7 @@ static int __xfrm4_output(struct net *net, struct sock *s= k, struct sk_buff *skb) int xfrm4_output(struct net *net, struct sock *sk, struct sk_buff *skb) { return NF_HOOK_COND(NFPROTO_IPV4, NF_INET_POST_ROUTING, - net, sk, skb, skb->dev, skb_dst(skb)->dev, + net, sk, skb, skb->dev, skb_dst_dev(skb), __xfrm4_output, !(IPCB(skb)->flags & IPSKB_REROUTED)); } --=20 2.55.0 From nobody Mon Sep 28 12:34:51 2026 Received: from smtpout-03.galae.net (smtpout-03.galae.net [185.246.85.4]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 9AD1F32D0EE; Fri, 21 Aug 2026 13:34:26 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.246.85.4 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787319268; cv=none; b=q7TbS+SznSDm41X0CMTRsZkECth4TIMHoLrf6O7DX2cdtEd+tVktU67KsdFrTIB4Sx8zBripKfW8bfg/C+u5/aiji1h+FkMQw5qpNKMA/j1Loy/SNdMhuhDJfyftqLm8XGZTI8MX+CZblP4uK8q3FCcX1mtJsdDC/HNDJthA9bQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787319268; c=relaxed/simple; bh=BdXgn4sRe9EqG8nZ8tl9iiMkI7i8f/LlhKWsg7ZEk6I=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=KRTxWwNYQ+VYlSPmQMJH6/5dTdHRp1eKK7bbWOzXe5OWMQR77s6BU8wRX0Bcn0A/sHc+jcHimXIIftmmkLXbSRg/7DYtU4lyV1MBjt+6qXSp7Twb9PRYpIGri2aElZLeCdWkeuntofHNW48KCppHgxYpyeQ9Gsdi8daXDysyi+0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com; spf=pass smtp.mailfrom=bootlin.com; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b=TaWp5fzQ; arc=none smtp.client-ip=185.246.85.4 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=bootlin.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b="TaWp5fzQ" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-03.galae.net (Postfix) with ESMTPS id 0216F4E4131F; Fri, 21 Aug 2026 13:34:25 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id CA808604AA; Fri, 21 Aug 2026 13:34:24 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id D967111C77154; Fri, 21 Aug 2026 15:34:17 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1787319259; h=from:subject:date:message-id:to:cc:mime-version:content-type: content-transfer-encoding:in-reply-to:references; bh=EwH3Ypx289io+C0LZ7hWAmRw5EugYRav2eKuXPeBs0E=; b=TaWp5fzQA2xlsC2IY5lI3NsPzUbJfQDZpleIIlfAWQzhZFZPO7ZJhNQU2DK5xJZsbwy2K/ 7b8j6qJ4vfyJiuCIf7geaptfWEbzAjajFnFCiRs9uDQu3gKPGqxsD8lRv1p1gRABi+v36x ZCd+NTvE8EBsNAaCSzdSNPrx5N0pro/NmmEF5aYwJk3yATjGgJiLDwvbll5akijix1xuhA nPqswn6DRAS9tD7EeexXSraWv5b5kd/ttLK1TcTM0sSEcxxzrYOmlBz/Xys92bKbXcQV03 e2hCmtOjuDEHSwU98YmGfii3Die57piSFtfR/A+cASfMmaf2Qj0m/a5bPboTWw== From: "Miguel Gazquez (Schneider Electric)" Date: Fri, 21 Aug 2026 15:33:37 +0200 Subject: [PATCH v6.1.y 3/4] net: dst: introduce dst->dev_rcu Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260821-cve-2025-40074-6-1-v1-3-cad5cf499b76@bootlin.com> References: <20260821-cve-2025-40074-6-1-v1-0-cad5cf499b76@bootlin.com> In-Reply-To: <20260821-cve-2025-40074-6-1-v1-0-cad5cf499b76@bootlin.com> To: stable@vger.kernel.org, "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Wei Wang , Martin KaFai Lau , Hideaki YOSHIFUJI , David Ahern , Steffen Klassert , Herbert Xu , Pablo Neira Ayuso , Jozsef Kadlecsik , Florian Westphal Cc: Thomas Petazzoni , netdev@vger.kernel.org, linux-kernel@vger.kernel.org, netfilter-devel@vger.kernel.org, coreteam@netfilter.org, Miguel Gazquez X-Mailer: b4 0.15.2 X-Developer-Signature: v=1; a=ed25519-sha256; t=1787319234; l=3443; i=miguel.gazquez@bootlin.com; s=20250708; h=from:subject:message-id; bh=Qh4yGpefzJpMEezVFgmBfkjqu1IK8GzcTa9YD/69U0A=; b=lndM3a8dW9VB37KPeVBU/BTGadXo2ALj2RPsJJZe73yciXobdCv/9Urp1gM6AWy63BttYH9pd M2eAAfr8p8lAb3r0+/lC4biaUKkK+1NkTJtBsl59/sEcSQXthk0ilYi X-Developer-Key: i=miguel.gazquez@bootlin.com; a=ed25519; pk=k/2KI9jkmayaF0ghZ8QYUH9Wm/kFHDhl8QoZ0RHbr4w= X-Last-TLS-Session-Version: TLSv1.3 From: Eric Dumazet [ Upstream commit caedcc5b6df1b2e2b5f39079e3369c1d4d5c5f50 ] Followup of commit 88fe14253e18 ("net: dst: add four helpers to annotate data-races around dst->dev"). We want to gradually add explicit RCU protection to dst->dev, including lockdep support. Add an union to alias dst->dev_rcu and dst->dev. Add dst_dev_net_rcu() helper. Fixes: 4a6ce2b6f2ec ("net: introduce a new function dst_dev_put()") Signed-off-by: Eric Dumazet Reviewed-by: David Ahern Link: https://patch.msgid.link/20250828195823.3958522-2-edumazet@google.com Signed-off-by: Jakub Kicinski Signed-off-by: Miguel Gazquez --- include/net/dst.h | 16 +++++++++++----- net/core/dst.c | 2 +- net/ipv4/route.c | 4 ++-- 3 files changed, 14 insertions(+), 8 deletions(-) diff --git a/include/net/dst.h b/include/net/dst.h index 7c0cf856154d..96dd65a941c5 100644 --- a/include/net/dst.h +++ b/include/net/dst.h @@ -23,7 +23,10 @@ struct sk_buff; =20 struct dst_entry { - struct net_device *dev; + union { + struct net_device *dev; + struct net_device __rcu *dev_rcu; + }; struct dst_ops *ops; unsigned long _metrics; unsigned long expires; @@ -562,9 +565,12 @@ static inline struct net_device *dst_dev(const struct = dst_entry *dst) =20 static inline struct net_device *dst_dev_rcu(const struct dst_entry *dst) { - /* In the future, use rcu_dereference(dst->dev) */ - WARN_ON_ONCE(!rcu_read_lock_held()); - return READ_ONCE(dst->dev); + return rcu_dereference(dst->dev_rcu); +} + +static inline struct net *dst_dev_net_rcu(const struct dst_entry *dst) +{ + return dev_net_rcu(dst_dev_rcu(dst)); } =20 static inline struct net_device *skb_dst_dev(const struct sk_buff *skb) @@ -584,7 +590,7 @@ static inline struct net *skb_dst_dev_net(const struct = sk_buff *skb) =20 static inline struct net *skb_dst_dev_net_rcu(const struct sk_buff *skb) { - return dev_net_rcu(skb_dst_dev(skb)); + return dev_net_rcu(skb_dst_dev_rcu(skb)); } =20 struct dst_entry *dst_blackhole_check(struct dst_entry *dst, u32 cookie); diff --git a/net/core/dst.c b/net/core/dst.c index 24a1cc3d2a08..cbb6888aa32b 100644 --- a/net/core/dst.c +++ b/net/core/dst.c @@ -151,7 +151,7 @@ void dst_dev_put(struct dst_entry *dst) dst->ops->ifdown(dst, dev, true); dst->input =3D dst_discard; dst->output =3D dst_discard_out; - WRITE_ONCE(dst->dev, blackhole_netdev); + rcu_assign_pointer(dst->dev_rcu, blackhole_netdev); netdev_ref_replace(dev, blackhole_netdev, &dst->dev_tracker, GFP_ATOMIC); } diff --git a/net/ipv4/route.c b/net/ipv4/route.c index a2985265c792..e3cce307e0e9 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c @@ -1069,7 +1069,7 @@ static void __ip_rt_update_pmtu(struct rtable *rt, st= ruct flowi4 *fl4, u32 mtu) return; =20 rcu_read_lock(); - net =3D dev_net_rcu(dst_dev(dst)); + net =3D dst_dev_net_rcu(dst); if (mtu < net->ipv4.ip_rt_min_pmtu) { lock =3D true; mtu =3D min(old_mtu, net->ipv4.ip_rt_min_pmtu); @@ -1367,7 +1367,7 @@ static unsigned int ipv4_default_advmss(const struct = dst_entry *dst) struct net *net; =20 rcu_read_lock(); - net =3D dev_net_rcu(dst_dev(dst)); + net =3D dst_dev_net_rcu(dst); advmss =3D max_t(unsigned int, ipv4_mtu(dst) - header_size, net->ipv4.ip_rt_min_advmss); rcu_read_unlock(); --=20 2.55.0 From nobody Mon Sep 28 12:34:51 2026 Received: from smtpout-02.galae.net (smtpout-02.galae.net [185.246.84.56]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 46DA1327204; Fri, 21 Aug 2026 13:34:32 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.246.84.56 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787319273; cv=none; b=BfjsG2wz//r3cCQa2qvvI79NfED4a3AN25iN626hm8jdA4eW5jBEM5jQMGPEXsT9QWtXeFpJa2RQKMxtL3XILCH3uAR6Kf5lHFRom9O3R0dvfj32939M/mQ36CbisGK9lcKoa62cGrGaM8GDRgF6okkGKpOKwMtDljzirC7JVnY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787319273; c=relaxed/simple; bh=0cBdeBKAoZMckm4oypj7qiBbqo45cHPDVRVN3aaz/uc=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=OoXtizPN8HV9JKeiZ0lWU7kPmeTYrruSo39YrSJsVMjl5P6zbMEj9aT1hlUtsXusv8Am3TqURt53W5rCSubaFq0dUhzlITQ4xHy/AzwmZPXjRgFch8Td2VY4av/ZGnhnmKUEHQ6DOi3KA90ovXiVRJKvWUzJKwRSowqyyhGQD3s= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com; spf=pass smtp.mailfrom=bootlin.com; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b=BWoFk8yu; arc=none smtp.client-ip=185.246.84.56 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=bootlin.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b="BWoFk8yu" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-02.galae.net (Postfix) with ESMTPS id B79551A1780; Fri, 21 Aug 2026 13:34:30 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id 83270604AA; Fri, 21 Aug 2026 13:34:30 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id 1A1E211C77155; Fri, 21 Aug 2026 15:34:24 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1787319265; h=from:subject:date:message-id:to:cc:mime-version:content-type: content-transfer-encoding:in-reply-to:references; bh=sSK7wQls//2t/gBlSOfdfhT2YxJnO5Zs6EyGQfgl/c4=; b=BWoFk8yuq3757VU0qGG4P04JEutrbg+pMcZJWibyaPCYcCmJOxnQTBxsHi5yP8zi415wmh GZbwSn6f+NACAIWp/ZLgNgKhlL+OmYmY77/5dcJwu2GmKQv68kfO56sxOKLbINuDCGlYfB UQYqfhGFNhJCVz0xvbDj71Wl0Yh4GjNzhNUquc1k7sNkVl/3pGiTfQ6pFdcj4bOEnrX3+V 1EActJYHgxJa2Q7hLPkPu+jlM+3HWOBv88/QoE16sD6HQuc9uF9Z4aA0qK9WnrnDU2oQDI gLPAQJA177Fqme7YVdgHG8LedSkHAKr5MMEC/CuCFS9yyBN7CdDJdrU/J0X40A== From: "Miguel Gazquez (Schneider Electric)" Date: Fri, 21 Aug 2026 15:33:38 +0200 Subject: [PATCH v6.1.y 4/4] ipv4: start using dst_dev_rcu() Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260821-cve-2025-40074-6-1-v1-4-cad5cf499b76@bootlin.com> References: <20260821-cve-2025-40074-6-1-v1-0-cad5cf499b76@bootlin.com> In-Reply-To: <20260821-cve-2025-40074-6-1-v1-0-cad5cf499b76@bootlin.com> To: stable@vger.kernel.org, "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Wei Wang , Martin KaFai Lau , Hideaki YOSHIFUJI , David Ahern , Steffen Klassert , Herbert Xu , Pablo Neira Ayuso , Jozsef Kadlecsik , Florian Westphal Cc: Thomas Petazzoni , netdev@vger.kernel.org, linux-kernel@vger.kernel.org, netfilter-devel@vger.kernel.org, coreteam@netfilter.org, Miguel Gazquez X-Mailer: b4 0.15.2 X-Developer-Signature: v=1; a=ed25519-sha256; t=1787319234; l=3849; i=miguel.gazquez@bootlin.com; s=20250708; h=from:subject:message-id; bh=KdCidSzyMWhI98Jiee7VIqnLTiAwLq+MAszWW3VzCjQ=; b=ZvBuuFbGmvLsoe99JGCB08NBg61pH7Q7lZi+lQZKDDxvqN06Ns0T8PDxT6uUYipuqQU4prtlM Fwqv3zghBzbCeswc0j4uK5JL+mGV2M2rbNQs8d6ZwhjH4vhR+4w4546 X-Developer-Key: i=miguel.gazquez@bootlin.com; a=ed25519; pk=k/2KI9jkmayaF0ghZ8QYUH9Wm/kFHDhl8QoZ0RHbr4w= X-Last-TLS-Session-Version: TLSv1.3 From: Eric Dumazet [ 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 Reviewed-by: David Ahern Link: https://patch.msgid.link/20250828195823.3958522-9-edumazet@google.com Signed-off-by: Jakub Kicinski [ minor modifications to fix conflict, added rcu_read_lock and unlock to ip_defrag function ] Signed-off-by: Miguel Gazquez (Schneider Electric) --- net/ipv4/icmp.c | 6 +++--- net/ipv4/ip_fragment.c | 9 +++++++-- net/ipv4/ipmr.c | 2 +- net/ipv4/route.c | 4 ++-- 4 files changed, 13 insertions(+), 8 deletions(-) diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c index 7763a98ddc96..e87325b80e0c 100644 --- a/net/ipv4/icmp.c +++ b/net/ipv4/icmp.c @@ -320,17 +320,17 @@ static bool icmpv4_xrlim_allow(struct net *net, struc= t rtable *rt, return true; =20 /* No rate limit on loopback */ - dev =3D dst_dev(dst); + rcu_read_lock(); + dev =3D dst_dev_rcu(dst); if (dev && (dev->flags & IFF_LOOPBACK)) goto out; =20 - rcu_read_lock(); peer =3D inet_getpeer_v4(net->ipv4.peers, fl4->daddr, l3mdev_master_ifindex_rcu(dev)); rc =3D 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 diff --git a/net/ipv4/ip_fragment.c b/net/ipv4/ip_fragment.c index a70ede523297..43b1265f5ac1 100644 --- a/net/ipv4/ip_fragment.c +++ b/net/ipv4/ip_fragment.c @@ -481,13 +481,16 @@ static int ip_frag_reasm(struct ipq *qp, struct sk_bu= ff *skb, /* Process an incoming IP datagram fragment. */ int ip_defrag(struct net *net, struct sk_buff *skb, u32 user) { - struct net_device *dev =3D skb->dev ? : skb_dst_dev(skb); - int vif =3D l3mdev_master_ifindex_rcu(dev); + struct net_device *dev; struct ipq *qp; + int vif; =20 __IP_INC_STATS(net, IPSTATS_MIB_REASMREQDS); =20 /* Lookup (or create) queue header */ + rcu_read_lock(); + dev =3D skb->dev ? : skb_dst_dev_rcu(skb); + vif =3D l3mdev_master_ifindex_rcu(dev); qp =3D ip_find(net, ip_hdr(skb), user, vif); if (qp) { int ret; @@ -497,9 +500,11 @@ int ip_defrag(struct net *net, struct sk_buff *skb, u3= 2 user) ret =3D ip_frag_queue(qp, skb); =20 spin_unlock(&qp->q.lock); + rcu_read_unlock(); ipq_put(qp); return ret; } + rcu_read_unlock(); =20 __IP_INC_STATS(net, IPSTATS_MIB_REASMFAILS); kfree_skb(skb); diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c index f64651c0dea6..8d4f556fced2 100644 --- a/net/ipv4/ipmr.c +++ b/net/ipv4/ipmr.c @@ -1879,7 +1879,7 @@ static void ipmr_queue_xmit(struct net *net, struct m= r_table *mrt, goto out_free; } =20 - dev =3D rt->dst.dev; + dev =3D dst_dev_rcu(&rt->dst); =20 if (skb->len+encap > dst_mtu(&rt->dst) && (ntohs(iph->frag_off) & IP_DF))= { /* Do not fragment multicasts. Alas, IPv4 does not diff --git a/net/ipv4/route.c b/net/ipv4/route.c index e3cce307e0e9..5528a5543df5 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c @@ -416,11 +416,11 @@ static struct neighbour *ipv4_neigh_lookup(const stru= ct dst_entry *dst, const void *daddr) { const struct rtable *rt =3D container_of(dst, struct rtable, dst); - struct net_device *dev =3D dst_dev(dst); + struct net_device *dev; struct neighbour *n; =20 rcu_read_lock(); - + dev =3D dst_dev_rcu(dst); if (likely(rt->rt_gw_family =3D=3D AF_INET)) { n =3D ip_neigh_gw4(dev, rt->rt_gw4); } else if (rt->rt_gw_family =3D=3D AF_INET6) { --=20 2.55.0