The Linux kernel is the heart of millions of computers, phones, and devices worldwide. Its security is crucial. This post will help you understand CVE-2022-24958, a flaw in drivers/usb/gadget/legacy/inode.c which affects the Linux kernel up to version 5.16.8. We'll break down what happened, show you some source code, discuss exploitation risk, and walk through defensive steps. Even if you're not a kernel expert, you'll be able to follow along.

What is CVE-2022-24958?

This flaw concerns the Linux USB gadget driver, which lets Linux devices pretend to be USB devices (like thumb drives or keyboards) when plugged into another machine. Specifically, the bug lies in mishandling the release (or freeing) of dev->buf, which could result in a double-free or use-after-free situation — serious issues that can lead to system crashes or kernel exploitation.

Quick summary

- Component: Linux kernel gadget, specifically drivers/usb/gadget/legacy/inode.c

Affected versions: Linux kernel through 5.16.8

- Vulnerability type: Memory mismanagement (double-free/use-after-free)

Understanding the Bug

Let's look at the relevant code. We'll focus on the release function, which is called when an object is cleaned up.

static int gadgetfs_release(struct inode *inode, struct file *fd)
{
    struct dev_data   *dev = fd->private_data;

    if (!dev)
        return ;

    if (dev->state != STATE_DEV_UNBORN) {
        /* ... hardware state cleanup ... */
    }

    kfree(dev->buf);  // <-- Problem area
    dev->buf = NULL;

    /* ... more cleanup code ... */

    kfree(dev);

    return ;
}

What's wrong?

The core of the bug is how dev->buf is released (via kfree). If some other part of the code frees dev->buf without marking it as NULL, it's possible for this release function to free it again, leading to a double-free. Alternatively, if memory is accessed after freeing the buffer, you get a use-after-free.

Why is this dangerous?

- Double-free: The same chunk of memory is released twice. This can corrupt the kernel's memory allocator, leading to unpredictable behavior or even allowing an attacker to execute code in the kernel.
- Use-after-free: Accessing dev->buf after it's been freed can expose sensitive data or allow an attacker to trigger kernel code execution.

Manipulate the state such that dev->buf gets freed elsewhere first, and then again here.

This usually requires the attacker to have local access (for example, being able to open and close the USB gadget device) and some knowledge of how memory is being managed.

Example: Triggering the Bug

Below is a simplified proof-of-concept that shows how repeated open/close operations on the gadgetfs device node could cause the double-free.

// pseudo-code

int fd1 = open("/dev/gadget", O_RDWR);
int fd2 = open("/dev/gadget", O_RDWR);

// This might allocate dev->buf for both, depending on the code path

close(fd1); // First call to release -> kfree(dev->buf)
close(fd2); // Second call to release -> kfree(dev->buf) again (double-free!)

This is hugely simplified and in real-world exploitation the attacker may need to coordinate operations across processes or threads, but it gives you a taste of how misuse of the cleanup logic can lead to kernel memory corruption.

- NVD CVE-2022-24958 Summary
- oss-security mailing list disclosure
- Patch discussion on LKML
- Git commit fixing CVE-2022-24958 (example; actual commit id might vary)

Was it Fixed? How?

Yes, Linux maintainers fixed the bug by adding additional checks and making sure buffer pointers are handled safely — for example, always setting pointer fields to NULL after freeing, and making sure only one cleanup path exists.

Fix conceptual example

if (dev->buf) {
    kfree(dev->buf);
    dev->buf = NULL;
}

And by ensuring every other code path checks dev->buf before freeing.

How Do I Remediate?

- Update your kernel! All major Linux vendors have released patches. Make sure your OS and kernel (and any systems you manage) are running 5.16.9 or later, or a distribution-patched kernel.
- Check for USB gadget subsystems: This bug only affects machines using the gadget driver, but it's common on embedded devices, Raspberry Pis, or Android.
- Limit local device access: Until you can patch, prevent untrusted local users from accessing /dev/gadget or equivalent device files.

Keeping your kernel up to date is critical for security.

- If you're doing kernel development: always NULL pointers after kfree/free!

Final Thoughts

CVE-2022-24958 is a classic example of how a small misstep in pointer management can open the kernel to big risks. Even if you don’t write kernel code, understanding root-cause helps you appreciate why patching and defense-in-depth matter.

If you want to learn more, here’s a great writeup on USB gadgets and Kernel newbies: How kernel memory allocation works.

Timeline

Published on: 02/11/2022 06:15:00 UTC
Last modified on: 07/01/2022 14:15:00 UTC