The USB over IP kernel driver allows a server system to export its USB devices to a client system over an IP network via USB over IP protocol. Exportable USB devices include physical devices and software entities that are created on the server using the USB gadget sub-system. This article will cover a major bug related to USB over IP in the Linux kernel that was recently uncovered; it created some significant security issues but was resolved with help from the kernel community.
The Basics of the USB Over IP Protocol
There are two USB over IP server kernel modules:
- usbip-host (stub driver): A stub USB device driver that can be bound to physical USB devices to export them over the network.
- usbip-vudc: A virtual USB Device Controller that exports a USB device created with the USB Gadget Subsystem.
There is one USB over IP client kernel module:
- usbip-vhci: A virtual USB Host Controller that imports a USB device from a USB over IP capable server.
Finally, there is one USB over IP utility:
- (usbip-utils): A set of user-space tools used to handle connection and management, this is used on both the client and server side.
The USB/IP protocol consists of a set of packets that get exchanged between the client and server that query the exportable devices, request an attachment to one, access the device, and finally detach once finished. The server responds to these requests from the client, and this exchange is a series of TCP/IP packets with a TCP/IP payload that carries the USB/IP packets over the network. I’m not going to discuss the protocol in detail in this blog, please refer to usbip_protocol.txt to learn more.
Identifying a Security Problem With USB Over IP in Linux
When a client accesses an imported USB device, usbip-vhci sends a USBIP_CMD_SUBMIT to the usbip-host, which submits a USB Request Block (URB). An endpoint number, transfer_buffer_length, and number of ISO packets are among the valid URB fields that will be in a USBIP_CMD_SUBMIT packet. There are some potential vulnerabilities with this, specifically a malicious packet could be sent from a client with an invalid endpoint, or a very large transfer_buffer_length with a large number of ISO packets. A bad endpoint value could force the usbip-host to access memory out of bounds unless usbip-host validates the endpoint to be within valid range of 0-15. A large transfer_buffer_length could result in the kernel allocating large amounts of memory. Either of these malicious requests could adversely impact the server system operation.
Jakub Jirasek from Secunia Research at Flexera reported these security vulnerabilities in the driver to the malicious input. In addition, he reported an instance of a socket pointer address (kernel memory address) leaked in a world-readable sysfs USB/IP client side file and in debug output. Unfortunately, the USB over IP driver had these security vulnerabilities since the beginning. The good news is that they have been found and fixed now, I sent a series of 4 fixes to address all of the issues reported by Jakub Jirasek. In addition, I am continuing to look for other potential problems.
All of these problems are a result of a lack of validation checks on the input and an incorrect handling of error conditions; my fixes add the missing checks and take proper action. These fixes will propagate into the stable releases within the next few weeks. One exception is the issue with kernel address leaks which is an intentional design decision to provide a convenient way to find IP address from socket addresses that opened a security hole.
Where are these fixes?
The fixes are going in to the 4.15 and stable releases. The fixes can be found in the following two git branches:
Secunia Research has created the following CVEs for the fixes:
- CVE-2017-16911 usbip: prevent vhci_hcd driver from leaking a socket pointer
- CVE-2017-16912 usbip: fix stub_rx: get_pipe() to validate endpoint number
- CVE-2017-16913 usbip: fix stub_rx: harden CMD_SUBMIT path to handle
- CVE-2017-16914 usbip: fix stub_send_ret_submit() vulnerability to null
Do it Right the First Time
This is a great example of how open source software can benefit from having many eyes looking over it to identify problems so the software can be improved. However, after solving these issues, my takeaway is to be proactive in detecting security problems, but better yet, avoid introducing them entirely. Failing to validate input is an obvious coding error in any case, that can potentially allow users to send malicious packets with severe consequences. In addition, be mindful of exposing sensitive information such as the kernel pointer addresses. Fortunately, we were able to work together to solve this problem which should make USB over IP more secure in the Linux kernel.