[PATCH OLK-5.10 0/9] net: Netdev use RCU protection
Netdev use RCU protection Dong Chenchen (1): net: dst: Fix kabi-breakage for struct dst_entry Eric Dumazet (7): net: dst: add four helpers to annotate data-races around dst->dev ipv4: use RCU protection in __ip_rt_update_pmtu() net: dst: introduce dst->dev_rcu tcp_metrics: use dst_dev_net_rcu() ipv4: start using dst_dev_rcu() ipv4: use RCU protection in ip_dst_mtu_maybe_forward() net: use dst_dev_rcu() in sk_setup_caps() Kuniyuki Iwashima (1): tls: Use __sk_dst_get() and dst_dev_rcu() in get_netdev_for_sock(). include/net/dst.h | 34 ++++++++++++++++++++++++++++++---- include/net/ip.h | 22 ++++++++++++++++------ include/net/ip6_route.h | 2 +- include/net/route.h | 9 +++++++-- net/core/dst.c | 4 ++-- net/core/sock.c | 10 +++++++--- net/ipv4/icmp.c | 10 +++++++--- net/ipv4/ip_fragment.c | 9 +++++++-- net/ipv4/ipmr.c | 2 +- net/ipv4/route.c | 7 ++++--- net/ipv4/tcp_metrics.c | 6 +++--- net/tls/tls_device.c | 13 ++++++------- 12 files changed, 91 insertions(+), 37 deletions(-) -- 2.25.1
反馈: 您发送到kernel@openeuler.org的补丁/补丁集,已成功转换为PR! PR链接地址: https://gitee.com/openeuler/kernel/pulls/19307 邮件列表地址:https://mailweb.openeuler.org/archives/list/kernel@openeuler.org/message/Z5N... FeedBack: The patch(es) which you have sent to kernel@openeuler.org mailing list has been converted to a pull request successfully! Pull request link: https://gitee.com/openeuler/kernel/pulls/19307 Mailing list address: https://mailweb.openeuler.org/archives/list/kernel@openeuler.org/message/Z5N...
From: Eric Dumazet <edumazet@google.com> mainline inclusion from mainline-v6.17-rc1 commit 88fe14253e181878c2ddb51a298ae8c468a63010 category: bugfix bugzilla: https://gitee.com/src-openeuler/kernel/issues/ID3WJ1 CVE: CVE-2025-40074 Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?i... -------------------------------- 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 <edumazet@google.com> Reviewed-by: Kuniyuki Iwashima <kuniyu@google.com> Link: https://patch.msgid.link/20250630121934.3399505-7-edumazet@google.com Signed-off-by: Jakub Kicinski <kuba@kernel.org> Conflicts: include/net/dst.h net/core/dst.c net/core/sock.c [conflicts due to not merge 8a402bbe5476 ("net: dst: annotate data-races around dst->obsolete"), conflicts due to not merge f1c5fd34891a ("net: dst: annotate data-races around dst->input"), conflicts due to not merge 2dce8c52a989 ("net: dst: annotate data-races around dst->output"), conflicts due to not merge b1a78b9b9886 ("net: add support for ipv4 big tcp"), commit 1dbf1d590d10 has been merged.] Signed-off-by: Dong Chenchen <dongchenchen2@huawei.com> --- 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 7f4609e7933c..cf491816d3c5 100644 --- a/include/net/dst.h +++ b/include/net/dst.h @@ -538,6 +538,11 @@ static inline void skb_dst_update_pmtu_no_confirm(struct sk_buff *skb, u32 mtu) dst->ops->update_pmtu(dst, NULL, skb, mtu, false); } +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) */ @@ -545,11 +550,26 @@ static inline struct net_device *dst_dev_rcu(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_device *skb_dst_dev_rcu(const struct sk_buff *skb) { return dst_dev_rcu(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)); +} + 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 299b4b4f76f6..64e1a6dc74ba 100644 --- a/net/core/dst.c +++ b/net/core/dst.c @@ -153,7 +153,7 @@ void dst_dev_put(struct dst_entry *dst) dst->ops->ifdown(dst, dev, true); dst->input = dst_discard; dst->output = dst_discard_out; - dst->dev = blackhole_netdev; + WRITE_ONCE(dst->dev, blackhole_netdev); dev_hold(dst->dev); dev_put(dev); } @@ -274,7 +274,7 @@ unsigned int dst_blackhole_mtu(const struct dst_entry *dst) { unsigned int mtu = dst_metric_raw(dst, RTAX_MTU); - return mtu ? : dst->dev->mtu; + return mtu ? : dst_dev(dst)->mtu; } EXPORT_SYMBOL_GPL(dst_blackhole_mtu); diff --git a/net/core/sock.c b/net/core/sock.c index 0e4ba9d63542..6d1d465511ad 100644 --- a/net/core/sock.c +++ b/net/core/sock.c @@ -2055,7 +2055,7 @@ void sk_setup_caps(struct sock *sk, struct dst_entry *dst) { u32 max_segs = 1; - sk->sk_route_caps = dst->dev->features | sk->sk_route_forced_caps; + sk->sk_route_caps = dst_dev(dst)->features | sk->sk_route_forced_caps; if (sk->sk_route_caps & NETIF_F_GSO) sk->sk_route_caps |= NETIF_F_GSO_SOFTWARE; sk->sk_route_caps &= ~sk->sk_route_nocaps; @@ -2064,8 +2064,8 @@ void sk_setup_caps(struct sock *sk, struct dst_entry *dst) sk->sk_route_caps &= ~NETIF_F_GSO_MASK; } else { sk->sk_route_caps |= NETIF_F_SG | NETIF_F_HW_CSUM; - sk->sk_gso_max_size = dst->dev->gso_max_size; - max_segs = max_t(u32, dst->dev->gso_max_segs, 1); + sk->sk_gso_max_size = dst_dev(dst)->gso_max_size; + max_segs = max_t(u32, dst_dev(dst)->gso_max_segs, 1); } } sk->sk_gso_max_segs = max_segs; -- 2.25.1
From: Eric Dumazet <edumazet@google.com> mainline inclusion from mainline-v6.14-rc3 commit 139512191bd06f1b496117c76372b2ce372c9a41 category: bugfix bugzilla: https://gitee.com/src-openeuler/kernel/issues/ID3WJ1 CVE: CVE-2025-40074 Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?i... -------------------------------- __ip_rt_update_pmtu() must use RCU protection to make sure the net structure it reads does not disappear. Fixes: 2fbc6e89b2f1 ("ipv4: Update exception handling for multipath routes via same device") Fixes: 1de6b15a434c ("Namespaceify min_pmtu sysctl") Signed-off-by: Eric Dumazet <edumazet@google.com> Link: https://patch.msgid.link/20250205155120.1676781-8-edumazet@google.com Signed-off-by: Jakub Kicinski <kuba@kernel.org> Conflicts: net/ipv4/route.c [commit 1de6b15a434c namespaceify min_pmtu sysctl, which not merged lead to context conflicts.] Signed-off-by: Dong Chenchen <dongchenchen2@huawei.com> --- net/ipv4/route.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/net/ipv4/route.c b/net/ipv4/route.c index 677caffa1ded..c2bfe245c5f1 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c @@ -1038,9 +1038,9 @@ out: kfree_skb(skb); static void __ip_rt_update_pmtu(struct rtable *rt, struct flowi4 *fl4, u32 mtu) { struct dst_entry *dst = &rt->dst; - struct net *net = dev_net(dst->dev); struct fib_result res; bool lock = false; + struct net *net; u32 old_mtu; if (ip_mtu_locked(dst)) @@ -1060,6 +1060,7 @@ static void __ip_rt_update_pmtu(struct rtable *rt, struct flowi4 *fl4, u32 mtu) return; rcu_read_lock(); + net = dev_net_rcu(dst->dev); if (fib_lookup(net, fl4, &res, 0) == 0) { struct fib_nh_common *nhc; -- 2.25.1
From: Eric Dumazet <edumazet@google.com> mainline inclusion from mainline-v6.18-rc1 commit caedcc5b6df1b2e2b5f39079e3369c1d4d5c5f50 category: bugfix bugzilla: https://gitee.com/src-openeuler/kernel/issues/ID3WJ1 CVE: CVE-2025-40074 Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?i... -------------------------------- 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 <edumazet@google.com> Reviewed-by: David Ahern <dsahern@kernel.org> Link: https://patch.msgid.link/20250828195823.3958522-2-edumazet@google.com Signed-off-by: Jakub Kicinski <kuba@kernel.org> Conflicts: net/core/dst.c net/ipv4/route.c [commit f1c5fd34891a and d62607c3fe45(dst.c) a74fc62eec15 and 2e9589ff809e(route.c) is not backport] Signed-off-by: Dong Chenchen <dongchenchen2@huawei.com> --- include/net/dst.h | 16 +++++++++++----- net/core/dst.c | 2 +- net/ipv4/route.c | 2 +- 3 files changed, 13 insertions(+), 7 deletions(-) diff --git a/include/net/dst.h b/include/net/dst.h index cf491816d3c5..324aa252fde1 100644 --- a/include/net/dst.h +++ b/include/net/dst.h @@ -23,7 +23,10 @@ struct sk_buff; 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; @@ -545,9 +548,12 @@ static inline struct net_device *dst_dev(const struct dst_entry *dst) 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)); } static inline struct net_device *skb_dst_dev(const struct sk_buff *skb) @@ -567,7 +573,7 @@ static inline struct net *skb_dst_dev_net(const struct sk_buff *skb) 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)); } 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 64e1a6dc74ba..162679986d49 100644 --- a/net/core/dst.c +++ b/net/core/dst.c @@ -153,7 +153,7 @@ void dst_dev_put(struct dst_entry *dst) dst->ops->ifdown(dst, dev, true); dst->input = dst_discard; dst->output = dst_discard_out; - WRITE_ONCE(dst->dev, blackhole_netdev); + rcu_assign_pointer(dst->dev_rcu, blackhole_netdev); dev_hold(dst->dev); dev_put(dev); } diff --git a/net/ipv4/route.c b/net/ipv4/route.c index c2bfe245c5f1..394fa615db82 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c @@ -1060,7 +1060,7 @@ static void __ip_rt_update_pmtu(struct rtable *rt, struct flowi4 *fl4, u32 mtu) return; rcu_read_lock(); - net = dev_net_rcu(dst->dev); + net = dst_dev_net_rcu(dst); if (fib_lookup(net, fl4, &res, 0) == 0) { struct fib_nh_common *nhc; -- 2.25.1
From: Eric Dumazet <edumazet@google.com> mainline inclusion from mainline-v6.18-rc1 commit 50c127a69cd6285300931853b352a1918cfa180f category: bugfix bugzilla: https://gitee.com/src-openeuler/kernel/issues/ID3WJ1 CVE: CVE-2025-40074 Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?i... -------------------------------- Replace three dst_dev() with a lockdep enabled helper. Fixes: 4a6ce2b6f2ec ("net: introduce a new function dst_dev_put()") Signed-off-by: Eric Dumazet <edumazet@google.com> Reviewed-by: David Ahern <dsahern@kernel.org> Link: https://patch.msgid.link/20250828195823.3958522-7-edumazet@google.com Signed-off-by: Jakub Kicinski <kuba@kernel.org> Conflicts: net/ipv4/tcp_metrics.c [commit a74fc62eec15 is not backport] Signed-off-by: Dong Chenchen <dongchenchen2@huawei.com> --- net/ipv4/tcp_metrics.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/net/ipv4/tcp_metrics.c b/net/ipv4/tcp_metrics.c index 95b5ac082a2f..b48d6c07370b 100644 --- a/net/ipv4/tcp_metrics.c +++ b/net/ipv4/tcp_metrics.c @@ -170,7 +170,7 @@ static struct tcp_metrics_block *tcpm_new(struct dst_entry *dst, bool reclaim = false; spin_lock_bh(&tcp_metrics_lock); - net = dev_net(dst->dev); + net = dst_dev_net_rcu(dst); /* 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; } - net = dev_net(dst->dev); + net = dst_dev_net_rcu(dst); hash ^= net_hash_mix(net); hash = hash_32(hash, tcp_metrics_hash_log); @@ -318,7 +318,7 @@ static struct tcp_metrics_block *tcp_get_metrics(struct sock *sk, else return NULL; - net = dev_net(dst->dev); + net = dst_dev_net_rcu(dst); hash ^= net_hash_mix(net); hash = hash_32(hash, tcp_metrics_hash_log); -- 2.25.1
From: Eric Dumazet <edumazet@google.com> mainline inclusion from mainline-v6.18-rc1 commit 6ad8de3cefdb6ffa6708b21c567df0dbf82c43a8 category: bugfix bugzilla: https://gitee.com/src-openeuler/kernel/issues/ID3WJ1 CVE: CVE-2025-40074 Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?i... -------------------------------- 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 <edumazet@google.com> Reviewed-by: David Ahern <dsahern@kernel.org> Link: https://patch.msgid.link/20250828195823.3958522-9-edumazet@google.com Signed-off-by: Jakub Kicinski <kuba@kernel.org> Conflicts: net/ipv4/icmp.c net/ipv4/ip_fragment.c net/ipv4/ipmr.c net/ipv4/route.c [commit a74fc62eec15 is not backport. commit a853c609504e and c73f836caefe(icmp.c), commit ca0359df45a5(ip_fragment.c), commit b2e653bcff0f and 3b7bc938e0ad and 35bec72a24ac(ipmr.c), commit 09eed1192cec(route.c) are not backport] Signed-off-by: Dong Chenchen <dongchenchen2@huawei.com> --- net/ipv4/icmp.c | 10 +++++++--- net/ipv4/ip_fragment.c | 9 +++++++-- net/ipv4/ipmr.c | 2 +- net/ipv4/route.c | 4 ++-- 4 files changed, 17 insertions(+), 8 deletions(-) diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c index 7041f73d5be6..6fdac117fe16 100644 --- a/net/ipv4/icmp.c +++ b/net/ipv4/icmp.c @@ -316,23 +316,27 @@ static bool icmpv4_xrlim_allow(struct net *net, struct rtable *rt, { struct dst_entry *dst = &rt->dst; struct inet_peer *peer; + struct net_device *dev; bool rc = true; int vif; if (icmpv4_mask_allow(net, type, code)) - goto out; + return true; /* No rate limit on loopback */ - if (dst->dev && (dst->dev->flags&IFF_LOOPBACK)) + rcu_read_lock(); + dev = dst_dev_rcu(dst); + if (dev && (dev->flags&IFF_LOOPBACK)) goto out; - vif = l3mdev_master_ifindex(dst->dev); + vif = l3mdev_master_ifindex(dev); peer = inet_getpeer_v4(net->ipv4.peers, fl4->daddr, vif, 1); rc = inet_peer_xrlim_allow(peer, READ_ONCE(net->ipv4.sysctl_icmp_ratelimit)); if (peer) inet_putpeer(peer); out: + rcu_read_unlock(); return rc; } diff --git a/net/ipv4/ip_fragment.c b/net/ipv4/ip_fragment.c index ec2264adf2a6..5cdc65a5c010 100644 --- a/net/ipv4/ip_fragment.c +++ b/net/ipv4/ip_fragment.c @@ -475,13 +475,16 @@ 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 = skb->dev ? : skb_dst(skb)->dev; - 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 */ + rcu_read_lock(); + dev = skb->dev ? : skb_dst_dev_rcu(skb); + vif = l3mdev_master_ifindex_rcu(dev); qp = ip_find(net, ip_hdr(skb), user, vif); if (qp) { int ret; @@ -491,9 +494,11 @@ int ip_defrag(struct net *net, struct sk_buff *skb, u32 user) ret = ip_frag_queue(qp, skb); spin_unlock(&qp->q.lock); + rcu_read_unlock(); ipq_put(qp); return ret; } + rcu_read_unlock(); __IP_INC_STATS(net, IPSTATS_MIB_REASMFAILS); kfree_skb(skb); diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c index be1976536f1c..59104722b03f 100644 --- a/net/ipv4/ipmr.c +++ b/net/ipv4/ipmr.c @@ -1855,7 +1855,7 @@ static void ipmr_queue_xmit(struct net *net, struct mr_table *mrt, goto out_free; } - dev = rt->dst.dev; + dev = dst_dev_rcu(&rt->dst); 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 394fa615db82..142798b158e5 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c @@ -436,11 +436,11 @@ static struct neighbour *ipv4_neigh_lookup(const struct dst_entry *dst, const void *daddr) { const struct rtable *rt = container_of(dst, struct rtable, dst); - struct net_device *dev = dst->dev; + struct net_device *dev; struct neighbour *n; rcu_read_lock_bh(); - + 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) { -- 2.25.1
hulk inclusion category: bugfix bugzilla: https://gitee.com/src-openeuler/kernel/issues/ID3WJ1 CVE: CVE-2025-40074 -------------------------------- Use KBAI_REPLACE to fix kabi breakage of struct dst_entry for adding dev_rcu. Fixes: caedcc5b6df1 ("net: dst: introduce dst->dev_rcu") Signed-off-by: Dong Chenchen <dongchenchen2@huawei.com> --- include/net/dst.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/net/dst.h b/include/net/dst.h index 324aa252fde1..4013dd23e0be 100644 --- a/include/net/dst.h +++ b/include/net/dst.h @@ -23,10 +23,10 @@ struct sk_buff; struct dst_entry { - union { + KABI_REPLACE(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; -- 2.25.1
From: Kuniyuki Iwashima <kuniyu@google.com> mainline inclusion from mainline-v6.18-rc1 commit c65f27b9c3be2269918e1cbad6d8884741f835c5 category: bugfix bugzilla: https://gitee.com/src-openeuler/kernel/issues/ID3WJ1 CVE: CVE-2025-40074 Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?i... -------------------------------- get_netdev_for_sock() is called during setsockopt(), so not under RCU. Using sk_dst_get(sk)->dev could trigger UAF. Let's use __sk_dst_get() and dst_dev_rcu(). Note that the only ->ndo_sk_get_lower_dev() user is bond_sk_get_lower_dev(), which uses RCU. Fixes: e8f69799810c ("net/tls: Add generic NIC offload infrastructure") Signed-off-by: Kuniyuki Iwashima <kuniyu@google.com> Reviewed-by: Eric Dumazet <edumazet@google.com> Reviewed-by: Sabrina Dubroca <sd@queasysnail.net> Link: https://patch.msgid.link/20250916214758.650211-6-kuniyu@google.com Signed-off-by: Jakub Kicinski <kuba@kernel.org> Conflicts: net/tls/tls_device.c [commit 153cbd137f0a is not backport] Signed-off-by: Dong Chenchen <dongchenchen2@huawei.com> --- net/tls/tls_device.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/net/tls/tls_device.c b/net/tls/tls_device.c index d9832a2ae23d..b0db6d8d7e21 100644 --- a/net/tls/tls_device.c +++ b/net/tls/tls_device.c @@ -113,15 +113,14 @@ static void tls_device_queue_ctx_destruction(struct tls_context *ctx) /* We assume that the socket is already connected */ static struct net_device *get_netdev_for_sock(struct sock *sk) { - struct dst_entry *dst = sk_dst_get(sk); struct net_device *netdev = NULL; + struct dst_entry *dst; - if (likely(dst)) { - netdev = dst->dev; - dev_hold(netdev); - } - - dst_release(dst); + rcu_read_lock(); + dst = __sk_dst_get(sk); + netdev = dst ? dst_dev_rcu(dst) : NULL; + dev_hold(netdev); + rcu_read_unlock(); return netdev; } -- 2.25.1
From: Eric Dumazet <edumazet@google.com> mainline inclusion from mainline-v6.14-rc3 commit 071d8012869b6af352acca346ade13e7be90a49f category: bugfix bugzilla: https://gitee.com/src-openeuler/kernel/issues/ID3WJ1 CVE: CVE-2025-40074 Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?i... -------------------------------- ip_dst_mtu_maybe_forward() must use RCU protection to make sure the net structure it reads does not disappear. Fixes: f87c10a8aa1e8 ("ipv4: introduce ip_dst_mtu_maybe_forward and protect forwarding path against pmtu spoofing") Signed-off-by: Eric Dumazet <edumazet@google.com> Reviewed-by: Kuniyuki Iwashima <kuniyu@amazon.com> Link: https://patch.msgid.link/20250205155120.1676781-4-edumazet@google.com Signed-off-by: Jakub Kicinski <kuba@kernel.org> Conflicts: include/net/ip.h [commit 1caf27297215 and ac6627a28dbf are not backport] Signed-off-by: Dong Chenchen <dongchenchen2@huawei.com> --- include/net/ip.h | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/include/net/ip.h b/include/net/ip.h index 12cb525572f0..6ecea4ef54dc 100644 --- a/include/net/ip.h +++ b/include/net/ip.h @@ -442,20 +442,28 @@ static inline bool ip_sk_ignore_df(const struct sock *sk) static inline unsigned int ip_dst_mtu_maybe_forward(const struct dst_entry *dst, bool forwarding) { - struct net *net = dev_net(dst->dev); - unsigned int mtu; + unsigned int mtu, res; + struct net *net; + + rcu_read_lock(); + net = dev_net_rcu(dst->dev); if (READ_ONCE(net->ipv4.sysctl_ip_fwd_use_pmtu) || ip_mtu_locked(dst) || - !forwarding) - return dst_mtu(dst); + !forwarding) { + res = dst_mtu(dst); + goto out; + } /* 'forwarding = true' case should always honour route mtu */ mtu = dst_metric_raw(dst, RTAX_MTU); if (!mtu) mtu = min(READ_ONCE(dst->dev->mtu), IP_MAX_MTU); - return mtu - lwtunnel_headroom(dst->lwtstate, mtu); + res = mtu - lwtunnel_headroom(dst->lwtstate, mtu); +out: + rcu_read_unlock(); + return res; } static inline unsigned int ip_skb_dst_mtu(struct sock *sk, -- 2.25.1
From: Eric Dumazet <edumazet@google.com> mainline inclusion from mainline-v6.18-rc1 commit 99a2ace61b211b0be861b07fbaa062fca4b58879 category: bugfix bugzilla: https://gitee.com/src-openeuler/kernel/issues/ID3WJ1 CVE: CVE-2025-40074 Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?i... -------------------------------- Use RCU to protect accesses to dst->dev from sk_setup_caps() and sk_dst_gso_max_size(). Also use dst_dev_rcu() in ip6_dst_mtu_maybe_forward(), and ip_dst_mtu_maybe_forward(). ip4_dst_hoplimit() can use dst_dev_net_rcu(). Fixes: 4a6ce2b6f2ec ("net: introduce a new function dst_dev_put()") Signed-off-by: Eric Dumazet <edumazet@google.com> Reviewed-by: David Ahern <dsahern@kernel.org> Link: https://patch.msgid.link/20250828195823.3958522-6-edumazet@google.com Signed-off-by: Jakub Kicinski <kuba@kernel.org> Conflicts: include/net/ip.h include/net/ip6_route.h include/net/route.h net/core/sock.c [commit 1caf27297215 and ac6627a28dbf(ip.h) 469308552ca4(route.h), b1a78b9b9886 and d0d598ca86bd(sock.c) are not backport] Signed-off-by: Dong Chenchen <dongchenchen2@huawei.com> --- include/net/ip.h | 6 ++++-- include/net/ip6_route.h | 2 +- include/net/route.h | 9 +++++++-- net/core/sock.c | 10 +++++++--- 4 files changed, 19 insertions(+), 8 deletions(-) diff --git a/include/net/ip.h b/include/net/ip.h index 6ecea4ef54dc..72415f77934a 100644 --- a/include/net/ip.h +++ b/include/net/ip.h @@ -442,12 +442,14 @@ static inline bool ip_sk_ignore_df(const struct sock *sk) static inline unsigned int ip_dst_mtu_maybe_forward(const struct dst_entry *dst, bool forwarding) { + const struct net_device *dev; unsigned int mtu, res; struct net *net; rcu_read_lock(); - net = dev_net_rcu(dst->dev); + dev = dst_dev_rcu(dst); + net = dev_net_rcu(dev); if (READ_ONCE(net->ipv4.sysctl_ip_fwd_use_pmtu) || ip_mtu_locked(dst) || !forwarding) { @@ -458,7 +460,7 @@ static inline unsigned int ip_dst_mtu_maybe_forward(const struct dst_entry *dst, /* 'forwarding = true' case should always honour route mtu */ mtu = dst_metric_raw(dst, RTAX_MTU); if (!mtu) - mtu = min(READ_ONCE(dst->dev->mtu), IP_MAX_MTU); + mtu = min(READ_ONCE(dev->mtu), IP_MAX_MTU); res = mtu - lwtunnel_headroom(dst->lwtstate, mtu); out: diff --git a/include/net/ip6_route.h b/include/net/ip6_route.h index 44969d03debf..69ef838f91d6 100644 --- a/include/net/ip6_route.h +++ b/include/net/ip6_route.h @@ -328,7 +328,7 @@ static inline unsigned int ip6_dst_mtu_forward(const struct dst_entry *dst) mtu = IPV6_MIN_MTU; rcu_read_lock(); - idev = __in6_dev_get(dst->dev); + idev = __in6_dev_get(dst_dev_rcu(dst)); if (idev) mtu = idev->cnf.mtu6; rcu_read_unlock(); diff --git a/include/net/route.h b/include/net/route.h index 2551f3f03b37..07d6fa94a6a8 100644 --- a/include/net/route.h +++ b/include/net/route.h @@ -357,10 +357,15 @@ static inline int inet_iif(const struct sk_buff *skb) static inline int ip4_dst_hoplimit(const struct dst_entry *dst) { int hoplimit = dst_metric_raw(dst, RTAX_HOPLIMIT); - struct net *net = dev_net(dst->dev); - if (hoplimit == 0) + if (hoplimit == 0) { + const struct net *net; + + rcu_read_lock(); + net = dst_dev_net_rcu(dst); hoplimit = net->ipv4.sysctl_ip_default_ttl; + rcu_read_unlock(); + } return hoplimit; } diff --git a/net/core/sock.c b/net/core/sock.c index 6d1d465511ad..b22ff2f641ab 100644 --- a/net/core/sock.c +++ b/net/core/sock.c @@ -2053,9 +2053,12 @@ EXPORT_SYMBOL_GPL(sk_free_unlock_clone); void sk_setup_caps(struct sock *sk, struct dst_entry *dst) { + const struct net_device *dev; u32 max_segs = 1; - sk->sk_route_caps = dst_dev(dst)->features | sk->sk_route_forced_caps; + rcu_read_lock(); + dev = dst_dev_rcu(dst); + sk->sk_route_caps = dev->features | sk->sk_route_forced_caps; if (sk->sk_route_caps & NETIF_F_GSO) sk->sk_route_caps |= NETIF_F_GSO_SOFTWARE; sk->sk_route_caps &= ~sk->sk_route_nocaps; @@ -2064,14 +2067,15 @@ void sk_setup_caps(struct sock *sk, struct dst_entry *dst) sk->sk_route_caps &= ~NETIF_F_GSO_MASK; } else { sk->sk_route_caps |= NETIF_F_SG | NETIF_F_HW_CSUM; - sk->sk_gso_max_size = dst_dev(dst)->gso_max_size; - max_segs = max_t(u32, dst_dev(dst)->gso_max_segs, 1); + sk->sk_gso_max_size = dev->gso_max_size; + max_segs = max_t(u32, dev->gso_max_segs, 1); } } sk->sk_gso_max_segs = max_segs; sk_dst_set(sk, dst); net_rship_sk_dst_set(sk, dst); + rcu_read_unlock(); } EXPORT_SYMBOL_GPL(sk_setup_caps); -- 2.25.1
participants (2)
-
Dong Chenchen -
patchwork bot