CVE-2024-26587 - Linux Kernel netdevsim PHC NULL Dereference (Explained with Exploit Details)

In early 2024, a critical bug was discovered and patched in the Linux kernel’s netdevsim driver—a network device simulator widely used for testing. The flaw, assigned CVE-2024-26587, could lead to a crash when destroying a netdevsim device configured with Virtual Functions (VFs). This post explains what happened, how to reproduce or exploit the issue, and what code was changed to fix it. Let’s break it down in simple terms.

The Problem

The function nsim_init_netdevsim() initializes the PHC (the hardware clock), but only if the device is a Physical Function (PF), not a Virtual Function (VF). However, when a device with VFs was destroyed, the cleanup code tried to destroy a PHC that was never initialized on the VFs, leading to a NULL pointer dereference and kernel crash.

The Bug: NULL Pointer Dereference

When removing or destroying a netdevsim device with VFs, the kernel attempted to destroy the PHC even if it was never set up. This triggers a core bug:

BUG: kernel NULL pointer dereference, address: 00000000000000b8
RIP: 001:mock_phc_destroy+xd/x30
Call Trace:
 <TASK>
 nsim_destroy+x4a/x70 [netdevsim]
 __nsim_dev_port_del+x47/x70 [netdevsim]
 nsim_dev_reload_destroy+x105/x120 [netdevsim]
 nsim_drv_remove+x2f/xb [netdevsim]
 device_release_driver_internal+x1a1/x210
 bus_remove_device+xd5/x120
 device_del+x159/x490
 device_unregister+x12/x30
 del_device_store+x11a/x1a [netdevsim]
 kernfs_fop_write_iter+x130/x1d
 vfs_write+x30b/x4b
 ksys_write+x69/xf
 do_syscall_64+xcc/x1e
 entry_SYSCALL_64_after_hwframe+x6f/x77

Linux systems running recent kernels with netdevsim and VFs enabled.

- Triggerable by any user with permissions to manage netdevsim devices—often root, but potentially exploitable for denial-of-service.

Here’s how this could look in practice

# Create a netdevsim device (with instance index )
/bin/echo  > /sys/bus/netdevsim/new_device

# Enable 1 VF on the device (pretend it’s PCI 000:00:00.)
devlink dev param set pci/000:00:00. name vf_num value 1 cmode runtime

# Trigger the bug by destroying the parent device
/bin/echo  > /sys/bus/netdevsim/del_device
# At this point, the kernel may crash with a NULL pointer dereference

Note: Don't run this on production or important systems. It is for educational/test environments only!

What changed in the code?

The logic to initialize and destroy the PHC was refactored so mock_phc_destroy() is only called for Physical Functions (PF), NOT VFs.

Before

int nsim_destroy(...) {
   mock_phc_destroy(dev); // Called on all, including VFs
   ...
}

After

int nsim_destroy(...) {
   if (nsim_dev_port_is_pf(dev))
      mock_phc_destroy(dev); // Only if this is a PF
   ...
}

Commit reference:
netdevsim: don’t try to destroy PHC on VFs (patch)

Now, PHC (the mock hardware clock) is only created and destroyed if the device is a PF, so trying to destroy a VF won’t result in a NULL pointer dereference.

References

- Linux Kernel Patch: netdevsim: don't try to destroy PHC on VFs
- CVE-2024-26587 on NVD (may update after publishing)
- devlink.sh test (reference test suite)

Conclusion

CVE-2024-26587 is a textbook example of why careful initialization and cleanup logic is critical in kernel code, especially with virtualization features. An incorrectly-placed cleanup call led to an easy-to-trigger kernel panic. The fix is simple, and updating your kernel resolves the risk.

Timeline

Published on: 02/22/2024 17:15:08 UTC
Last modified on: 03/18/2024 18:09:54 UTC