CVE-2024-44987 Overview
CVE-2024-44987 is a use-after-free (UAF) vulnerability in the Linux kernel's IPv6 networking stack, specifically within the ip6_send_skb() function in net/ipv6/ip6_output.c. The flaw was discovered by syzbot kernel fuzzing infrastructure. After ip6_local_out() returns, the code dereferences the route (rt) structure without holding rcu_read_lock(), allowing the destination entry to be freed concurrently. The vulnerability is classified under [CWE-416] (Use After Free) and affects multiple stable Linux kernel branches up to 6.11-rc4. Siemens has also issued advisories covering affected industrial products.
Critical Impact
A local attacker with low privileges can trigger memory corruption in the IPv6 stack, leading to kernel crashes, denial of service, or potential local privilege escalation through controlled use-after-free exploitation.
Affected Products
- Linux Kernel (multiple stable branches prior to fix commits)
- Linux Kernel 6.11-rc1 through 6.11-rc4
- Debian LTS distributions shipping affected kernel versions
- Siemens industrial products referenced in advisories SSA-265688, SSA-355557, and SSA-613116
Discovery Timeline
- 2024-09-04 - CVE-2024-44987 published to NVD
- 2026-05-12 - Last updated in NVD database
Technical Details for CVE-2024-44987
Vulnerability Analysis
The vulnerability resides in ip6_send_skb() within net/ipv6/ip6_output.c at line 1964. The function calls ip6_local_out() to transmit an IPv6 socket buffer, then continues to dereference the route structure pointer rt for statistics updates. Once ip6_local_out() returns, the kernel can no longer guarantee that rt remains valid because the destination entry may have been released and freed by the RCU reclamation path running on another CPU.
KASAN reports demonstrate the issue clearly: the slab object backing the destination cache is allocated via dst_alloc() in ip6_blackhole_route(), then freed by dst_destroy() during RCU batch processing while ip6_send_skb() is still accessing it. The path that exposes this race runs through rawv6_sendmsg() and rawv6_push_pending_frames(), which are reachable from user space using a raw IPv6 socket.
A closely related fix in commit a688caa34beb (ipv6: take rcu lock in rawv6_send_hdrinc()) addressed the same pattern in a different code path.
Root Cause
The root cause is missing RCU (Read-Copy-Update) synchronization. Linux destination entries are reclaimed using RCU callbacks, so any code accessing a dst_entry outside the original RCU read-side critical section must re-acquire rcu_read_lock(). ip6_send_skb() violated this contract by dereferencing rt after handing the skb to ip6_local_out(), which itself releases the implicit RCU protection.
Attack Vector
Exploitation requires local access and the ability to send packets through a raw IPv6 socket, which on most distributions requires CAP_NET_RAW. An attacker repeatedly triggers route lookups and concurrent route invalidations (for example through XFRM policy changes that flow into ip6_blackhole_route()) to race destination release against ip6_send_skb(). Successful exploitation yields a read of freed slab memory, which can be leveraged for information disclosure, kernel panic, or, with additional heap-shaping primitives, controlled use-after-free escalation.
No public proof-of-concept exploit code has been released. The vulnerability was found through syzbot fuzzing, and technical details are available in the upstream kernel commits listed in the Linux stable tree.
Detection Methods for CVE-2024-44987
Indicators of Compromise
- KASAN slab-use-after-free reports referencing ip6_send_skb+0x18d/0x230 in net/ipv6/ip6_output.c
- Unexplained kernel oops or panic messages tied to rawv6_push_pending_frames or rawv6_sendmsg call paths
- Repeated raw IPv6 socket creation by unprivileged or low-privileged user accounts on production hosts
Detection Strategies
- Inventory running kernel versions against the fixed commits and flag any host running an unpatched 6.x or stable backport branch
- Monitor audit logs for processes acquiring CAP_NET_RAW and opening AF_INET6 raw sockets in workloads that do not require them
- Enable kernel crash collection (kdump, pstore) and centralize crash signatures to detect repeated UAF traces in IPv6 output paths
Monitoring Recommendations
- Forward dmesg and journald kernel logs to a centralized log platform and alert on KASAN, BUG, and Oops strings
- Track XFRM policy changes and high-rate IPv6 route invalidations, which can indicate race-condition exploitation attempts
- Baseline raw socket usage per host and alert on deviations, particularly from non-system accounts
How to Mitigate CVE-2024-44987
Immediate Actions Required
- Apply the upstream kernel patches referenced in the kernel.org stable commits for your kernel branch
- Update Debian-based systems using the Debian LTS Announcement (October 2024) and Debian LTS Announcement (January 2025)
- Review Siemens guidance in SSA-265688, SSA-355557, and SSA-613116 for affected industrial products
- Reboot patched hosts to ensure the fixed kernel image is active
Patch Information
The Linux kernel maintainers released fixes across multiple stable branches. The patches wrap the post-ip6_local_out() dereference of rt inside an rcu_read_lock()/rcu_read_unlock() pair, matching the pattern used in the earlier rawv6_send_hdrinc() fix. Distribution-specific updated packages are available through Debian LTS advisories and Siemens product certifications. Verify the running kernel version with uname -r after applying updates.
Workarounds
- Restrict CAP_NET_RAW to trusted system processes only, preventing unprivileged users from opening raw IPv6 sockets
- Disable IPv6 on hosts that do not require it by setting net.ipv6.conf.all.disable_ipv6=1 until the kernel can be patched
- Apply seccomp or AppArmor profiles to container workloads to block raw socket creation in untrusted tenants
# Configuration example
# Verify running kernel version
uname -r
# Temporarily disable IPv6 until the kernel is patched
sysctl -w net.ipv6.conf.all.disable_ipv6=1
sysctl -w net.ipv6.conf.default.disable_ipv6=1
# Persist the setting
echo "net.ipv6.conf.all.disable_ipv6 = 1" >> /etc/sysctl.d/99-cve-2024-44987.conf
echo "net.ipv6.conf.default.disable_ipv6 = 1" >> /etc/sysctl.d/99-cve-2024-44987.conf
sysctl --system
# Audit which processes hold CAP_NET_RAW
getcap -r / 2>/dev/null | grep cap_net_raw
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

