[PATCH OLK-5.10 0/3] ndisc: Fix CVE-2025-21764

fix CVE-2025-21764. Eric Dumazet (2): net: add dev_net_rcu() helper ndisc: use RCU protection in ndisc_alloc_skb() Jiri Pirko (1): net: treat possible_net_t net pointer as an RCU one and add read_pnet_rcu() include/linux/netdevice.h | 6 ++++++ include/net/net_namespace.h | 15 ++++++++++++--- net/ipv6/ndisc.c | 10 ++++------ 3 files changed, 22 insertions(+), 9 deletions(-) -- 2.25.1

反馈: 您发送到kernel@openeuler.org的补丁/补丁集,已成功转换为PR! PR链接地址: https://gitee.com/openeuler/kernel/pulls/16063 邮件列表地址:https://mailweb.openeuler.org/archives/list/kernel@openeuler.org/message/W72... 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/16063 Mailing list address: https://mailweb.openeuler.org/archives/list/kernel@openeuler.org/message/W72...

From: Jiri Pirko <jiri@nvidia.com> mainline inclusion from mainline-v6.7-rc1 commit 2034d90ae41ae93e30d492ebcf1f06f97a9cfba6 category: bugfix bugzilla: https://gitee.com/src-openeuler/kernel/issues/IBPC6A CVE: CVE-2025-21764 Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?i... -------------------------------- Make the net pointer stored in possible_net_t structure annotated as an RCU pointer. Change the access helpers to treat it as such. Introduce read_pnet_rcu() helper to allow caller to dereference the net pointer under RCU read lock. Signed-off-by: Jiri Pirko <jiri@nvidia.com> Reviewed-by: Simon Horman <horms@kernel.org> Signed-off-by: David S. Miller <davem@davemloft.net> Conflicts: include/net/net_namespace.h [commit 9ba74e6c9e9d add refcount tracker, which not merged lead to context conflict(no put_net_track())] Signed-off-by: Dong Chenchen <dongchenchen2@huawei.com> --- include/net/net_namespace.h | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/include/net/net_namespace.h b/include/net/net_namespace.h index 8e7aa1aabe17..e5867b9af92b 100644 --- a/include/net/net_namespace.h +++ b/include/net/net_namespace.h @@ -332,21 +332,30 @@ static inline int check_net(const struct net *net) typedef struct { #ifdef CONFIG_NET_NS - struct net *net; + struct net __rcu *net; #endif } possible_net_t; static inline void write_pnet(possible_net_t *pnet, struct net *net) { #ifdef CONFIG_NET_NS - pnet->net = net; + rcu_assign_pointer(pnet->net, net); #endif } static inline struct net *read_pnet(const possible_net_t *pnet) { #ifdef CONFIG_NET_NS - return pnet->net; + return rcu_dereference_protected(pnet->net, true); +#else + return &init_net; +#endif +} + +static inline struct net *read_pnet_rcu(possible_net_t *pnet) +{ +#ifdef CONFIG_NET_NS + return rcu_dereference(pnet->net); #else return &init_net; #endif -- 2.25.1

From: Eric Dumazet <edumazet@google.com> mainline inclusion from mainline-v6.14-rc3 commit 482ad2a4ace2740ca0ff1cbc8f3c7f862f3ab507 category: bugfix bugzilla: https://gitee.com/src-openeuler/kernel/issues/IBPC6A CVE: CVE-2025-21764 Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?i... -------------------------------- dev->nd_net can change, readers should either use rcu_read_lock() or RTNL. We currently use a generic helper, dev_net() with no debugging support. We probably have many hidden bugs. Add dev_net_rcu() helper for callers using rcu_read_lock() protection. Signed-off-by: Eric Dumazet <edumazet@google.com> Reviewed-by: Kuniyuki Iwashima <kuniyu@amazon.com> Link: https://patch.msgid.link/20250205155120.1676781-2-edumazet@google.com Signed-off-by: Jakub Kicinski <kuba@kernel.org> Signed-off-by: Dong Chenchen <dongchenchen2@huawei.com> --- include/linux/netdevice.h | 6 ++++++ include/net/net_namespace.h | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index dc52d8b57b2f..df61a63a5550 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -2441,6 +2441,12 @@ struct net *dev_net(const struct net_device *dev) return read_pnet(&dev->nd_net); } +static inline +struct net *dev_net_rcu(const struct net_device *dev) +{ + return read_pnet_rcu(&dev->nd_net); +} + static inline void dev_net_set(struct net_device *dev, struct net *net) { diff --git a/include/net/net_namespace.h b/include/net/net_namespace.h index e5867b9af92b..07610af3bdca 100644 --- a/include/net/net_namespace.h +++ b/include/net/net_namespace.h @@ -352,7 +352,7 @@ static inline struct net *read_pnet(const possible_net_t *pnet) #endif } -static inline struct net *read_pnet_rcu(possible_net_t *pnet) +static inline struct net *read_pnet_rcu(const possible_net_t *pnet) { #ifdef CONFIG_NET_NS return rcu_dereference(pnet->net); -- 2.25.1

From: Eric Dumazet <edumazet@google.com> mainline inclusion from mainline-v6.14-rc3 commit 628e6d18930bbd21f2d4562228afe27694f66da9 category: bugfix bugzilla: https://gitee.com/src-openeuler/kernel/issues/IBPC6A CVE: CVE-2025-21764 Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?i... -------------------------------- ndisc_alloc_skb() can be called without RTNL or RCU being held. Add RCU protection to avoid possible UAF. Fixes: de09334b9326 ("ndisc: Introduce ndisc_alloc_skb() helper.") Signed-off-by: Eric Dumazet <edumazet@google.com> Reviewed-by: David Ahern <dsahern@kernel.org> Reviewed-by: Kuniyuki Iwashima <kuniyu@amazon.com> Link: https://patch.msgid.link/20250207135841.1948589-3-edumazet@google.com Signed-off-by: Jakub Kicinski <kuba@kernel.org> Signed-off-by: Dong Chenchen <dongchenchen2@huawei.com> --- net/ipv6/ndisc.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c index 14251347c4a5..5134fa7f2888 100644 --- a/net/ipv6/ndisc.c +++ b/net/ipv6/ndisc.c @@ -415,15 +415,11 @@ static struct sk_buff *ndisc_alloc_skb(struct net_device *dev, { int hlen = LL_RESERVED_SPACE(dev); int tlen = dev->needed_tailroom; - struct sock *sk = dev_net(dev)->ipv6.ndisc_sk; struct sk_buff *skb; skb = alloc_skb(hlen + sizeof(struct ipv6hdr) + len + tlen, GFP_ATOMIC); - if (!skb) { - ND_PRINTK(0, err, "ndisc: %s failed to allocate an skb\n", - __func__); + if (!skb) return NULL; - } skb->protocol = htons(ETH_P_IPV6); skb->dev = dev; @@ -434,7 +430,9 @@ static struct sk_buff *ndisc_alloc_skb(struct net_device *dev, /* Manually assign socket ownership as we avoid calling * sock_alloc_send_pskb() to bypass wmem buffer limits */ - skb_set_owner_w(skb, sk); + rcu_read_lock(); + skb_set_owner_w(skb, dev_net_rcu(dev)->ipv6.ndisc_sk); + rcu_read_unlock(); return skb; } -- 2.25.1
participants (2)
-
Dong Chenchen
-
patchwork bot