A critical bug, now identified as CVE-2024-44989, was found in the Linux kernel bonding driver. This flaw could lead to a system crash (kernel panic) due to a NULL pointer dereference in certain networking situations, especially when IPsec (IP Security) offload is involved. This post will explain the vulnerability in simple terms, show you how it happens with code snippets, and provide links to further reading.

How Does Bonding Work in Linux?

Bonding is a feature in Linux that lets you combine several network interfaces into one logical "bonded" interface (for redundancy or increased throughput). The bonded interface keeps pointers to the real physical devices ("slaves").

When you use advanced features like IPsec offloading, Linux networking expects these pointers ("real_dev") to be valid. If they aren’t, and the code tries to use them, you’ll get a crash.

This happened when switching which network interface in the bond was active.

- If a packet was in-flight and parallel code (especially in xfrm IPsec offload code) expected real_dev to be valid, a NULL pointer dereference would happen.

This is what you might see in the kernel logs

kernel: BUG: unable to handle page fault for address: 000000000000103
...
kernel: RIP: 001:nsim_ipsec_offload_ok+xc/x20 [netdevsim]
kernel: Code: ... <83> 80 30 10 00 00 01 b8 01 00 00 00 c3 ...
...
kernel: Call Trace:
kernel:  nsim_ipsec_offload_ok+xc/x20 [netdevsim]
kernel:  bond_ipsec_offload_ok+x7b/x90 [bonding]
kernel:  xfrm_output+x61/x3b
kernel:  ip_push_pending_frames+x56/x80

The important part is this line:
> nsim_ipsec_offload_ok+xc/x20 [netdevsim]

This means the kernel hit a NULL pointer when trying to access the real_dev structure in code performing IPsec offload checks, because bonding had just switched the active device and set real_dev to NULL.

Here's a simplified example of what went wrong

// In the old bonding code:
bond->real_dev = NULL;   // Dangerous! Other code might still use it

// Somewhere else (e.g. in xfrm/ipsec offload):
if (bond->real_dev->offload_capable) {  // <-- Boom! NULL dereference!
    // do offload
}

Root Cause:
A background packet or callback tries to use bond->real_dev while it's already set to NULL. The code *assumed* it would always be valid.

Exploit Possibility

This bug is a Denial-of-Service (DoS) vulnerability.

- Any user or process that could manipulate bonding interfaces and rapidly change state (e.g. using ifenslave or network manager) might be able to trigger the bug in systems using IPsec offload.
- The exploit would involve rapidly toggling the active bond slave, causing packets in-flight to trigger a NULL dereference.

Simple Exploitation Scenario (example)

# Assume two interfaces: eth and eth1 are bonded as bond
while true; do
  ifenslave -d bond eth
  ifenslave bond eth
done

Meanwhile, another process is sending a lot of network traffic over an IPsec tunnel.
Result: Kernel Oops or panic due to the race.

Note: You need permission to manage network interfaces for this, so it's not a privilege escalation bug but a local or remote DoS.

# Fix

The fix commit prevents real_dev from being set to NULL until after all packets are fully handled:

> We shouldn't set real_dev to NULL because packets can be in transit and xfrm might call xdo_dev_offload_ok() in parallel. All callbacks assume real_dev is set.

Patched Code Snippet

// Instead of setting to NULL, ensure all in-flight packets are gone first
if (bond->real_dev) {
    // Remove safely, after synchronizing with in-flight packets
}

References

- Linux kernel commit fixing the bug
- CVE entry at MITRE
- Explaining Linux bonding and IPsec offload

Summary

- CVE-2024-44989 is a NULL pointer dereference bug in the Linux kernel bonding code with IPsec offload.
- Can crash the kernel if bonding and IPsec are used together, and the active network device is switched at the wrong time.
- Fixed in all current Linux kernel releases—update ASAP if you use bonding/IPsec.

If yes, patch your kernel!

Stay safe. For more info, see the kernel commit and CVE details.

Timeline

Published on: 09/04/2024 20:15:08 UTC
Last modified on: 09/06/2024 16:31:22 UTC