Skip to content

Conversation

pvts-mat
Copy link
Contributor

@pvts-mat pvts-mat commented Sep 3, 2025

[LTS 9.4]
CVE-2025-21764
VULN-54027

Problem

https://access.redhat.com/security/cve/CVE-2025-21764

A vulnerability was found in the Linux kernel's IPv6 Neighbor Discovery (NDISC) subsystem, which manages network neighbor information. The issue arises from improper synchronization mechanisms when allocating socket buffers (sk_buff) in the ndisc_alloc_skb() function. Specifically, the function can be called without holding the necessary Read-Copy-Update (RCU) or Routing Netlink (RTNL) locks, leading to a potential use-after-free (UAF) condition. This flaw allows an attacker with local access and low privileges to exploit the race condition, potentially causing system instability or crashes.

Solution

The mainline fix 628e6d1 uses dev_net_rcu(…) function defined in 482ad2a, which in turn uses read_pnet_rcu(…) defined in 2034d90, none of which were backported to ciqlts9_4, so they were included in this PR.

Consider the comparative timeline of net/ipv6/ndisc.c and include/net/net_namespace.h files changes in the mainline kernel, stable linux 5.15 and LTS 9.4 - all of the commits mentioned were backported to 5.15 along with CVE-2025-21764 patch:

timeline.log

   kernel-mainline                                                                                   linux-5.15.y            ciqlts9_4
   ------------------------------------------------------------------------------------------------  ----------------------  ----------------------
   c57a9c503 2025-04-14 net: Remove ->exit_batch_rtnl().
   7a60d91c6 2025-04-14 net: Add ->exit_rtnl() hook to struct pernet_operations.
   c353e8983 2025-03-24 net: introduce per netns packet chains
   e57a63202 2025-02-18 net: Add net_passive_inc() and net_passive_dec().
   0784d83df 2025-02-15 ndisc: ndisc_send_redirect() cleanup
   ed6ae1f32 2025-02-10 ndisc: extend RCU protection in ndisc_send_skb()                             ~ e24d225e4 2025-03-13
1> 628e6d189 2025-02-10 ndisc: use RCU protection in ndisc_alloc_skb()                               ~ b870256dd 2025-03-13
   48145a57d 2025-02-10 ndisc: ndisc_send_redirect() must use dev_get_by_index_rcu()                 ~ 80f706868 2025-03-13
2> 482ad2a4a 2025-02-06 net: add dev_net_rcu() helper                                                ~ 6e0d21491 2025-03-13
   0734d7c3d 2025-01-15 net: expedite synchronize_net() for cleanup_net()
   a853c6095 2024-12-17 inetpeer: do not get a refcount in inet_getpeer()
   …
   ffabe98cb 2024-02-04 net: make dev_unreg_count global
   b4a11b203 2023-10-20 net: fix IPSTATS_MIB_OUTPKGS increment in OutForwDatagrams.                                          ~ 791e96333 2023-12-11
3> 2034d90ae 2023-10-18 net: treat possible_net_t net pointer as an RCU one and add read_pnet_rcu()  ~ c22b8d778 2025-03-13
   d986f5212 2023-09-15 ipv6: lockless IPV6_MULTICAST_LOOP implementation
   b0adfba7e 2023-09-15 ipv6: lockless IPV6_UNICAST_HOPS implementation
   …
   c8d6c380d 2013-01-21 ndisc: Simplify arguments for ip6_nd_hdr().                                  = c8d6c380d 2013-01-21  = c8d6c380d 2013-01-21
   2576f17df 2013-01-21 ipv6: Unshare ip6_nd_hdr() and change return type to void.                   = 2576f17df 2013-01-21  = 2576f17df 2013-01-21
0> de09334b9 2013-01-21 ndisc: Introduce ndisc_alloc_skb() helper.                                   = de09334b9 2013-01-21  = de09334b9 2013-01-21
   9c86dafe9 2013-01-21 ndisc: Introduce ndisc_fill_redirect_hdr_option().                           = 9c86dafe9 2013-01-21  = 9c86dafe9 2013-01-21
   6bce6b4e1 2013-01-21 ndisc: Use skb_linearize() instead of pskb_may_pull(skb, skb->len).          = 6bce6b4e1 2013-01-21  = 6bce6b4e1 2013-01-21
   …

Legend:

0 de09334 Commit marked as introducing the bug
1 628e6d1 The mainline fix of CVE-2025-21764
2 482ad2a Defines `dev_net_rcu(…)`
3 2034d90 Defines `read_pnet_rcu(…)`

The dev_net_rcu(…) function defined in 482ad2a was specifically put as a groundwork for the patch series (https://lore.kernel.org/all/20250207135841.1948589-3-edumazet@google.com/) to which 628e6d1 belongs:

https://lore.kernel.org/all/173888823503.1713650.11309572430849516645.git-patchwork-notify@kernel.org/

Instead, add dev_net_rcu() for rcu_read_lock() contexts
and start to use it to fix bugs and clearly document the
safety requirements.

Apart from adding the read_pnet_rcu(…) function the 2034d90 commit modifies also the existing read_pnet(…) and write_pnet(…) functions used in other places of kernel code (it affects LTS 9.4 as CONFIG_NET_NS is enabled in all ciqlts9_4 configs). However, the semantics remain unchanged and only the additional RCU-related protections are introduced. See the documentation for the rcu_assign_pointer(…) macro

* rcu_assign_pointer() - assign to RCU-protected pointer
* @p: pointer to assign to
* @v: value to assign (publish)
*
* Assigns the specified value to the specified RCU-protected
* pointer, ensuring that any concurrent RCU readers will see
* any prior initialization.
*
* Inserts memory barriers on architectures that require them
* (which is most of them), and also prevents the compiler from
* reordering the code that initializes the structure after the pointer
* assignment. More importantly, this call documents which pointers
* will be dereferenced by RCU read-side code.

and the definition of __rcu_dereference_protected(…)

#define __rcu_dereference_protected(p, local, c, space) \
({ \
RCU_LOCKDEP_WARN(!(c), "suspicious rcu_dereference_protected() usage"); \
rcu_check_sparse(p, space); \
((typeof(*p) __force __kernel *)(p)); \
})

by which rcu_dereference_protected(…) is expressed:

#define rcu_dereference_protected(p, c) \
__rcu_dereference_protected((p), __UNIQUE_ID(rcu), (c), __rcu)

kABI check: passed

$ DESCR_TARGET=1 DEBUG=1 RELAXED_DEPS=1 CVE=CVE-2025-21764 ./ninja.sh -d explain _kabi_checked__x86_64--test--ciqlts9_4-CVE-2025-21764

ninja: Entering directory `/data/build/rocky-patching'
ninja explain: output state/kernels/ciqlts9_4-CVE-2025-21764/x86_64/kabi_checked doesn't exist
ninja explain: state/kernels/ciqlts9_4-CVE-2025-21764/x86_64/kabi_checked is dirty
[0/1] 	Check ABI of kernel [ciqlts9_4-CVE-2025-21764]	_kabi_checked__x86_64--test--ciqlts9_4-CVE-2025-21764
++ uname -m
+ python3 /data/src/ctrliq-github/kernel-dist-git-el-9.4/SOURCES/check-kabi -k /data/src/ctrliq-github/kernel-dist-git-el-9.4/SOURCES/Module.kabi_x86_64 -s vms/x86_64--build--ciqlts9_4/build_files/kernel-src-tree-ciqlts9_4-CVE-2025-21764/Module.symvers
kABI check passed
+ touch state/kernels/ciqlts9_4-CVE-2025-21764/x86_64/kabi_checked

Boot test: passed

boot-test.log

Kselftests: passed relative

Coverage

Only the net-related tests were run (at least for the patch, the reference test run contains full scope).

Reference

kselftests–ciqlts9_4–run1.log

Patch

kselftests–ciqlts9_4-CVE-2025-21764–run1.log
kselftests–ciqlts9_4-CVE-2025-21764–run2.log

Comparison

The tests results for the reference and patched kernel are the same

$ ktests.xsh diff --where 'tests.TestCase LIKE "net%"' kselftests--*.log

Column    File
--------  ----------------------------------------------
Status0   kselftests--ciqlts9_4--run1.log
Status1   kselftests--ciqlts9_4-CVE-2025-21764--run1.log
Status2   kselftests--ciqlts9_4-CVE-2025-21764--run2.log

TestCase                                          Status0  Status1  Status2  Summary
net/forwarding:bridge_locked_port.sh              pass     pass     pass     same
net/forwarding:bridge_mdb.sh                      skip     skip     skip     same
net/forwarding:bridge_mdb_host.sh                 pass     pass     pass     same
net/forwarding:bridge_mdb_max.sh                  skip     skip     skip     same
net/forwarding:bridge_mdb_port_down.sh            pass     pass     pass     same
net/forwarding:bridge_mld.sh                      pass     pass     pass     same
net/forwarding:bridge_port_isolation.sh           pass     pass     pass     same
net/forwarding:bridge_sticky_fdb.sh               pass     pass     pass     same
net/forwarding:bridge_vlan_aware.sh               pass     pass     pass     same
net/forwarding:bridge_vlan_mcast.sh               pass     pass     pass     same
net/forwarding:bridge_vlan_unaware.sh             pass     pass     pass     same
net/forwarding:custom_multipath_hash.sh           fail     fail     fail     same
net/forwarding:ethtool.sh                         skip     skip     skip     same
net/forwarding:ethtool_extended_state.sh          skip     skip     skip     same
net/forwarding:gre_custom_multipath_hash.sh       fail     fail     fail     same
net/forwarding:gre_inner_v4_multipath.sh          pass     pass     pass     same
net/forwarding:gre_multipath.sh                   pass     pass     pass     same
net/forwarding:gre_multipath_nh.sh                fail     fail     fail     same
net/forwarding:gre_multipath_nh_res.sh            fail     fail     fail     same
net/forwarding:hw_stats_l3.sh                     skip     skip     skip     same
net/forwarding:hw_stats_l3_gre.sh                 skip     skip     skip     same
net/forwarding:ip6_forward_instats_vrf.sh         skip     skip     skip     same
net/forwarding:ip6gre_custom_multipath_hash.sh    fail     fail     fail     same
net/forwarding:ip6gre_flat.sh                     pass     pass     pass     same
net/forwarding:ip6gre_flat_key.sh                 pass     pass     pass     same
net/forwarding:ip6gre_flat_keys.sh                pass     pass     pass     same
net/forwarding:ip6gre_hier.sh                     pass     pass     pass     same
net/forwarding:ip6gre_hier_key.sh                 pass     pass     pass     same
net/forwarding:ip6gre_hier_keys.sh                pass     pass     pass     same
net/forwarding:ip6gre_inner_v4_multipath.sh       pass     pass     pass     same
net/forwarding:ipip_flat_gre.sh                   pass     pass     pass     same
net/forwarding:ipip_flat_gre_key.sh               pass     pass     pass     same
net/forwarding:ipip_flat_gre_keys.sh              pass     pass     pass     same
net/forwarding:ipip_hier_gre.sh                   pass     pass     pass     same
net/forwarding:ipip_hier_gre_key.sh               pass     pass     pass     same
net/forwarding:local_termination.sh               skip     skip     skip     same
net/forwarding:loopback.sh                        skip     skip     skip     same
net/forwarding:mirror_gre.sh                      pass     pass     pass     same
net/forwarding:mirror_gre_bound.sh                pass     pass     pass     same
net/forwarding:mirror_gre_bridge_1d.sh            pass     pass     pass     same
net/forwarding:mirror_gre_bridge_1q.sh            pass     pass     pass     same
net/forwarding:mirror_gre_bridge_1q_lag.sh        pass     pass     pass     same
net/forwarding:mirror_gre_changes.sh              pass     pass     pass     same
net/forwarding:mirror_gre_flower.sh               pass     pass     pass     same
net/forwarding:mirror_gre_lag_lacp.sh             pass     pass     pass     same
net/forwarding:mirror_gre_neigh.sh                pass     pass     pass     same
net/forwarding:mirror_gre_nh.sh                   pass     pass     pass     same
net/forwarding:mirror_gre_vlan.sh                 pass     pass     pass     same
net/forwarding:mirror_vlan.sh                     pass     pass     pass     same
net/forwarding:no_forwarding.sh                   pass     pass     pass     same
net/forwarding:pedit_dsfield.sh                   pass     pass     pass     same
net/forwarding:pedit_ip.sh                        pass     pass     pass     same
net/forwarding:pedit_l4port.sh                    pass     pass     pass     same
net/forwarding:q_in_vni_ipv6.sh                   pass     pass     pass     same
net/forwarding:router.sh                          skip     skip     skip     same
net/forwarding:router_bridge.sh                   pass     pass     pass     same
net/forwarding:router_bridge_1d.sh                pass     pass     pass     same
net/forwarding:router_bridge_pvid_vlan_upper.sh   pass     pass     pass     same
net/forwarding:router_bridge_vlan.sh              pass     pass     pass     same
net/forwarding:router_bridge_vlan_upper.sh        pass     pass     pass     same
net/forwarding:router_bridge_vlan_upper_pvid.sh   pass     pass     pass     same
net/forwarding:router_broadcast.sh                pass     pass     pass     same
net/forwarding:router_mpath_nh.sh                 fail     fail     fail     same
net/forwarding:router_mpath_nh_res.sh             pass     pass     pass     same
net/forwarding:router_multicast.sh                skip     skip     skip     same
net/forwarding:router_multipath.sh                fail     fail     fail     same
net/forwarding:router_nh.sh                       pass     pass     pass     same
net/forwarding:router_vid_1.sh                    pass     pass     pass     same
net/forwarding:skbedit_priority.sh                pass     pass     pass     same
net/forwarding:tc_chains.sh                       pass     pass     pass     same
net/forwarding:tc_flower.sh                       pass     pass     pass     same
net/forwarding:tc_flower_cfm.sh                   fail     fail     fail     same
net/forwarding:tc_flower_l2_miss.sh               fail     fail     fail     same
net/forwarding:tc_flower_router.sh                pass     pass     pass     same
net/forwarding:tc_mpls_l2vpn.sh                   pass     pass     pass     same
net/forwarding:tc_shblocks.sh                     pass     pass     pass     same
net/forwarding:tc_tunnel_key.sh                   skip     skip     skip     same
net/forwarding:tc_vlan_modify.sh                  pass     pass     pass     same
net/forwarding:vxlan_asymmetric.sh                pass     pass     pass     same
net/forwarding:vxlan_asymmetric_ipv6.sh           pass     pass     pass     same
net/forwarding:vxlan_bridge_1d.sh                 pass     pass     pass     same
net/forwarding:vxlan_bridge_1d_port_8472.sh       pass     pass     pass     same
net/forwarding:vxlan_bridge_1d_port_8472_ipv6.sh  pass     pass     pass     same
net/forwarding:vxlan_bridge_1q.sh                 pass     pass     pass     same
net/forwarding:vxlan_bridge_1q_ipv6.sh            pass     pass     pass     same
net/forwarding:vxlan_bridge_1q_port_8472.sh       pass     pass     pass     same
net/forwarding:vxlan_bridge_1q_port_8472_ipv6.sh  pass     pass     pass     same
net/forwarding:vxlan_symmetric.sh                 pass     pass     pass     same
net/forwarding:vxlan_symmetric_ipv6.sh            pass     pass     pass     same
net/hsr:hsr_ping.sh                               fail     fail     fail     same
net/mptcp:diag.sh                                 pass     pass     pass     same
net/mptcp:mptcp_connect.sh                        pass     pass     pass     same
net/mptcp:mptcp_sockopt.sh                        pass     pass     pass     same
net/mptcp:pm_netlink.sh                           pass     pass     pass     same
net:altnames.sh                                   pass     pass     pass     same
net:bareudp.sh                                    pass     pass     pass     same
net:big_tcp.sh                                    skip     skip     skip     same
net:cmsg_so_mark.sh                               pass     pass     pass     same
net:devlink_port_split.py                         skip     skip     skip     same
net:drop_monitor_tests.sh                         skip     skip     skip     same
net:fcnal-test.sh                                 skip     skip     skip     same
net:fib-onlink-tests.sh                           pass     pass     pass     same
net:fib_nexthop_multiprefix.sh                    pass     pass     pass     same
net:fib_nexthop_nongw.sh                          pass     pass     pass     same
net:fib_rule_tests.sh                             pass     pass     pass     same
net:fib_tests.sh                                  fail     fail     fail     same
net:fin_ack_lat.sh                                pass     pass     pass     same
net:gre_gso.sh                                    skip     skip     skip     same
net:icmp.sh                                       fail     fail     fail     same
net:icmp_redirect.sh                              pass     pass     pass     same
net:io_uring_zerocopy_tx.sh                       fail     fail     fail     same
net:ip6_gre_headroom.sh                           pass     pass     pass     same
net:ipv6_flowlabel.sh                             pass     pass     pass     same
net:l2_tos_ttl_inherit.sh                         skip     skip     skip     same
net:l2tp.sh                                       pass     pass     pass     same
net:msg_zerocopy.sh                               pass     pass     pass     same
net:netdevice.sh                                  pass     pass     pass     same
net:pmtu.sh                                       fail     fail     fail     same
net:psock_snd.sh                                  pass     pass     pass     same
net:reuseaddr_ports_exhausted.sh                  pass     pass     pass     same
net:reuseport_bpf                                 pass     pass     pass     same
net:reuseport_bpf_cpu                             pass     pass     pass     same
net:reuseport_bpf_numa                            pass     pass     pass     same
net:reuseport_dualstack                           pass     pass     pass     same
net:route_localnet.sh                             pass     pass     pass     same
net:rps_default_mask.sh                           pass     pass     pass     same
net:rtnetlink.sh                                  skip     skip     skip     same
net:run_afpackettests                             pass     pass     pass     same
net:run_netsocktests                              pass     pass     pass     same
net:rxtimestamp.sh                                pass     pass     pass     same
net:so_txtime.sh                                  pass     pass     pass     same
net:srv6_end_next_csid_l3vpn_test.sh              pass     pass     pass     same
net:srv6_hencap_red_l3vpn_test.sh                 pass     pass     pass     same
net:srv6_hl2encap_red_l2vpn_test.sh               pass     pass     pass     same
net:stress_reuseport_listen.sh                    pass     pass     pass     same
net:tcp_fastopen_backup_key.sh                    pass     pass     pass     same
net:test_blackhole_dev.sh                         fail     fail     fail     same
net:test_bpf.sh                                   pass     pass     pass     same
net:test_bridge_neigh_suppress.sh                 skip     skip     skip     same
net:test_vxlan_fdb_changelink.sh                  pass     pass     pass     same
net:test_vxlan_under_vrf.sh                       pass     pass     pass     same
net:tls                                           pass     pass     pass     same
net:traceroute.sh                                 pass     pass     pass     same
net:udpgro.sh                                     fail     fail     fail     same
net:udpgro_bench.sh                               fail     fail     fail     same
net:udpgso.sh                                     pass     pass     pass     same
net:unicast_extensions.sh                         pass     pass     pass     same
net:veth.sh                                       fail     fail     fail     same
net:vrf-xfrm-tests.sh                             pass     pass     pass     same
net:vrf_route_leaking.sh                          pass     pass     pass     same
net:vrf_strict_mode_test.sh                       pass     pass     pass     same
netfilter:bridge_brouter.sh                       skip     skip     skip     same
netfilter:conntrack_icmp_related.sh               fail     fail     fail     same
netfilter:conntrack_tcp_unreplied.sh              fail     fail     fail     same
netfilter:conntrack_vrf.sh                        skip     skip     skip     same
netfilter:ipip-conntrack-mtu.sh                   skip     skip     skip     same
netfilter:ipvs.sh                                 skip     skip     skip     same
netfilter:nf_nat_edemux.sh                        skip     skip     skip     same
netfilter:nft_audit.sh                            fail     fail     fail     same
netfilter:nft_concat_range.sh                     fail     fail     fail     same
netfilter:nft_conntrack_helper.sh                 skip     skip     skip     same
netfilter:nft_fib.sh                              skip     skip     skip     same
netfilter:nft_flowtable.sh                        fail     fail     fail     same
netfilter:nft_meta.sh                             pass     pass     pass     same
netfilter:nft_nat.sh                              skip     skip     skip     same
netfilter:nft_queue.sh                            skip     skip     skip     same
netfilter:rpath.sh                                pass     pass     pass     same

Specific tests: skipped

…_rcu()

jira VULN-54027
cve-pre CVE-2025-21764
commit-author Jiri Pirko <jiri@nvidia.com>
commit 2034d90

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>
(cherry picked from commit 2034d90)
	Signed-off-by: Marcin Wcisło <marcin.wcislo@conclusive.pl>
jira VULN-54027
cve-pre CVE-2025-21764
commit-author Eric Dumazet <edumazet@google.com>
commit 482ad2a

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>
(cherry picked from commit 482ad2a)
	Signed-off-by: Marcin Wcisło <marcin.wcislo@conclusive.pl>
jira VULN-54027
cve CVE-2025-21764
commit-author Eric Dumazet <edumazet@google.com>
commit 628e6d1

ndisc_alloc_skb() can be called without RTNL or RCU being held.

Add RCU protection to avoid possible UAF.

Fixes: de09334 ("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>
(cherry picked from commit 628e6d1)
	Signed-off-by: Marcin Wcisło <marcin.wcislo@conclusive.pl>
Copy link
Collaborator

@PlaidCat PlaidCat left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:shipit:

Copy link
Collaborator

@bmastbergen bmastbergen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🥌

@PlaidCat PlaidCat merged commit 32c89d9 into ctrliq:ciqlts9_4 Sep 4, 2025
4 of 5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

3 participants