The Linux kernel is an essential part of the operating system, and it is crucial to ensure its security. Recently, a vulnerability in the Linux kernel regarding the net: dsa (Distributed Switch Architecture) has been resolved. The issue arose from the incorrect dereference of netdev_priv(), which caused a kernel oops. This post will provide details of the vulnerability, the relevant code snippet, and the fix that has been applied.

The vulnerability was found in the Linux kernel's handling of non-DSA netdevice events. Before the resolution, the kernel would dereference the netdev_priv() pointer for every NETDEV_CHANGEUPPER and NETDEV_PRECHANGEUPPER event in the system. This led to issues, as not all net_devices have a netdev_priv() of type struct dsa_user_priv.

The code snippet where the vulnerability existed

static inline struct dsa_port *dsa_user_to_port(const struct net_device *dev)
{
    struct dsa_user_priv *p = netdev_priv(dev);

    return p->dp;
}

The problem with this code is that p->dp dereferences 8 bytes starting with offset 16, causing issues with drivers that allocate memory in that area. Most importantly, the dummy interface, a special case in this context, calls alloc_netdev() with a priv size of , making every netdev_priv() dereference invalid. This resulted in the kernel reporting a bug with KASAN (Kernel Address Sanitizer), as seen in the following example:

$ ip link add dummy1 type dummy
$ ip link add link dummy1 name dummy1.100 type vlan id 100
[   43.309174] ==================================================================
[   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.330058]
[   43.342436] Call trace:
[   43.366542]  dsa_user_prechangeupper+x30/xe8
[   43.371024]  dsa_user_netdevice_event+xb38/xee8
[   43.375768]  notifier_call_chain+xa4/x210
[   43.379985]  raw_notifier_call_chain+x24/x38
[   43.384464]  __netdev_upper_dev_link+x3ec/x5d8
[   43.389120]  netdev_upper_dev_link+x70/xa8
[   43.393424]  register_vlan_dev+x1bc/x310
[   43.397554]  vlan_newlink+x210/x248
[   43.401247]  rtnl_newlink+x9fc/xe30
[   43.404942]  rtnetlink_rcv_msg+x378/x580

To fix this vulnerability and avoid the kernel oops, the dereference was moved after the type check, as it should have been from the start. This way, the invalid dereferences are avoided, and the kernel works as expected. The original patch reference can be found here.

In conclusion, the CVE-2024-26596 vulnerability in the Linux kernel's net: dsa handling of non-DSA netdevice events has been resolved. Properly dereferencing the pointer prevents the issues and potential vulnerabilities that existed before the fix.

Timeline

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