The RNDIS USB device class includes a buffer overflow vulnerability.
static int rndis_class_handler(struct usb_setup_packet *setup, int32_ *len, uint8_t **data)
{
LOG_DBG("len %d req_type 0x%x req 0x%x enabled %u",
*len, setup->bmRequestType, setup->bRequest,
netusb_enabled());
if (!netusb_enabled()) {
LOG_ERR("interface disabled");
return -ENODEV;
}
if (setup->bRequest == CDC_SEND_ENC_CMD &&
REQTYPE_GET_DIR(setup->bmRequestType) == REQTYPE_DIR_TO_DEVICE) {
/*
* Instead of handling here, queue
* handle_encapsulated_cmd(*data, *len);
*/
queue_encapsulated_cmd(*data, *len); // SH:
CONFIG_USB_REQUEST_BUFFER_SIZE bytes provided in control transfer request
are passed to function
static int queue_encapsulated_cmd(uint8_t *data, uint32_t len)
{
struct net_buf *buf;
buf = net_buf_alloc(&rndis_cmd_pool, K_NO_WAIT);
if (!buf) {
LOG_ERR("Cannot get free buffer");
return -ENOMEM;
}
memcpy(net_buf_add(buf, len), data, len); // SH: provided contents overwrite RNDIS CMD buffer violating boundaries
net_buf_put(&rndis_cmd_queue, buf);
LOG_DBG("queued buf %p", buf);
return 0;
}
static inline void *net_buf_add(struct net_buf *buf, size_t len)
{
return net_buf_simple_add(&buf->b, len);
}
void *net_buf_simple_add(struct net_buf_simple *buf, size_t len)
{
uint8_t *tail = net_buf_simple_tail(buf);
NET_BUF_SIMPLE_DBG("buf %p len %zu", buf, len);
__ASSERT_NO_MSG(net_buf_simple_tailroom(buf) >= len);
buf->len += len; // SH: only buffer length incremented
return tail; // SH: no indication that the buffer is not
large enough
}
Impact
The RNDIS USB device class includes a buffer overflow vulnerability.
When a "write to device" control transfer with command (bRequest)
CDC_SEND_ENC_CMD is handled by rndis_class_handler as defined in
function_rndis.c, in the queue_encapsulated_cmd function a RNDIS command pool
buffer is overwritten by user provided data violating buffer boundaries. The
control transfer request might be CONFIG_USB_REQUEST_BUFFER_SIZE (i.e. 2048)
bytes long, possibly significantly longer than the 512-byte RNDIS command
buffer.
This will result in a buffer overflow, allowing one to write data provided in
the control transfer request past buffer boundaries. Depending on actual memory
layout this might result in corruption of critical data structures or execution
of arbitrary code.
Patches
For more information
If you have any questions or comments about this advisory:
embargo: 2022-01-05