[LTS 9.2] net RCU: CVE-2025-40170, CVE-2025-40158, CVE-2025-40135, CVE-2025-21765, CVE-2025-21766, CVE-2024-44985, CVE-2024-44986 - #1534
Conversation
jira VULN-160265 cve-pre CVE-2025-40170 commit-author Vadim Fedorenko <vfedorenko@novek.ru> commit 427faee Replace ip6_dst_mtu_forward with ip6_dst_mtu_maybe_forward and reuse this code in ip6_mtu. Actually these two functions were almost duplicates, this change will simplify the maintaince of mtu calculation code. Signed-off-by: Vadim Fedorenko <vfedorenko@novek.ru> Reviewed-by: David Ahern <dsahern@kernel.org> Signed-off-by: David S. Miller <davem@davemloft.net> (cherry picked from commit 427faee) Signed-off-by: Marcin Wcisło <marcin.wcislo@conclusive.pl>
jira VULN-160265 cve-pre CVE-2025-40170 commit-author Vadim Fedorenko <vfedorenko@novek.ru> commit ac6627a Consolidate IPv4 MTU code the same way it is done in IPv6 to have code aligned in both address families Signed-off-by: Vadim Fedorenko <vfedorenko@novek.ru> Reviewed-by: David Ahern <dsahern@kernel.org> Signed-off-by: David S. Miller <davem@davemloft.net> (cherry picked from commit ac6627a) Signed-off-by: Marcin Wcisło <marcin.wcislo@conclusive.pl>
jira VULN-160216 cve-pre CVE-2025-40158 commit-author Yajun Deng <yajun.deng@linux.dev> commit 1e84dc6 Add neigh_confirm() for the confirmed member in struct neighbour, it can be called as an independent unit by other functions. Signed-off-by: Yajun Deng <yajun.deng@linux.dev> Reviewed-by: Eric Dumazet <edumazet@google.com> Signed-off-by: David S. Miller <davem@davemloft.net> (cherry picked from commit 1e84dc6) Signed-off-by: Marcin Wcisło <marcin.wcislo@conclusive.pl>
jira VULN-160216 cve-pre CVE-2025-40158 commit-author Pavel Begunkov <asml.silence@gmail.com> commit 58f71be Throw neigh checks in ip6_finish_output2() under a single slow path if, so we don't have the overhead in the hot path. Signed-off-by: Pavel Begunkov <asml.silence@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net> (cherry picked from commit 58f71be) Signed-off-by: Marcin Wcisło <marcin.wcislo@conclusive.pl>
jira VULN-160216 cve-pre CVE-2025-40158 commit-author Eric Dumazet <edumazet@google.com> commit c486640 rt6_check_neigh() uses read_lock() to protect n->nud_state reading. This seems overkill and causes false sharing. Signed-off-by: Eric Dumazet <edumazet@google.com> Reviewed-by: David Ahern <dsahern@kernel.org> Reviewed-by: Martin KaFai Lau <martin.lau@kernel.org> Signed-off-by: Jakub Kicinski <kuba@kernel.org> (cherry picked from commit c486640) Signed-off-by: Marcin Wcisło <marcin.wcislo@conclusive.pl>
jira VULN-160216 cve-pre CVE-2025-40158 commit-author Eric Dumazet <edumazet@google.com> commit 4c5c496 struct ip6_flowlabel are rcu managed, and call_rcu() is used to delay fl_free_rcu() after RCU grace period. There is no point disabling BH for pure RCU lookups. Signed-off-by: Eric Dumazet <edumazet@google.com> Signed-off-by: Jakub Kicinski <kuba@kernel.org> (cherry picked from commit 4c5c496) Signed-off-by: Marcin Wcisło <marcin.wcislo@conclusive.pl>
jira VULN-160216 cve-pre CVE-2025-40158 commit-author Eric Dumazet <edumazet@google.com> commit 09eed11 upstream-diff Used CentOS 9 backport 8b5b970 which dealt with most of the context conflicts. rcu_bh is no longer a win, especially for objects freed with standard call_rcu(). Switch neighbour code to no longer disable BH when not necessary. Signed-off-by: Eric Dumazet <edumazet@google.com> Signed-off-by: Jakub Kicinski <kuba@kernel.org> (cherry picked from commit 8b5b970) Signed-off-by: Marcin Wcisło <marcin.wcislo@conclusive.pl>
jira VULN-160216 cve-pre CVE-2025-40158 commit-author Eric Dumazet <edumazet@google.com> commit fe602c8 This helper is no longer used in the tree. Signed-off-by: Eric Dumazet <edumazet@google.com> Signed-off-by: Jakub Kicinski <kuba@kernel.org> (cherry picked from commit fe602c8) Signed-off-by: Marcin Wcisło <marcin.wcislo@conclusive.pl>
jira VULN-160216 cve-pre CVE-2025-40158 commit-author Eric Dumazet <edumazet@google.com> commit ef1148d After blamed commit, nexthop_fib6_nh_bh() and nexthop_fib6_nh() are the same. Delete nexthop_fib6_nh_bh(), and convert /proc/net/ipv6_route to standard rcu to avoid this splat: [ 5723.180080] WARNING: suspicious RCU usage [ 5723.180083] ----------------------------- [ 5723.180084] include/net/nexthop.h:516 suspicious rcu_dereference_check() usage! [ 5723.180086] other info that might help us debug this: [ 5723.180087] rcu_scheduler_active = 2, debug_locks = 1 [ 5723.180089] 2 locks held by cat/55856: [ 5723.180091] #0: ffff9440a582afa8 (&p->lock){+.+.}-{3:3}, at: seq_read_iter (fs/seq_file.c:188) [ 5723.180100] ctrliq#1: ffffffffaac07040 (rcu_read_lock_bh){....}-{1:2}, at: rcu_lock_acquire (include/linux/rcupdate.h:326) [ 5723.180109] stack backtrace: [ 5723.180111] CPU: 14 PID: 55856 Comm: cat Tainted: G S I 6.3.0-dbx-DEV ctrliq#528 [ 5723.180115] Call Trace: [ 5723.180117] <TASK> [ 5723.180119] dump_stack_lvl (lib/dump_stack.c:107) [ 5723.180124] dump_stack (lib/dump_stack.c:114) [ 5723.180126] lockdep_rcu_suspicious (include/linux/context_tracking.h:122) [ 5723.180132] ipv6_route_seq_show (include/net/nexthop.h:?) [ 5723.180135] ? ipv6_route_seq_next (net/ipv6/ip6_fib.c:2605) [ 5723.180140] seq_read_iter (fs/seq_file.c:272) [ 5723.180145] seq_read (fs/seq_file.c:163) [ 5723.180151] proc_reg_read (fs/proc/inode.c:316 fs/proc/inode.c:328) [ 5723.180155] vfs_read (fs/read_write.c:468) [ 5723.180160] ? up_read (kernel/locking/rwsem.c:1617) [ 5723.180164] ksys_read (fs/read_write.c:613) [ 5723.180168] __x64_sys_read (fs/read_write.c:621) [ 5723.180170] do_syscall_64 (arch/x86/entry/common.c:?) [ 5723.180174] entry_SYSCALL_64_after_hwframe (arch/x86/entry/entry_64.S:120) [ 5723.180177] RIP: 0033:0x7fa455677d2a Fixes: 09eed11 ("neighbour: switch to standard rcu, instead of rcu_bh") Reported-by: syzbot <syzkaller@googlegroups.com> Signed-off-by: Eric Dumazet <edumazet@google.com> Reviewed-by: David Ahern <dsahern@kernel.org> Link: https://lore.kernel.org/r/20230510154646.370659-1-edumazet@google.com Signed-off-by: Jakub Kicinski <kuba@kernel.org> (cherry picked from commit ef1148d) Signed-off-by: Marcin Wcisło <marcin.wcislo@conclusive.pl>
jira VULN-160265 cve-pre CVE-2025-40170 commit-author Vladislav Efanov <VEfanov@ispras.ru> commit 448a5ce Syzkaller got the following report: BUG: KASAN: use-after-free in sk_setup_caps+0x621/0x690 net/core/sock.c:2018 Read of size 8 at addr ffff888027f82780 by task syz-executor276/3255 The function sk_setup_caps (called by ip6_sk_dst_store_flow-> ip6_dst_store) referenced already freed memory as this memory was freed by parallel task in udpv6_sendmsg->ip6_sk_dst_lookup_flow-> sk_dst_check. task1 (connect) task2 (udp6_sendmsg) sk_setup_caps->sk_dst_set | | sk_dst_check-> | sk_dst_set | dst_release sk_setup_caps references | to already freed dst_entry| The reason for this race condition is: sk_setup_caps() keeps using the dst after transferring the ownership to the dst cache. Found by Linux Verification Center (linuxtesting.org) with syzkaller. Fixes: 1da177e ("Linux-2.6.12-rc2") Signed-off-by: Vladislav Efanov <VEfanov@ispras.ru> Signed-off-by: Paolo Abeni <pabeni@redhat.com> Signed-off-by: David S. Miller <davem@davemloft.net> (cherry picked from commit 448a5ce) Signed-off-by: Marcin Wcisło <marcin.wcislo@conclusive.pl>
jira VULN-160216 cve-pre CVE-2025-40158 commit-author Ido Schimmel <idosch@nvidia.com> commit 2033ab9 Cited commit converted the neighbour code to use the standard RCU variant instead of the RCU-bh variant, but the VRF code still uses rcu_read_lock_bh() / rcu_read_unlock_bh() around the neighbour lookup code in its IPv4 and IPv6 output paths, resulting in lockdep splats [1][2]. Can be reproduced using [3]. Fix by switching to rcu_read_lock() / rcu_read_unlock(). [1] ============================= WARNING: suspicious RCU usage 6.5.0-rc1-custom-g9c099e6dbf98 ctrliq#403 Not tainted ----------------------------- include/net/neighbour.h:302 suspicious rcu_dereference_check() usage! other info that might help us debug this: rcu_scheduler_active = 2, debug_locks = 1 2 locks held by ping/183: #0: ffff888105ea1d80 (sk_lock-AF_INET){+.+.}-{0:0}, at: raw_sendmsg+0xc6c/0x33c0 ctrliq#1: ffffffff85b46820 (rcu_read_lock_bh){....}-{1:2}, at: vrf_output+0x2e3/0x2030 stack backtrace: CPU: 0 PID: 183 Comm: ping Not tainted 6.5.0-rc1-custom-g9c099e6dbf98 ctrliq#403 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.16.2-1.fc37 04/01/2014 Call Trace: <TASK> dump_stack_lvl+0xc1/0xf0 lockdep_rcu_suspicious+0x211/0x3b0 vrf_output+0x1380/0x2030 ip_push_pending_frames+0x125/0x2a0 raw_sendmsg+0x200d/0x33c0 inet_sendmsg+0xa2/0xe0 __sys_sendto+0x2aa/0x420 __x64_sys_sendto+0xe5/0x1c0 do_syscall_64+0x38/0x80 entry_SYSCALL_64_after_hwframe+0x63/0xcd [2] ============================= WARNING: suspicious RCU usage 6.5.0-rc1-custom-g9c099e6dbf98 ctrliq#403 Not tainted ----------------------------- include/net/neighbour.h:302 suspicious rcu_dereference_check() usage! other info that might help us debug this: rcu_scheduler_active = 2, debug_locks = 1 2 locks held by ping6/182: #0: ffff888114b63000 (sk_lock-AF_INET6){+.+.}-{0:0}, at: rawv6_sendmsg+0x1602/0x3e50 ctrliq#1: ffffffff85b46820 (rcu_read_lock_bh){....}-{1:2}, at: vrf_output6+0xe9/0x1310 stack backtrace: CPU: 0 PID: 182 Comm: ping6 Not tainted 6.5.0-rc1-custom-g9c099e6dbf98 ctrliq#403 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.16.2-1.fc37 04/01/2014 Call Trace: <TASK> dump_stack_lvl+0xc1/0xf0 lockdep_rcu_suspicious+0x211/0x3b0 vrf_output6+0xd32/0x1310 ip6_local_out+0xb4/0x1a0 ip6_send_skb+0xbc/0x340 ip6_push_pending_frames+0xe5/0x110 rawv6_sendmsg+0x2e6e/0x3e50 inet_sendmsg+0xa2/0xe0 __sys_sendto+0x2aa/0x420 __x64_sys_sendto+0xe5/0x1c0 do_syscall_64+0x38/0x80 entry_SYSCALL_64_after_hwframe+0x63/0xcd [3] #!/bin/bash ip link add name vrf-red up numtxqueues 2 type vrf table 10 ip link add name swp1 up master vrf-red type dummy ip address add 192.0.2.1/24 dev swp1 ip address add 2001:db8:1::1/64 dev swp1 ip neigh add 192.0.2.2 lladdr 00:11:22:33:44:55 nud perm dev swp1 ip neigh add 2001:db8:1::2 lladdr 00:11:22:33:44:55 nud perm dev swp1 ip vrf exec vrf-red ping 192.0.2.2 -c 1 &> /dev/null ip vrf exec vrf-red ping6 2001:db8:1::2 -c 1 &> /dev/null Fixes: 09eed11 ("neighbour: switch to standard rcu, instead of rcu_bh") Reported-by: Naresh Kamboju <naresh.kamboju@linaro.org> Link: https://lore.kernel.org/netdev/CA+G9fYtEr-=GbcXNDYo3XOkwR+uYgehVoDjsP0pFLUpZ_AZcyg@mail.gmail.com/ Signed-off-by: Ido Schimmel <idosch@nvidia.com> Reviewed-by: David Ahern <dsahern@kernel.org> Reviewed-by: Eric Dumazet <edumazet@google.com> Link: https://lore.kernel.org/r/20230715153605.4068066-1-idosch@nvidia.com Signed-off-by: Paolo Abeni <pabeni@redhat.com> (cherry picked from commit 2033ab9) Signed-off-by: Marcin Wcisło <marcin.wcislo@conclusive.pl>
jira VULN-8330 cve CVE-2024-44986 commit-author Eric Dumazet <edumazet@google.com> commit da273b3 If skb_expand_head() returns NULL, skb has been freed and associated dst/idev could also have been freed. We need to hold rcu_read_lock() to make sure the dst and associated idev are alive. Fixes: 5796015 ("ipv6: allocate enough headroom in ip6_finish_output2()") Signed-off-by: Eric Dumazet <edumazet@google.com> Cc: Vasily Averin <vasily.averin@linux.dev> Reviewed-by: David Ahern <dsahern@kernel.org> Link: https://patch.msgid.link/20240820160859.3786976-3-edumazet@google.com Signed-off-by: Jakub Kicinski <kuba@kernel.org> (cherry picked from commit da273b3) Signed-off-by: Marcin Wcisło <marcin.wcislo@conclusive.pl>
jira VULN-8328 cve CVE-2024-44985 commit-author Eric Dumazet <edumazet@google.com> commit 2d5ff7e If skb_expand_head() returns NULL, skb has been freed and the associated dst/idev could also have been freed. We must use rcu_read_lock() to prevent a possible UAF. Fixes: 0c9f227 ("ipv6: use skb_expand_head in ip6_xmit") Signed-off-by: Eric Dumazet <edumazet@google.com> Cc: Vasily Averin <vasily.averin@linux.dev> Reviewed-by: David Ahern <dsahern@kernel.org> Link: https://patch.msgid.link/20240820160859.3786976-4-edumazet@google.com Signed-off-by: Jakub Kicinski <kuba@kernel.org> (cherry picked from commit 2d5ff7e) Signed-off-by: Marcin Wcisło <marcin.wcislo@conclusive.pl>
jira VULN-160216 cve-pre CVE-2025-40158 commit-author Jiawei Ye <jiawei.ye@foxmail.com> commit fb86c42 In the bpf_out_neigh_v6 function, rcu_read_lock() is used to begin an RCU read-side critical section. However, when unlocking, one branch incorrectly uses a different RCU unlock flavour rcu_read_unlock_bh() instead of rcu_read_unlock(). This mismatch in RCU locking flavours can lead to unexpected behavior and potential concurrency issues. This possible bug was identified using a static analysis tool developed by myself, specifically designed to detect RCU-related issues. This patch corrects the mismatched unlock flavour by replacing the incorrect rcu_read_unlock_bh() with the appropriate rcu_read_unlock(), ensuring that the RCU critical section is properly exited. This change prevents potential synchronization issues and aligns with proper RCU usage patterns. Fixes: 09eed11 ("neighbour: switch to standard rcu, instead of rcu_bh") Signed-off-by: Jiawei Ye <jiawei.ye@foxmail.com> Acked-by: Yonghong Song <yonghong.song@linux.dev> Link: https://lore.kernel.org/r/tencent_CFD3D1C3D68B45EA9F52D8EC76D2C4134306@qq.com Signed-off-by: Martin KaFai Lau <martin.lau@kernel.org> (cherry picked from commit fb86c42) Signed-off-by: Marcin Wcisło <marcin.wcislo@conclusive.pl>
jira VULN-160265 cve-pre CVE-2025-40170 commit-author Eric Dumazet <edumazet@google.com> commit 4693085 ip4_dst_hoplimit() must use RCU protection to make sure the net structure it reads does not disappear. Fixes: fa50d97 ("ipv4: Namespaceify ip_default_ttl sysctl knob") Signed-off-by: Eric Dumazet <edumazet@google.com> Reviewed-by: Kuniyuki Iwashima <kuniyu@amazon.com> Link: https://patch.msgid.link/20250205155120.1676781-3-edumazet@google.com Signed-off-by: Jakub Kicinski <kuba@kernel.org> (cherry picked from commit 4693085) Signed-off-by: Marcin Wcisło <marcin.wcislo@conclusive.pl>
jira VULN-160265 cve-pre CVE-2025-40170 commit-author Eric Dumazet <edumazet@google.com> commit 071d801 upstream-diff Used CentOS 9 backport 4ea98f0 which dealt with the context conflicts. ip_dst_mtu_maybe_forward() must use RCU protection to make sure the net structure it reads does not disappear. Fixes: f87c10a ("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> (cherry picked from commit 4ea98f0) Signed-off-by: Marcin Wcisło <marcin.wcislo@conclusive.pl>
jira VULN-54043 cve CVE-2025-21766 commit-author Eric Dumazet <edumazet@google.com> commit 1395121 upstream-diff Used CentOS 9 backport fd7e9d2 for the clean pick. The modified function `__ip_rt_update_pmtu' is identicial in LTS 9.2 and CentOS 9. __ip_rt_update_pmtu() must use RCU protection to make sure the net structure it reads does not disappear. Fixes: 2fbc6e8 ("ipv4: Update exception handling for multipath routes via same device") Fixes: 1de6b15 ("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> (cherry picked from commit fd7e9d2) Signed-off-by: Marcin Wcisło <marcin.wcislo@conclusive.pl>
jira VULN-53991 cve CVE-2025-21765 commit-author Eric Dumazet <edumazet@google.com> commit 3c8ffcd ip6_default_advmss() needs rcu protection to make sure the net structure it reads does not disappear. Fixes: 5578689 ("[NETNS][IPV6] route6 - make route6 per namespace") Signed-off-by: Eric Dumazet <edumazet@google.com> Reviewed-by: Kuniyuki Iwashima <kuniyu@amazon.com> Link: https://patch.msgid.link/20250205155120.1676781-11-edumazet@google.com Signed-off-by: Jakub Kicinski <kuba@kernel.org> (cherry picked from commit 3c8ffcd) Signed-off-by: Marcin Wcisło <marcin.wcislo@conclusive.pl>
jira VULN-160265 cve-pre CVE-2025-40170 commit-author Eric Dumazet <edumazet@google.com> commit 88fe142 upstream-diff | net/core/dst.c Resolved context conflicts in `dst_dev_put' function. (Missing commits: f1c5fd3, 2dce8c5, d62607c) net/core/sock.c - Changes to `sk_dst_gso_max_size()' omitted, because `dst' paramater not present in the function (introduced in the non-backported b1a78b9 ("net: add support for ipv4 big tcp")). - In function `sk_setup_caps()', the `dst->dev' to `dst_dev(dst)' conversion applied also in the `sk->sk_gso_max_size' assignment. (Ine the upstream this is delegated to the aforementioned `sk_dst_gso_max_size()' function.) 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: 4a6ce2b ("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> (cherry picked from commit 88fe142) Signed-off-by: Marcin Wcisło <marcin.wcislo@conclusive.pl>
jira VULN-160160 cve-pre CVE-2025-40135 commit-author Sharath Chandra Vurukala <quic_sharathv@quicinc.com> commit 1dbf1d5 upstream-diff Resolved context conflicts in `ip_output()' due to missing a74fc62 ("ipv4: adopt dst_dev, skb_dst_dev and skb_dst_dev_net[_rcu]") In ip_output() skb->dev is updated from the skb_dst(skb)->dev this can become invalid when the interface is unregistered and freed, Introduced new skb_dst_dev_rcu() function to be used instead of skb_dst_dev() within rcu_locks in ip_output.This will ensure that all the skb's associated with the dev being deregistered will be transnmitted out first, before freeing the dev. Given that ip_output() is called within an rcu_read_lock() critical section or from a bottom-half context, it is safe to introduce an RCU read-side critical section within it. Multiple panic call stacks were observed when UL traffic was run in concurrency with device deregistration from different functions, pasting one sample for reference. [496733.627565][T13385] Call trace: [496733.627570][T13385] bpf_prog_ce7c9180c3b128ea_cgroupskb_egres+0x24c/0x7f0 [496733.627581][T13385] __cgroup_bpf_run_filter_skb+0x128/0x498 [496733.627595][T13385] ip_finish_output+0xa4/0xf4 [496733.627605][T13385] ip_output+0x100/0x1a0 [496733.627613][T13385] ip_send_skb+0x68/0x100 [496733.627618][T13385] udp_send_skb+0x1c4/0x384 [496733.627625][T13385] udp_sendmsg+0x7b0/0x898 [496733.627631][T13385] inet_sendmsg+0x5c/0x7c [496733.627639][T13385] __sys_sendto+0x174/0x1e4 [496733.627647][T13385] __arm64_sys_sendto+0x28/0x3c [496733.627653][T13385] invoke_syscall+0x58/0x11c [496733.627662][T13385] el0_svc_common+0x88/0xf4 [496733.627669][T13385] do_el0_svc+0x2c/0xb0 [496733.627676][T13385] el0_svc+0x2c/0xa4 [496733.627683][T13385] el0t_64_sync_handler+0x68/0xb4 [496733.627689][T13385] el0t_64_sync+0x1a4/0x1a8 Changes in v3: - Replaced WARN_ON() with WARN_ON_ONCE(), as suggested by Willem de Bruijn. - Dropped legacy lines mistakenly pulled in from an outdated branch. Changes in v2: - Addressed review comments from Eric Dumazet - Used READ_ONCE() to prevent potential load/store tearing - Added skb_dst_dev_rcu() and used along with rcu_read_lock() in ip_output Signed-off-by: Sharath Chandra Vurukala <quic_sharathv@quicinc.com> Reviewed-by: Eric Dumazet <edumazet@google.com> Link: https://patch.msgid.link/20250730105118.GA26100@hu-sharathv-hyd.qualcomm.com Signed-off-by: Jakub Kicinski <kuba@kernel.org> (cherry picked from commit 1dbf1d5) Signed-off-by: Marcin Wcisło <marcin.wcislo@conclusive.pl>
jira VULN-160265 cve-pre CVE-2025-40170 commit-author Eric Dumazet <edumazet@google.com> commit caedcc5 upstream-diff Used CentOS 9 backport ca6810f as a clean cherry-pick base. - Used RH_KABI_REPLACE in `struct dst_entry' to silence the kABI checker. Originally the `struct net_device *dev' field was changed into a union of `struct net_device *dev' and `struct net_device __rcu *dev_rcu'. The latter has the same size and alignment as the former (this is actually checked statically by the RH_KABI_REPLACE macro), with the `__rcu' annotation serving only at compile time and being invisible to the binary output. The `dev_rcu' is therefore just an alias for the `dev' field. - Omitted changes to the `ipv4_default_advmss()' function because no `dst->dev' is being referenced there in LTS 9.2 (and CentOS 9). The `ip_rt_min_advmss' parameter was made dev-specific in commit 2e9589f ("ipv4: Namespaceify min_adv_mss sysctl knob"). - Resolved context conflicts in `dst_dev_put()' due to missing d62607c ("net: rename reference+tracking helpers") Followup of commit 88fe142 ("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: 4a6ce2b ("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> (cherry picked from commit ca6810f) Signed-off-by: Marcin Wcisło <marcin.wcislo@conclusive.pl>
jira VULN-160160 cve CVE-2025-40135 commit-author Eric Dumazet <edumazet@google.com> commit 9085e56 upstream-diff Used CentOS 9 backport f37f7b3 for a clean pick. It deals already with the similarly non-backported commit 1caf272 ("ipv6: adopt dst_dev() helper"). Use RCU in ip6_xmit() in order to use dst_dev_rcu() to prevent possible UAF. Fixes: 4a6ce2b ("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-4-edumazet@google.com Signed-off-by: Jakub Kicinski <kuba@kernel.org> (cherry picked from commit f37f7b3) Signed-off-by: Marcin Wcisło <marcin.wcislo@conclusive.pl>
jira VULN-160216 cve CVE-2025-40158 commit-author Eric Dumazet <edumazet@google.com> commit 1170957 upstream-diff Used CentOS 9 backport 9b21011 as the base. It deals with the similarly non-backported commits 1caf272 and 93d1cff. Resolved some context conflicts in `ip6_finish_output2()'. Use RCU in ip6_output() in order to use dst_dev_rcu() to prevent possible UAF. We can remove rcu_read_lock()/rcu_read_unlock() pairs from ip6_finish_output2(). Fixes: 4a6ce2b ("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-5-edumazet@google.com Signed-off-by: Jakub Kicinski <kuba@kernel.org> (cherry picked from commit 9b21011) Signed-off-by: Marcin Wcisło <marcin.wcislo@conclusive.pl>
jira VULN-160265 cve CVE-2025-40170 commit-author Eric Dumazet <edumazet@google.com> commit 99a2ace upstream-diff Used CentOS 9 backport acc5b1b as the base. It dealt already with the missing commits: - a74fc62 ("ipv4: adopt dst_dev, skb_dst_dev and skb_dst_dev_net[_rcu]") - 1caf272 ("ipv6: adopt dst_dev() helper") Additionally, in net/core/sock.c: - Omitted changes to the `sk_trim_gso_size()' function (`sk_dst_gso_max_size()' in the upstream), because `dst->dev' is not used there (introduced in 5a01b46 ("net: add support for ipv4 big tcp")). - In `sk_setup_caps()', instead of changing the last argument of the nonexistent `sk_dst_gso_max_size()' call from `dst' to `dev' a `dst_dev(dst)' to `dev' substitution was made similarly to how it was done 4 lines later. 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: 4a6ce2b ("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> (cherry picked from commit acc5b1b) Signed-off-by: Marcin Wcisło <marcin.wcislo@conclusive.pl>
139de76 to
4bcf01b
Compare
|
🤖 Validation Checks In Progress Workflow run: https://github.com/ctrliq/kernel-src-tree/actions/runs/32178826591 |
🔍 Interdiff Analysis
================================================================================
* CONTEXT DIFFERENCES - surrounding code differences between the patches *
================================================================================
--- b/include/net/ip.h
+++ b/include/net/ip.h
@@ -436,7 +436,7 @@
struct net *net = dev_net(dst->dev);
unsigned int mtu;
- if (READ_ONCE(net->ipv4.sysctl_ip_fwd_use_pmtu) ||
+ if (net->ipv4.sysctl_ip_fwd_use_pmtu ||
ip_mtu_locked(dst) ||
!forwarding)
return dst_mtu(dst);
================================================================================
* DELTA DIFFERENCES - code changes that differ between the patches *
================================================================================
--- b/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -1017,7 +1017,7 @@
unsigned int hash = inet6_addr_hash(dev_net(dev), &ifa->addr);
int err = 0;
- spin_lock_bh(&addrconf_hash_lock);
+ spin_lock(&addrconf_hash_lock);
/* Ignore adding duplicate addresses on an interface */
if (ipv6_chk_same_addr(dev_net(dev), &ifa->addr, dev, hash)) {
@@ -1027,7 +1027,7 @@
hlist_add_head_rcu(&ifa->addr_lst, &inet6_addr_lst[hash]);
}
- spin_unlock_bh(&addrconf_hash_lock);
+ spin_unlock(&addrconf_hash_lock);
return err;
}
################################################################################
! REJECTED PATCH2 HUNKS - could not be compared; manual review needed !
################################################################################
--- b/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -1034,7 +1034,7 @@
unsigned int hash = inet6_addr_hash(net, &ifa->addr);
int err = 0;
- spin_lock(&net->ipv6.addrconf_hash_lock);
+ spin_lock_bh(&net->ipv6.addrconf_hash_lock);
/* Ignore adding duplicate addresses on an interface */
if (ipv6_chk_same_addr(net, &ifa->addr, dev, hash)) {
@@ -1044,7 +1044,7 @@
hlist_add_head_rcu(&ifa->addr_lst, &net->ipv6.inet6_addr_lst[hash]);
}
- spin_unlock(&net->ipv6.addrconf_hash_lock);
+ spin_unlock_bh(&net->ipv6.addrconf_hash_lock);
return err;
}
--- b/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -1154,7 +1154,7 @@
n = __ipv6_neigh_lookup_noref(rt->dst.dev,
rt6_nexthop(rt, &fl6->daddr));
err = n && !(READ_ONCE(n->nud_state) & NUD_VALID) ? -EINVAL : 0;
- rcu_read_unlock_bh();
+ rcu_read_unlock();
if (err) {
struct inet6_ifaddr *ifp;
================================================================================
* CONTEXT DIFFERENCES - surrounding code differences between the patches *
================================================================================
--- b/net/core/neighbour.c
+++ b/net/core/neighbour.c
@@ -3055,4 +3198,4 @@
- if (n->nud_state & ~NUD_NOARP)
+ if (READ_ONCE(n->nud_state) & ~NUD_NOARP)
break;
next:
n = rcu_dereference_bh(n->next);
@@ -3097,4 +3240,4 @@
- if (n->nud_state & ~NUD_NOARP)
+ if (READ_ONCE(n->nud_state) & ~NUD_NOARP)
break;
next:
n = rcu_dereference_bh(n->next);
--- b/net/ipv4/fib_semantics.c
+++ b/net/ipv4/fib_semantics.c
@@ -2222,5 +2202,5 @@
if (n)
- state = n->nud_state;
+ state = READ_ONCE(n->nud_state);
rcu_read_unlock_bh();
}
--- b/net/ipv4/nexthop.c
+++ b/net/ipv4/nexthop.c
@@ -1128,7 +1128,7 @@
n = __ipv6_neigh_lookup_noref_stub(nh->fib_nh_dev, &nh->fib_nh_gw6);
if (n)
- state = n->nud_state;
+ state = READ_ONCE(n->nud_state);
rcu_read_unlock_bh();
@@ -1145,7 +1145,7 @@
n = __ipv4_neigh_lookup_noref(nh->fib_nh_dev,
(__force u32)nh->fib_nh_gw4);
if (n)
- state = n->nud_state;
+ state = READ_ONCE(n->nud_state);
rcu_read_unlock_bh();
--- b/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -1014,5 +1015,5 @@
int err = 0;
- spin_lock(&addrconf_hash_lock);
+ spin_lock(&net->ipv6.addrconf_hash_lock);
/* Ignore adding duplicate addresses on an interface */
@@ -1020,7 +1020,8 @@
- hlist_add_head_rcu(&ifa->addr_lst, &inet6_addr_lst[hash]);
+ if (ipv6_chk_same_addr(net, &ifa->addr, dev, hash)) {
+ hlist_add_head_rcu(&ifa->addr_lst, &net->ipv6.inet6_addr_lst[hash]);
}
- spin_unlock(&addrconf_hash_lock);
+ spin_unlock(&net->ipv6.addrconf_hash_lock);
return err;
}
--- b/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -1150,7 +1150,7 @@
rcu_read_lock_bh();
n = __ipv6_neigh_lookup_noref(rt->dst.dev,
rt6_nexthop(rt, &fl6->daddr));
- err = n && !(n->nud_state & NUD_VALID) ? -EINVAL : 0;
+ err = n && !(READ_ONCE(n->nud_state) & NUD_VALID) ? -EINVAL : 0;
rcu_read_unlock_bh();
if (err) {
--- b/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -635,4 +634,5 @@
+ neigh = __ipv6_neigh_lookup_noref(dev, nh_gw);
- if (neigh->nud_state & NUD_VALID)
+ if (READ_ONCE(neigh->nud_state) & NUD_VALID)
goto out;
write_lock(&neigh->lock);
################################################################################
! REJECTED PATCH2 HUNKS - could not be compared; manual review needed !
################################################################################
--- b/include/net/ip.h
+++ b/include/net/ip.h
@@ -471,8 +471,10 @@
bool forwarding)
{
const struct rtable *rt = dst_rtable(dst);
- struct net *net = dev_net(dst->dev);
- unsigned int mtu;
+ unsigned int mtu, res;
+ struct net *net;
+
+ rcu_read_lock();
if (READ_ONCE(net->ipv4.sysctl_ip_fwd_use_pmtu) ||
ip_mtu_locked(dst) ||
================================================================================
* CONTEXT DIFFERENCES - surrounding code differences between the patches *
================================================================================
--- b/include/net/ip.h
+++ b/include/net/ip.h
@@ -438,6 +438,6 @@
bool forwarding)
{
- const struct rtable *rt = container_of(dst, struct rtable, dst);
+ const struct rtable *rt = dst_rtable(dst);
struct net *net = dev_net(dst->dev);
unsigned int mtu;
################################################################################
! REJECTED PATCH2 HUNKS - could not be compared; manual review needed !
################################################################################
--- b/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -1020,6 +1020,8 @@
if (old_mtu < mtu)
return;
+ rcu_read_lock();
+ net = dev_net_rcu(dst->dev);
if (mtu < net->ipv4.ip_rt_min_pmtu) {
lock = true;
mtu = min(old_mtu, net->ipv4.ip_rt_min_pmtu);
@@ -1027,7 +1029,7 @@
if (rt->rt_pmtu == mtu && !lock &&
time_before(jiffies, dst->expires - net->ipv4.ip_rt_mtu_expires / 2))
- return;
+ goto out;
rcu_read_lock();
if (fib_lookup(net, fl4, &res, 0) == 0) {
@@ -1042,8 +1043,7 @@
update_or_create_fnhe(nhc, fl4->daddr, 0, mtu, lock,
jiffies + net->ipv4.ip_rt_mtu_expires);
}
- rcu_read_unlock();
- return;
+ goto out;
}
#endif /* CONFIG_IP_ROUTE_MULTIPATH */
nhc = FIB_RES_NHC(res);
================================================================================
* CONTEXT DIFFERENCES - surrounding code differences between the patches *
================================================================================
--- b/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -1034,6 +1020,6 @@
if (old_mtu < mtu)
return;
- if (mtu < ip_rt_min_pmtu) {
+ if (mtu < net->ipv4.ip_rt_min_pmtu) {
lock = true;
- mtu = min(old_mtu, ip_rt_min_pmtu);
+ mtu = min(old_mtu, net->ipv4.ip_rt_min_pmtu);
@@ -1040,6 +1026,6 @@
if (rt->rt_pmtu == mtu && !lock &&
- time_before(jiffies, dst->expires - ip_rt_mtu_expires / 2))
+ time_before(jiffies, dst->expires - net->ipv4.ip_rt_mtu_expires / 2))
return;
rcu_read_lock();
@@ -1049,5 +1043,5 @@
update_or_create_fnhe(nhc, fl4->daddr, 0, mtu, lock,
- jiffies + ip_rt_mtu_expires);
+ jiffies + net->ipv4.ip_rt_mtu_expires);
}
rcu_read_unlock();
}
================================================================================
* DELTA DIFFERENCES - code changes that differ between the patches *
================================================================================
--- b/net/core/sock.c
+++ b/net/core/sock.c
@@ -2298,7 +2298,7 @@
} else {
sk->sk_route_caps |= NETIF_F_SG | NETIF_F_HW_CSUM;
/* pairs with the WRITE_ONCE() in netif_set_gso_max_size() */
- sk->sk_gso_max_size = READ_ONCE(dst_dev(dst)->gso_max_size);
+ sk->sk_gso_max_size = READ_ONCE(dst->dev->gso_max_size);
sk_trim_gso_size(sk);
sk->sk_gso_max_size -= (MAX_TCP_HEADER + 1);
/* pairs with the WRITE_ONCE() in netif_set_gso_max_segs() */
################################################################################
! REJECTED PATCH2 HUNKS - could not be compared; manual review needed !
################################################################################
--- b/net/core/dst.c
+++ b/net/core/dst.c
@@ -150,7 +150,7 @@
dst->ops->ifdown(dst, dev);
WRITE_ONCE(dst->input, dst_discard);
WRITE_ONCE(dst->output, dst_discard_out);
- dst->dev = blackhole_netdev;
+ WRITE_ONCE(dst->dev, blackhole_netdev);
netdev_ref_replace(dev, blackhole_netdev, &dst->dev_tracker,
GFP_ATOMIC);
}
--- b/net/core/sock.c
+++ b/net/core/sock.c
@@ -2588,8 +2588,8 @@
!ipv6_addr_v4mapped(&sk->sk_v6_rcv_saddr));
#endif
/* pairs with the WRITE_ONCE() in netif_set_gso(_ipv4)_max_size() */
- max_size = is_ipv6 ? READ_ONCE(dst->dev->gso_max_size) :
- READ_ONCE(dst->dev->gso_ipv4_max_size);
+ max_size = is_ipv6 ? READ_ONCE(dst_dev(dst)->gso_max_size) :
+ READ_ONCE(dst_dev(dst)->gso_ipv4_max_size);
if (max_size > GSO_LEGACY_MAX_SIZE && !sk_is_tcp(sk))
max_size = GSO_LEGACY_MAX_SIZE;
@@ -2600,7 +2600,7 @@
{
u32 max_segs = 1;
- sk->sk_route_caps = dst->dev->features;
+ sk->sk_route_caps = dst_dev(dst)->features;
if (sk_is_tcp(sk)) {
struct inet_connection_sock *icsk = inet_csk(sk);
================================================================================
* CONTEXT DIFFERENCES - surrounding code differences between the patches *
================================================================================
--- b/net/core/dst.c
+++ b/net/core/dst.c
@@ -147,7 +147,7 @@
- dst->ops->ifdown(dst, dev, true);
- dst->input = dst_discard;
- dst->output = dst_discard_out;
+ dst->ops->ifdown(dst, dev);
+ WRITE_ONCE(dst->input, dst_discard);
+ WRITE_ONCE(dst->output, dst_discard_out);
dst->dev = blackhole_netdev;
- dev_replace_track(dev, blackhole_netdev, &dst->dev_tracker,
- GFP_ATOMIC);
+ netdev_ref_replace(dev, blackhole_netdev, &dst->dev_tracker,
+ GFP_ATOMIC);
}
--- b/net/core/sock.c
+++ b/net/core/sock.c
@@ -2282,7 +2290,7 @@
{
u32 max_segs = 1;
sk->sk_route_caps = dst->dev->features;
- if (sk_is_tcp(sk))
- sk->sk_route_caps |= NETIF_F_GSO;
- if (sk->sk_route_caps & NETIF_F_GSO)
+ if (sk_is_tcp(sk)) {
+ struct inet_connection_sock *icsk = inet_csk(sk);
+
@@ -2290,8 +2297,5 @@
sk->sk_route_caps |= NETIF_F_SG | NETIF_F_HW_CSUM;
- /* pairs with the WRITE_ONCE() in netif_set_gso_max_size() */
- sk->sk_gso_max_size = READ_ONCE(dst->dev->gso_max_size);
- sk_trim_gso_size(sk);
- sk->sk_gso_max_size -= (MAX_TCP_HEADER + 1);
+ sk->sk_gso_max_size = sk_dst_gso_max_size(sk, dst);
/* pairs with the WRITE_ONCE() in netif_set_gso_max_segs() */
max_segs = max_t(u32, READ_ONCE(dst->dev->gso_max_segs), 1);
}
================================================================================
* DELTA DIFFERENCES - code changes that differ between the patches *
================================================================================
--- b/net/ipv4/ip_output.c
+++ b/net/ipv4/ip_output.c
@@ -420,8 +420,7 @@
int ip_output(struct net *net, struct sock *sk, struct sk_buff *skb)
{
- struct net_device *dev, *indev = skb->dev;
- int ret_val;
+ struct net_device *dev = skb_dst(skb)->dev, *indev = skb->dev;
IP_UPD_PO_STATS(net, IPSTATS_MIB_OUT, skb->len);
################################################################################
! REJECTED PATCH2 HUNKS - could not be compared; manual review needed !
################################################################################
--- b/net/ipv4/ip_output.c
+++ b/net/ipv4/ip_output.c
@@ -425,7 +425,8 @@
int ip_output(struct net *net, struct sock *sk, struct sk_buff *skb)
{
- struct net_device *dev = skb_dst_dev(skb), *indev = skb->dev;
+ struct net_device *dev, *indev = skb->dev;
+ int ret_val;
skb->dev = dev;
skb->protocol = htons(ETH_P_IP);
================================================================================
* CONTEXT DIFFERENCES - surrounding code differences between the patches *
================================================================================
--- b/net/ipv4/ip_output.c
+++ b/net/ipv4/ip_output.c
@@ -417,9 +417,7 @@
int ip_output(struct net *net, struct sock *sk, struct sk_buff *skb)
{
- struct net_device *dev = skb_dst(skb)->dev, *indev = skb->dev;
-
- IP_UPD_PO_STATS(net, IPSTATS_MIB_OUT, skb->len);
+ struct net_device *dev = skb_dst_dev(skb), *indev = skb->dev;
skb->dev = dev;
skb->protocol = htons(ETH_P_IP);
================================================================================
* DELTA DIFFERENCES - code changes that differ between the patches *
================================================================================
--- b/include/net/dst.h
+++ b/include/net/dst.h
@@ -23,12 +23,10 @@
struct sk_buff;
struct dst_entry {
- RH_KABI_REPLACE(
- struct net_device *dev,
- union {
- struct net_device *dev;
- struct net_device __rcu *dev_rcu;
- })
+ union {
+ struct net_device *dev;
+ struct net_device __rcu *dev_rcu;
+ };
struct dst_ops *ops;
unsigned long _metrics;
unsigned long expires;
--- b/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -1035,7 +1035,7 @@
return;
rcu_read_lock();
- net = dst_dev_net_rcu(dst);
+ net = dev_net_rcu(dst->dev);
if (mtu < ip_rt_min_pmtu) {
lock = true;
mtu = min(old_mtu, ip_rt_min_pmtu);
################################################################################
! REJECTED PATCH2 HUNKS - could not be compared; manual review needed !
################################################################################
--- b/net/core/dst.c
+++ b/net/core/dst.c
@@ -150,7 +150,7 @@
dst->ops->ifdown(dst, dev);
WRITE_ONCE(dst->input, dst_discard);
WRITE_ONCE(dst->output, 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);
}
--- b/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -1027,7 +1027,7 @@
return;
rcu_read_lock();
- net = dev_net_rcu(dst_dev(dst));
+ net = dst_dev_net_rcu(dst);
if (mtu < net->ipv4.ip_rt_min_pmtu) {
lock = true;
mtu = min(old_mtu, net->ipv4.ip_rt_min_pmtu);
@@ -1327,7 +1327,7 @@
struct net *net;
rcu_read_lock();
- net = dev_net_rcu(dst_dev(dst));
+ net = dst_dev_net_rcu(dst);
advmss = max_t(unsigned int, ipv4_mtu(dst) - header_size,
net->ipv4.ip_rt_min_advmss);
rcu_read_unlock();
================================================================================
* CONTEXT DIFFERENCES - surrounding code differences between the patches *
================================================================================
--- b/net/core/dst.c
+++ b/net/core/dst.c
@@ -147,7 +147,7 @@
- dst->ops->ifdown(dst, dev, true);
- dst->input = dst_discard;
- dst->output = dst_discard_out;
+ dst->ops->ifdown(dst, dev);
+ WRITE_ONCE(dst->input, dst_discard);
+ WRITE_ONCE(dst->output, dst_discard_out);
WRITE_ONCE(dst->dev, blackhole_netdev);
- dev_replace_track(dev, blackhole_netdev, &dst->dev_tracker,
- GFP_ATOMIC);
+ netdev_ref_replace(dev, blackhole_netdev, &dst->dev_tracker,
+ GFP_ATOMIC);
}
--- b/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -1032,6 +1040,6 @@
rcu_read_lock();
- net = dev_net_rcu(dst->dev);
- if (mtu < ip_rt_min_pmtu) {
- lock = true;
- mtu = min(old_mtu, ip_rt_min_pmtu);
+ net = dev_net_rcu(dst_dev(dst));
+ advmss = max_t(unsigned int, ipv4_mtu(dst) - header_size,
+ net->ipv4.ip_rt_min_advmss);
+ rcu_read_unlock();
================================================================================
* DELTA DIFFERENCES - code changes that differ between the patches *
================================================================================
--- b/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -256,6 +256,7 @@
const struct ipv6_pinfo *np = inet6_sk(sk);
struct in6_addr *first_hop = &fl6->daddr;
struct dst_entry *dst = skb_dst(skb);
+ struct net_device *dev = dst->dev;
struct inet6_dev *idev = ip6_dst_idev(dst);
struct hop_jumbo_hdr *hop_jumbo;
int hoplen = sizeof(*hop_jumbo);
################################################################################
! REJECTED PATCH2 HUNKS - could not be compared; manual review needed !
################################################################################
--- b/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -271,7 +270,6 @@
const struct ipv6_pinfo *np = inet6_sk(sk);
struct in6_addr *first_hop = &fl6->daddr;
struct dst_entry *dst = skb_dst(skb);
- struct net_device *dev = dst_dev(dst);
struct inet6_dev *idev = ip6_dst_idev(dst);
struct hop_jumbo_hdr *hop_jumbo;
int hoplen = sizeof(*hop_jumbo);
================================================================================
* CONTEXT DIFFERENCES - surrounding code differences between the patches *
================================================================================
--- b/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -257,7 +272,7 @@
const struct ipv6_pinfo *np = inet6_sk(sk);
struct in6_addr *first_hop = &fl6->daddr;
struct dst_entry *dst = skb_dst(skb);
- struct net_device *dev = dst->dev;
+ struct net_device *dev = dst_dev(dst);
struct inet6_dev *idev = ip6_dst_idev(dst);
struct hop_jumbo_hdr *hop_jumbo;
int hoplen = sizeof(*hop_jumbo);
================================================================================
* DELTA DIFFERENCES - code changes that differ between the patches *
================================================================================
--- b/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -59,7 +59,7 @@
static int ip6_finish_output2(struct net *net, struct sock *sk, struct sk_buff *skb)
{
struct dst_entry *dst = skb_dst(skb);
- struct net_device *dev = dst_dev_rcu(dst);
+ struct net_device *dev = dst->dev;
struct inet6_dev *idev = ip6_dst_idev(dst);
unsigned int hh_len = LL_RESERVED_SPACE(dev);
const struct in6_addr *daddr, *nexthop;
@@ -211,10 +212,8 @@
int ip6_output(struct net *net, struct sock *sk, struct sk_buff *skb)
{
- struct dst_entry *dst = skb_dst(skb);
- struct net_device *dev, *indev = skb->dev;
- struct inet6_dev *idev;
- int ret;
+ struct net_device *dev = skb_dst(skb)->dev, *indev = skb->dev;
+ struct inet6_dev *idev = ip6_dst_idev(skb_dst(skb));
skb->protocol = htons(ETH_P_IPV6);
rcu_read_lock();
################################################################################
! REJECTED PATCH2 HUNKS - could not be compared; manual review needed !
################################################################################
--- b/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -60,7 +60,7 @@
static int ip6_finish_output2(struct net *net, struct sock *sk, struct sk_buff *skb)
{
struct dst_entry *dst = skb_dst(skb);
- struct net_device *dev = dst_dev(dst);
+ struct net_device *dev = dst_dev_rcu(dst);
struct inet6_dev *idev = ip6_dst_idev(dst);
unsigned int hh_len = LL_RESERVED_SPACE(dev);
const struct in6_addr *daddr, *nexthop;
@@ -120,7 +117,6 @@
IP6_UPD_PO_STATS(net, idev, IPSTATS_MIB_OUT, skb->len);
- rcu_read_lock();
nexthop = rt6_nexthop(dst_rt6_info(dst), daddr);
neigh = __ipv6_neigh_lookup_noref(dev, nexthop);
@@ -228,8 +222,9 @@
int ip6_output(struct net *net, struct sock *sk, struct sk_buff *skb)
{
struct dst_entry *dst = skb_dst(skb);
- struct net_device *dev = dst_dev(dst), *indev = skb->dev;
- struct inet6_dev *idev = ip6_dst_idev(dst);
+ struct net_device *dev, *indev = skb->dev;
+ struct inet6_dev *idev;
+ int ret;
skb->protocol = htons(ETH_P_IPV6);
skb->dev = dev;
================================================================================
* CONTEXT DIFFERENCES - surrounding code differences between the patches *
================================================================================
--- b/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -56,7 +56,7 @@
static int ip6_finish_output2(struct net *net, struct sock *sk, struct sk_buff *skb)
{
struct dst_entry *dst = skb_dst(skb);
- struct net_device *dev = dst->dev;
+ struct net_device *dev = dst_dev(dst);
struct inet6_dev *idev = ip6_dst_idev(dst);
unsigned int hh_len = LL_RESERVED_SPACE(dev);
const struct in6_addr *daddr, *nexthop;
@@ -117,7 +115,7 @@
- return res;
- }
+
+ IP6_UPD_PO_STATS(net, idev, IPSTATS_MIB_OUT, skb->len);
rcu_read_lock();
- nexthop = rt6_nexthop((struct rt6_info *)dst, daddr);
+ nexthop = rt6_nexthop(dst_rt6_info(dst), daddr);
neigh = __ipv6_neigh_lookup_noref(dev, nexthop);
@@ -214,12 +215,13 @@
int ip6_output(struct net *net, struct sock *sk, struct sk_buff *skb)
{
- struct net_device *dev = skb_dst(skb)->dev, *indev = skb->dev;
- struct inet6_dev *idev = ip6_dst_idev(skb_dst(skb));
+ struct dst_entry *dst = skb_dst(skb);
+ struct net_device *dev = dst_dev(dst), *indev = skb->dev;
+ struct inet6_dev *idev = ip6_dst_idev(dst);
skb->protocol = htons(ETH_P_IPV6);
skb->dev = dev;
- if (unlikely(idev->cnf.disable_ipv6)) {
+ if (unlikely(!idev || READ_ONCE(idev->cnf.disable_ipv6))) {
IP6_INC_STATS(net, idev, IPSTATS_MIB_OUTDISCARDS);
kfree_skb_reason(skb, SKB_DROP_REASON_IPV6DISABLED);
return 0;
================================================================================
* DELTA DIFFERENCES - code changes that differ between the patches *
================================================================================
--- b/include/net/ip.h
+++ b/include/net/ip.h
@@ -441,14 +441,12 @@
bool forwarding)
{
const struct rtable *rt = container_of(dst, struct rtable, dst);
- const struct net_device *dev;
unsigned int mtu, res;
struct net *net;
rcu_read_lock();
- dev = dst_dev_rcu(dst);
- net = dev_net_rcu(dev);
+ net = dev_net_rcu(dst->dev);
if (READ_ONCE(net->ipv4.sysctl_ip_fwd_use_pmtu) ||
ip_mtu_locked(dst) ||
!forwarding) {
@@ -462,7 +460,7 @@
if (mtu)
goto out;
- mtu = READ_ONCE(dev->mtu);
+ mtu = READ_ONCE(dst->dev->mtu);
if (unlikely(ip_mtu_locked(dst))) {
if (rt->rt_uses_gateway && mtu > 576)
--- b/include/net/ip6_route.h
+++ b/include/net/ip6_route.h
@@ -330,7 +330,7 @@
mtu = IPV6_MIN_MTU;
rcu_read_lock();
- idev = __in6_dev_get(dst_dev_rcu(dst));
+ idev = __in6_dev_get(dst->dev);
if (idev)
mtu = idev->cnf.mtu6;
rcu_read_unlock();
--- b/include/net/route.h
+++ b/include/net/route.h
@@ -363,7 +363,7 @@
const struct net *net;
rcu_read_lock();
- net = dst_dev_net_rcu(dst);
+ net = dev_net_rcu(dst->dev);
hoplimit = READ_ONCE(net->ipv4.sysctl_ip_default_ttl);
rcu_read_unlock();
}
--- b/net/core/sock.c
+++ b/net/core/sock.c
@@ -2301,7 +2299,7 @@
} else {
sk->sk_route_caps |= NETIF_F_SG | NETIF_F_HW_CSUM;
/* pairs with the WRITE_ONCE() in netif_set_gso_max_size() */
- sk->sk_gso_max_size = READ_ONCE(dev->gso_max_size);
+ sk->sk_gso_max_size = READ_ONCE(dst_dev(dst)->gso_max_size);
sk_trim_gso_size(sk);
sk->sk_gso_max_size -= (MAX_TCP_HEADER + 1);
/* pairs with the WRITE_ONCE() in netif_set_gso_max_segs() */
################################################################################
! REJECTED PATCH2 HUNKS - could not be compared; manual review needed !
################################################################################
--- b/include/net/ip.h
+++ b/include/net/ip.h
@@ -467,6 +467,7 @@
bool forwarding)
{
const struct rtable *rt = dst_rtable(dst);
+ const struct net_device *dev;
unsigned int mtu, res;
struct net *net;
@@ -470,7 +471,8 @@
rcu_read_lock();
- net = dev_net_rcu(dst_dev(dst));
+ 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) {
@@ -486,7 +488,7 @@
if (mtu)
goto out;
- mtu = READ_ONCE(dst_dev(dst)->mtu);
+ mtu = READ_ONCE(dev->mtu);
if (unlikely(ip_mtu_locked(dst))) {
if (rt->rt_uses_gateway && mtu > 576)
--- b/include/net/ip6_route.h
+++ b/include/net/ip6_route.h
@@ -337,7 +337,7 @@
mtu = IPV6_MIN_MTU;
rcu_read_lock();
- idev = __in6_dev_get(dst_dev(dst));
+ idev = __in6_dev_get(dst_dev_rcu(dst));
if (idev)
mtu = READ_ONCE(idev->cnf.mtu6);
rcu_read_unlock();
--- b/include/net/route.h
+++ b/include/net/route.h
@@ -390,7 +390,7 @@
const struct net *net;
rcu_read_lock();
- net = dev_net_rcu(dst_dev(dst));
+ net = dst_dev_net_rcu(dst);
hoplimit = READ_ONCE(net->ipv4.sysctl_ip_default_ttl);
rcu_read_unlock();
}
--- b/net/core/sock.c
+++ b/net/core/sock.c
@@ -2587,7 +2587,7 @@
}
EXPORT_SYMBOL_GPL(sk_clone_lock);
-static u32 sk_dst_gso_max_size(struct sock *sk, struct dst_entry *dst)
+static u32 sk_dst_gso_max_size(struct sock *sk, const struct net_device *dev)
{
bool is_ipv6 = false;
u32 max_size;
@@ -2597,8 +2597,8 @@
!ipv6_addr_v4mapped(&sk->sk_v6_rcv_saddr));
#endif
/* pairs with the WRITE_ONCE() in netif_set_gso(_ipv4)_max_size() */
- max_size = is_ipv6 ? READ_ONCE(dst_dev(dst)->gso_max_size) :
- READ_ONCE(dst_dev(dst)->gso_ipv4_max_size);
+ max_size = is_ipv6 ? READ_ONCE(dev->gso_max_size) :
+ READ_ONCE(dev->gso_ipv4_max_size);
if (max_size > GSO_LEGACY_MAX_SIZE && !sk_is_tcp(sk))
max_size = GSO_LEGACY_MAX_SIZE;
@@ -2610,7 +2611,9 @@
{
u32 max_segs = 1;
- sk->sk_route_caps = dst_dev(dst)->features;
+ rcu_read_lock();
+ dev = dst_dev_rcu(dst);
+ sk->sk_route_caps = dev->features;
if (sk_is_tcp(sk)) {
struct inet_connection_sock *icsk = inet_csk(sk);
@@ -2626,7 +2629,7 @@
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 = sk_dst_gso_max_size(sk, dst);
+ sk->sk_gso_max_size = sk_dst_gso_max_size(sk, dev);
/* pairs with the WRITE_ONCE() in netif_set_gso_max_segs() */
max_segs = max_t(u32, READ_ONCE(dst_dev(dst)->gso_max_segs), 1);
}
================================================================================
* CONTEXT DIFFERENCES - surrounding code differences between the patches *
================================================================================
--- b/include/net/ip.h
+++ b/include/net/ip.h
@@ -438,12 +438,12 @@
bool forwarding)
{
- const struct rtable *rt = container_of(dst, struct rtable, dst);
+ const struct rtable *rt = dst_rtable(dst);
unsigned int mtu, res;
struct net *net;
rcu_read_lock();
- net = dev_net_rcu(dst->dev);
+ net = dev_net_rcu(dst_dev(dst));
if (READ_ONCE(net->ipv4.sysctl_ip_fwd_use_pmtu) ||
ip_mtu_locked(dst) ||
!forwarding) {
@@ -460,7 +486,7 @@
if (mtu)
goto out;
- mtu = READ_ONCE(dst->dev->mtu);
+ mtu = READ_ONCE(dst_dev(dst)->mtu);
if (unlikely(ip_mtu_locked(dst))) {
if (rt->rt_uses_gateway && mtu > 576)
--- b/include/net/ip6_route.h
+++ b/include/net/ip6_route.h
@@ -329,5 +329,5 @@
rcu_read_lock();
- idev = __in6_dev_get(dst->dev);
+ idev = __in6_dev_get(dst_dev(dst));
if (idev)
- mtu = idev->cnf.mtu6;
+ mtu = READ_ONCE(idev->cnf.mtu6);
rcu_read_unlock();
--- b/include/net/route.h
+++ b/include/net/route.h
@@ -360,7 +360,7 @@
const struct net *net;
rcu_read_lock();
- net = dev_net_rcu(dst->dev);
+ net = dev_net_rcu(dst_dev(dst));
hoplimit = READ_ONCE(net->ipv4.sysctl_ip_default_ttl);
rcu_read_unlock();
}
--- b/net/core/sock.c
+++ b/net/core/sock.c
@@ -2280,9 +2295,9 @@
void sk_setup_caps(struct sock *sk, struct dst_entry *dst)
{
u32 max_segs = 1;
sk->sk_route_caps = dst_dev(dst)->features;
- if (sk_is_tcp(sk))
- sk->sk_route_caps |= NETIF_F_GSO;
- if (sk->sk_route_caps & NETIF_F_GSO)
+ if (sk_is_tcp(sk)) {
+ struct inet_connection_sock *icsk = inet_csk(sk);
+
@@ -2289,9 +2305,6 @@
} else {
sk->sk_route_caps |= NETIF_F_SG | NETIF_F_HW_CSUM;
- /* pairs with the WRITE_ONCE() in netif_set_gso_max_size() */
- sk->sk_gso_max_size = READ_ONCE(dst_dev(dst)->gso_max_size);
- sk_trim_gso_size(sk);
- sk->sk_gso_max_size -= (MAX_TCP_HEADER + 1);
+ sk->sk_gso_max_size = sk_dst_gso_max_size(sk, dst);
/* pairs with the WRITE_ONCE() in netif_set_gso_max_segs() */
max_segs = max_t(u32, READ_ONCE(dst_dev(dst)->gso_max_segs), 1);
}This is an automated interdiff check for backported commits. |
JIRA PR Check Results24 commit(s) with issues found: Commit
|
|
❌ Validation checks completed with issues View full results: https://github.com/ctrliq/kernel-src-tree/actions/runs/32178826591 |
bmastbergen
left a comment
There was a problem hiding this comment.
We have a commit that removes rcu_dereference_bh_rtnl as unused, but there are still two callers in net/sched/cls_tcindex.c CONFIG_NET_CLS_TCINDEX is not set in our configs, so not a big deal but maybe we should remove them for correctness' sake?
|
|
||
| NEIGH_CACHE_STAT_INC(tbl, lookups); | ||
|
|
||
| rcu_read_lock_bh(); |
There was a problem hiding this comment.
Should this be switched to rcu_read_lock() as well?
| } | ||
| } | ||
|
|
||
| rcu_read_unlock_bh(); |
There was a problem hiding this comment.
Should this be switched to rcu_read_unlock() as well?
[LTS 9.2]
About
This PR is similar to its LTS 9.6 version, which was based, in turn, on the CentOS 9.8 MR. The differences and similarities between the versions can be summarized in the following table:
Commits
Part of one of the upstream branches backported as prerequisite (the
net: first round to use dev_net_rcu()branch, identified asipgroup in the LTS 9.6 PR). Pulled into the solution because it picks cleanly and is part of a branch already being backported as prerequisite.Prerequisite for
net: use dst_dev_rcu() in sk_setup_caps().Bugfix for
neighbour: switch to standard rcu, instead of rcu_bh.Prerequisite for
ipv6: use RCU in ip6_xmit().Prerequisite for
ipv6: use RCU in ip6_output().Bugfix for
neighbour: switch to standard rcu, instead of rcu_bh.Prerequisite for
net: use dst_dev_rcu() in sk_setup_caps().Bugfix for
neighbour: switch to standard rcu, instead of rcu_bh.Prerequisite for
neighbour: switch to standard rcu, instead of rcu_bh.Prerequisite for
net: use dst_dev_rcu() in sk_setup_caps(). Needed so that the change toip6_dst_mtu_maybe_forwarddone by that commit doesn't have to be duplicated inip6_mtu.kABI check: passed
Boot test: passed
boot-test.log
Kselftests: passed relative
Reference
kselftests–ciqlts9_2–run1.log
kselftests–ciqlts9_2–run2.log
kselftests–ciqlts9_2–run3.log
Patch
kselftests–ciqlts9_2-CVE-batch-43–run1.log
kselftests–ciqlts9_2-CVE-batch-43–run2.log
kselftests–ciqlts9_2-CVE-batch-43–run3.log
Comparison
The tests results for the reference and the patch are the same.
full-test-results-comparison.log