summaryrefslogtreecommitdiff
path: root/components
diff options
context:
space:
mode:
Diffstat (limited to 'components')
-rw-r--r--components/legacy/usb/usbhost/class/hid.c14
-rw-r--r--components/legacy/usb/usbhost/class/ukbd.c15
-rw-r--r--components/legacy/usb/usbhost/class/umouse.c15
-rw-r--r--components/legacy/usb/usbhost/core/hub.c32
-rw-r--r--components/legacy/usb/usbhost/core/usbhost_core.c8
5 files changed, 71 insertions, 13 deletions
diff --git a/components/legacy/usb/usbhost/class/hid.c b/components/legacy/usb/usbhost/class/hid.c
index 5911faf1aa..ccd3183269 100644
--- a/components/legacy/usb/usbhost/class/hid.c
+++ b/components/legacy/usb/usbhost/class/hid.c
@@ -244,6 +244,7 @@ static void rt_usbh_hid_callback(void* context)
upipe_t pipe;
struct uhid* hid;
int timeout = USB_TIMEOUT_LONG;
+ rt_size_t xfer_len;
/* parameter check */
RT_ASSERT(context != RT_NULL);
@@ -254,11 +255,18 @@ static void rt_usbh_hid_callback(void* context)
/* invoke protocal callback function */
hid->protocal->callback((void*)hid);
+ /* the endpoint packet size is device controlled and may exceed buffer */
+ xfer_len = pipe->ep.wMaxPacketSize;
+ if (xfer_len > sizeof(hid->buffer))
+ {
+ xfer_len = sizeof(hid->buffer);
+ }
+
/* parameter check */
- RT_ASSERT(((struct uhintf*)pipe->inst)->device->hcd != RT_NULL);
+ RT_ASSERT(((struct uhintf *)pipe->inst)->device->hcd != RT_NULL);
- rt_usb_hcd_pipe_xfer(((struct uhintf*)pipe->inst)->device->hcd, pipe,
- hid->buffer, pipe->ep.wMaxPacketSize, timeout);
+ rt_usb_hcd_pipe_xfer(((struct uhintf *)pipe->inst)->device->hcd, pipe,
+ hid->buffer, xfer_len, timeout);
}
/**
diff --git a/components/legacy/usb/usbhost/class/ukbd.c b/components/legacy/usb/usbhost/class/ukbd.c
index db080ed406..1c55df407a 100644
--- a/components/legacy/usb/usbhost/class/ukbd.c
+++ b/components/legacy/usb/usbhost/class/ukbd.c
@@ -42,11 +42,20 @@ static rt_thread_t kbd_thread;
static void kbd_task(void* param)
{
struct uhintf* intf = (struct uhintf*)param;
+ struct uhid *hid = (struct uhid *)intf->user_data;
+ rt_size_t xfer_len;
+
+ /* the endpoint packet size is device controlled and may exceed buffer */
+ xfer_len = hid->pipe_in->ep.wMaxPacketSize;
+ if (xfer_len > sizeof(hid->buffer))
+ {
+ xfer_len = sizeof(hid->buffer);
+ }
+
while (1)
{
- if (rt_usb_hcd_pipe_xfer(intf->device->hcd, ((struct uhid*)intf->user_data)->pipe_in,
- ((struct uhid*)intf->user_data)->buffer, ((struct uhid*)intf->user_data)->pipe_in->ep.wMaxPacketSize,
- USB_TIMEOUT_BASIC) == 0)
+ if (rt_usb_hcd_pipe_xfer(intf->device->hcd, hid->pipe_in,
+ hid->buffer, xfer_len, USB_TIMEOUT_BASIC) == 0)
{
break;
}
diff --git a/components/legacy/usb/usbhost/class/umouse.c b/components/legacy/usb/usbhost/class/umouse.c
index dfd6e9081c..53a4234876 100644
--- a/components/legacy/usb/usbhost/class/umouse.c
+++ b/components/legacy/usb/usbhost/class/umouse.c
@@ -135,11 +135,20 @@ static rt_thread_t mouse_thread;
static void mouse_task(void* param)
{
struct uhintf* intf = (struct uhintf*)param;
+ struct uhid *hid = (struct uhid *)intf->user_data;
+ rt_size_t xfer_len;
+
+ /* the endpoint packet size is device controlled and may exceed buffer */
+ xfer_len = hid->pipe_in->ep.wMaxPacketSize;
+ if (xfer_len > sizeof(hid->buffer))
+ {
+ xfer_len = sizeof(hid->buffer);
+ }
+
while (1)
{
- if (rt_usb_hcd_pipe_xfer(intf->device->hcd, ((struct uhid*)intf->user_data)->pipe_in,
- ((struct uhid*)intf->user_data)->buffer, ((struct uhid*)intf->user_data)->pipe_in->ep.wMaxPacketSize,
- USB_TIMEOUT_BASIC) == 0)
+ if (rt_usb_hcd_pipe_xfer(intf->device->hcd, hid->pipe_in,
+ hid->buffer, xfer_len, USB_TIMEOUT_BASIC) == 0)
{
break;
}
diff --git a/components/legacy/usb/usbhost/core/hub.c b/components/legacy/usb/usbhost/core/hub.c
index d8e6716099..614e448165 100644
--- a/components/legacy/usb/usbhost/core/hub.c
+++ b/components/legacy/usb/usbhost/core/hub.c
@@ -468,6 +468,7 @@ static void rt_usbh_hub_irq(void* context)
upipe_t pipe;
uhub_t hub;
int timeout = USB_TIMEOUT_BASIC;
+ rt_size_t xfer_len;
RT_ASSERT(context != RT_NULL);
@@ -484,10 +485,17 @@ static void rt_usbh_hub_irq(void* context)
LOG_D("hub int xfer...");
+ /* the endpoint packet size is device controlled and may exceed buffer */
+ xfer_len = pipe->ep.wMaxPacketSize;
+ if (xfer_len > sizeof(hub->buffer))
+ {
+ xfer_len = sizeof(hub->buffer);
+ }
+
/* parameter check */
- RT_ASSERT(pipe->inst->hcd != RT_NULL);
+ RT_ASSERT(pipe->inst->hcd != RT_NULL);
- rt_usb_hcd_pipe_xfer(hub->self->hcd, pipe, hub->buffer, pipe->ep.wMaxPacketSize, timeout);
+ rt_usb_hcd_pipe_xfer(hub->self->hcd, pipe, hub->buffer, xfer_len, timeout);
}
/**
@@ -509,6 +517,7 @@ static rt_err_t rt_usbh_hub_enable(void *arg)
struct uhintf* intf = (struct uhintf*)arg;
upipe_t pipe_in = RT_NULL;
int timeout = USB_TIMEOUT_LONG;
+ rt_size_t xfer_len;
/* paremeter check */
RT_ASSERT(intf != RT_NULL);
@@ -531,6 +540,15 @@ static rt_err_t rt_usbh_hub_enable(void *arg)
return -RT_ERROR;
}
+ /* length is device supplied and is reused as the next read size into
+ * hub_desc; it must cover the head read and fit the descriptor field. */
+ if (hub->hub_desc.length < 8 ||
+ hub->hub_desc.length > sizeof(struct uhub_descriptor))
+ {
+ rt_kprintf("invalid hub descriptor length %d\n", hub->hub_desc.length);
+ return -RT_ERROR;
+ }
+
/* get full hub descriptor */
ret = rt_usbh_hub_get_descriptor(device, (rt_uint8_t*)&hub->hub_desc,
hub->hub_desc.length);
@@ -589,8 +607,14 @@ static rt_err_t rt_usbh_hub_enable(void *arg)
/* parameter check */
RT_ASSERT(device->hcd != RT_NULL);
pipe_in->user_data = hub;
- rt_usb_hcd_pipe_xfer(hub->hcd, pipe_in, hub->buffer,
- pipe_in->ep.wMaxPacketSize, timeout);
+
+ xfer_len = pipe_in->ep.wMaxPacketSize;
+ if (xfer_len > sizeof(hub->buffer))
+ {
+ xfer_len = sizeof(hub->buffer);
+ }
+
+ rt_usb_hcd_pipe_xfer(hub->hcd, pipe_in, hub->buffer, xfer_len, timeout);
return RT_EOK;
}
diff --git a/components/legacy/usb/usbhost/core/usbhost_core.c b/components/legacy/usb/usbhost/core/usbhost_core.c
index 6fea444b02..c81a3be10c 100644
--- a/components/legacy/usb/usbhost/core/usbhost_core.c
+++ b/components/legacy/usb/usbhost/core/usbhost_core.c
@@ -145,6 +145,14 @@ rt_err_t rt_usbh_attatch_instance(uinst_t device)
LOG_D("get device descriptor length %d",
dev_desc->bLength);
+ /* bLength is device controlled and is reused as the size of the next
+ * transfer into dev_desc. Reject anything but the standard size. */
+ if (dev_desc->bLength != sizeof(struct udevice_descriptor))
+ {
+ LOG_E("invalid device descriptor length %d", dev_desc->bLength);
+ return -RT_EINVAL;
+ }
+
/* get full device descriptor again */
ret = rt_usbh_get_descriptor(device, USB_DESC_TYPE_DEVICE, (void*)dev_desc, dev_desc->bLength);
if(ret != RT_EOK)