Skip to content

Two buffer overflow vulnerabilities in Zephyr USB code

Moderate
ceolin published GHSA-4vgv-5r6q-r6xh Aug 12, 2023

Package

Zephyr

Affected versions

< 3.4.0

Patched versions

3..4.0

Description

Summary

While reading the Zephyr code related to USB, I noticed a couple of buffer overflow vulnerabilities in the following locations:
https://github.com/zephyrproject-rtos/zephyr/blob/v3.3-branch/drivers/usb/device/usb_dc_native_posix.c#L359
https://github.com/zephyrproject-rtos/zephyr/blob/v3.3-branch/subsys/usb/device/class/netusb/function_rndis.c#L841

Details

The first buffer overflow vulnerability is located in the following function:

int usb_dc_ep_write(const uint8_t ep, const uint8_t *const data,
		    const uint32_t data_len, uint32_t * const ret_bytes)
{
	LOG_DBG("ep %x len %u", ep, data_len);

	if (!usbip_ctrl.attached || !usbip_ep_is_valid(ep)) {
		LOG_ERR("Not attached / Invalid endpoint: EP 0x%x", ep);
		return -EINVAL;
	}

	/* Check if IN ep */
	if (USB_EP_GET_DIR(ep) != USB_EP_DIR_IN) {
		return -EINVAL;
	}

	/* Check if ep enabled */
	if (!usbip_ep_is_enabled(ep)) {
		LOG_WRN("ep %x disabled", ep);
		return -EINVAL;
	}

	if (USB_EP_GET_IDX(ep) == 0) {
		if (!usbip_send_common(ep, data_len)) {
			return -EIO;
		}

		if (usbip_send(ep, data, data_len) != data_len) {
			return -EIO;
		}
	} else {
		uint8_t ep_idx = USB_EP_GET_IDX(ep);
		struct usb_ep_ctrl_prv *ctrl = &usbip_ctrl.in_ep_ctrl[ep_idx];

		memcpy(ctrl->buf, data, data_len); /* VULN */
		ctrl->buf_len = data_len;
	}

	if (ret_bytes) {
		*ret_bytes = data_len;
	}

	return 0;
}

A check on data_len is missing. If data and data_len are attacker-controlled, the fixed-size buffer buf in the following structure could overflow during memcpy(), thus potentially leading to denial of service or arbitrary code execution:

struct usb_ep_ctrl_prv {
	u8_t ep_ena;
	u16_t mps;
	usb_dc_ep_callback cb;
	u32_t data_len;
	u8_t buf[64];
	u8_t buf_len;
};

The second buffer overflow vulnerability is located in the following function:

static int handle_encapsulated_rsp(uint8_t **data, uint32_t *len)
{
	struct net_buf *buf;

	LOG_DBG("");

	buf = net_buf_get(&rndis_tx_queue, K_NO_WAIT);
	if (!buf) {
		LOG_ERR("Error getting response buffer");
		*len = 0U;
		return -ENODATA;
	}

	if (VERBOSE_DEBUG) {
		net_hexdump("RSP <", buf->data, buf->len);
	}

	memcpy(*data, buf->data, buf->len); /* VULN */
	*len = buf->len;

	net_buf_unref(buf);

	return 0;
}

A check on buf->len is missing. If buf->data and buf->len are attacker-controlled, the data buffer could overflow due to memcpy(), thus potentially leading to denial of service or arbitrary code execution.

PoC

I haven't tried to reproduce these potential vulnerabilities against a live install of the Zephyr OS.

Impact

If the vulnerabilities are confirmed, their impact could range from denial of service to arbitrary code execution.

Severity

Moderate
6.4
/ 10

CVSS base metrics

Attack vector
Physical
Attack complexity
Low
Privileges required
None
User interaction
None
Scope
Unchanged
Confidentiality
Low
Integrity
High
Availability
High
CVSS:3.1/AV:P/AC:L/PR:N/UI:N/S:U/C:L/I:H/A:H

CVE ID

CVE-2023-4265

Weaknesses

Credits