A recent vulnerability in the Linux kernel (CVE-2024-41035) has caused numerous issues involving USB devices. The bug in question is related to duplicate endpoint descriptors and affects the usbcore module. Syzbot, an automated bug finding tool, has found a solution to this problem by clearing the reserved bits in an endpoint descriptor.

In this post, we'll discuss the details of this vulnerability, provide code snippets to better understand the issue, and share original references for further reading.

Background

Endpoint descriptors are part of the USB protocol, allowing a device to communicate effectively with a host system (e.g., computer). These descriptors contain information about the type and direction of the data transfer. However, due to an assumption that the reserved bits in an endpoint descriptor's bEndpointAddress field would always be , the endpoint_is_duplicate() routine in config.c, and possibly other routines, may mistakenly perceive two descriptors as distinct endpoints, even though they have the same direction and endpoint number.

This misunderstanding can lead to confusion and bugs, such as one identified by syzbot, where there were two descriptors with matching endpoint numbers and directions, one being interrupt and the other being bulk.

Exploit Details

The main issue with this vulnerability is that it can cause system instability, data corruption, and potentially even crashes. In order to avoid these problems, a fix has been proposed. The solution involves clearing the reserved bits in the endpoint descriptor.

The following code snippet shows the usb_parse_endpoint() function in question

static int usb_parse_endpoint(struct device *ddev, struct usb_host_endpoint *endpoint,
        unsigned char *buffer, int size, int interval_1_8)
{
    // original descriptor parsing code...
    
    /* Clear reserved bits in bEndpointAddress */
    p[2] &= USB_ENDPOINT_NUMBER_MASK | USB_DIR_IN;
    
    // check for duplicates using the modified descriptor
    if (endpoint_is_duplicate(desc, endpoint))
    {
        dev_dbg(ddev, "Duplicate endpoint descriptor for ep%02x\n", desc->bEndpointAddress);
        return -EINVAL;
    }
    
    // rest of the function...
}

The fix requires us to make a copy of the descriptor earlier in usb_parse_endpoint() and use the copy, instead of the original when checking for duplicates. By clearing the reserved bits, the endpoint_is_duplicate() routine will no longer mistakenly perceive two descriptors as being unique.

References

1. Linux kernel source code: Here
2. Linux kernel USB subsystem documentation: Here

Conclusion

The discovery and resolution of this Linux kernel vulnerability CVE-2024-41035 highlights the importance of providing regular updates and actively seeking out potential bugs. By applying the appropriate fix to clear the reserved bits in an endpoint descriptor, issues related to duplicate endpoint descriptors are effectively addressed, ensuring a more reliable and stable environment when using USB devices. Users are encouraged to update their kernel to the latest version available to benefit from these improvements.

Timeline

Published on: 07/29/2024 15:15:12 UTC
Last modified on: 12/19/2024 09:10:31 UTC