Skip to content

usb: fix unaligned access to interface and device descriptor #8495

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion subsys/usb/class/bluetooth.c
Original file line number Diff line number Diff line change
Expand Up @@ -263,7 +263,8 @@ static int bluetooth_class_handler(struct usb_setup_packet *setup,

static void bluetooth_interface_config(u8_t bInterfaceNumber)
{
bluetooth_cfg.if0.bInterfaceNumber = bInterfaceNumber;
UNALIGNED_PUT(bInterfaceNumber,
&bluetooth_cfg.if0.bInterfaceNumber);
}

USBD_CFG_DATA_DEFINE(hci) struct usb_cfg_data bluetooth_config = {
Expand Down
15 changes: 10 additions & 5 deletions subsys/usb/class/cdc_acm.c
Original file line number Diff line number Diff line change
Expand Up @@ -427,12 +427,17 @@ static void cdc_acm_dev_status_cb(enum usb_dc_status_code status, u8_t *param)

static void cdc_interface_config(u8_t bInterfaceNumber)
{
cdc_acm_cfg.if0.bInterfaceNumber = bInterfaceNumber;
cdc_acm_cfg.if0_union.bControlInterface = bInterfaceNumber;
cdc_acm_cfg.if1.bInterfaceNumber = bInterfaceNumber + 1;
cdc_acm_cfg.if0_union.bSubordinateInterface0 = bInterfaceNumber + 1;
UNALIGNED_PUT(bInterfaceNumber,
&cdc_acm_cfg.if0.bInterfaceNumber);
UNALIGNED_PUT(bInterfaceNumber,
&cdc_acm_cfg.if0_union.bControlInterface);
UNALIGNED_PUT((bInterfaceNumber + 1),
&cdc_acm_cfg.if1.bInterfaceNumber);
UNALIGNED_PUT((bInterfaceNumber + 1),
&cdc_acm_cfg.if0_union.bSubordinateInterface0);
#ifdef CONFIG_USB_COMPOSITE_DEVICE
cdc_acm_cfg.iad_cdc.bFirstInterface = bInterfaceNumber;
UNALIGNED_PUT(bInterfaceNumber,
&cdc_acm_cfg.iad_cdc.bFirstInterface);
#endif
}

Expand Down
7 changes: 4 additions & 3 deletions subsys/usb/class/hid/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,8 @@ USBD_CLASS_DESCR_DEFINE(primary) struct usb_hid_config hid_cfg = {

static void usb_set_hid_report_size(u16_t report_desc_size)
{
hid_cfg.if0_hid.subdesc[0].wDescriptorLength =
sys_cpu_to_le16(report_desc_size);
UNALIGNED_PUT(sys_cpu_to_le16(report_desc_size),
&hid_cfg.if0_hid.subdesc[0].wDescriptorLength);
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder could we use here sys_put_le16()

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see it now, should work, @SavinayDharmappa can you try it?


static struct hid_device_info {
Expand Down Expand Up @@ -211,7 +211,8 @@ static struct usb_ep_cfg_data hid_ep_data[] = {

static void hid_interface_config(u8_t bInterfaceNumber)
{
hid_cfg.if0.bInterfaceNumber = bInterfaceNumber;
UNALIGNED_PUT(bInterfaceNumber,
&hid_cfg.if0.bInterfaceNumber);
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It does not need alignment.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You might be right, I have no knowledge about how Intel S1000 supports unaligned accesses


USBD_CFG_DATA_DEFINE(hid) struct usb_cfg_data hid_config = {
Expand Down
3 changes: 2 additions & 1 deletion subsys/usb/class/mass_storage.c
Original file line number Diff line number Diff line change
Expand Up @@ -818,7 +818,8 @@ static void mass_storage_status_cb(enum usb_dc_status_code status, u8_t *param)

static void mass_interface_config(u8_t bInterfaceNumber)
{
mass_cfg.if0.bInterfaceNumber = bInterfaceNumber;
UNALIGNED_PUT(bInterfaceNumber,
&mass_cfg.if0.bInterfaceNumber);
}

/* Configuration of the Mass Storage Device send to the USB Driver */
Expand Down
39 changes: 26 additions & 13 deletions subsys/usb/class/netusb/netusb.c
Original file line number Diff line number Diff line change
Expand Up @@ -367,29 +367,42 @@ static void netusb_interface_config(u8_t bInterfaceNumber)

if (idx) {
SYS_LOG_DBG("fixup string %d", idx);
cdc_ecm_cfg.if0_netfun_ecm.iMACAddress = idx;
UNALIGNED_PUT(idx,
&cdc_ecm_cfg.if0_netfun_ecm.iMACAddress);
}

cdc_ecm_cfg.if0.bInterfaceNumber = bInterfaceNumber;
cdc_ecm_cfg.if0_union.bControlInterface = bInterfaceNumber;
cdc_ecm_cfg.if0_union.bSubordinateInterface0 = bInterfaceNumber + 1;
cdc_ecm_cfg.if1_0.bInterfaceNumber = bInterfaceNumber + 1;
cdc_ecm_cfg.if1_1.bInterfaceNumber = bInterfaceNumber + 1;
UNALIGNED_PUT(bInterfaceNumber,
&cdc_ecm_cfg.if0.bInterfaceNumber);
UNALIGNED_PUT(bInterfaceNumber,
&cdc_ecm_cfg.if0_union.bControlInterface);
UNALIGNED_PUT((bInterfaceNumber + 1),
&cdc_ecm_cfg.if0_union.bSubordinateInterface0);
UNALIGNED_PUT((bInterfaceNumber + 1),
&cdc_ecm_cfg.if1_0.bInterfaceNumber);
UNALIGNED_PUT((bInterfaceNumber + 1),
&cdc_ecm_cfg.if1_1.bInterfaceNumber);
#ifdef CONFIG_USB_COMPOSITE_DEVICE
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same here

cdc_ecm_cfg.iad.bFirstInterface = bInterfaceNumber;
UNALIGNED_PUT(bInterfaceNumber,
&cdc_ecm_cfg.iad.bFirstInterface);
#endif
#endif
#ifdef CONFIG_USB_DEVICE_NETWORK_RNDIS
rndis_cfg.if0.bInterfaceNumber = bInterfaceNumber;
rndis_cfg.if0_union.bControlInterface = bInterfaceNumber;
rndis_cfg.if0_union.bSubordinateInterface0 = bInterfaceNumber + 1;
rndis_cfg.if1.bInterfaceNumber = bInterfaceNumber + 1;
UNALIGNED_PUT(bInterfaceNumber,
&rndis_cfg.if0.bInterfaceNumber);
UNALIGNED_PUT(bInterfaceNumber,
&rndis_cfg.if0_union.bControlInterface);
UNALIGNED_PUT((bInterfaceNumber + 1),
&rndis_cfg.if0_union.bSubordinateInterface0);
UNALIGNED_PUT((bInterfaceNumber + 1),
&rndis_cfg.if1.bInterfaceNumber);
#ifdef CONFIG_USB_COMPOSITE_DEVICE
rndis_cfg.iad.bFirstInterface = bInterfaceNumber;
UNALIGNED_PUT(bInterfaceNumber,
&rndis_cfg.iad.bFirstInterface);
#endif
#endif
#ifdef CONFIG_USB_DEVICE_NETWORK_EEM
cdc_eem_cfg.if0.bInterfaceNumber = bInterfaceNumber;
UNALIGNED_PUT(bInterfaceNumber,
&cdc_eem_cfg.if0.bInterfaceNumber);
#endif
}

Expand Down
3 changes: 2 additions & 1 deletion subsys/usb/class/usb_dfu.c
Original file line number Diff line number Diff line change
Expand Up @@ -646,7 +646,8 @@ static int dfu_custom_handle_req(struct usb_setup_packet *pSetup,

static void dfu_interface_config(u8_t bInterfaceNumber)
{
dfu_cfg.if0.bInterfaceNumber = bInterfaceNumber;
UNALIGNED_PUT(bInterfaceNumber,
&dfu_cfg.if0.bInterfaceNumber);
}

/* Configuration of the DFU Device send to the USB Driver */
Expand Down
15 changes: 8 additions & 7 deletions subsys/usb/usb_descriptor.c
Original file line number Diff line number Diff line change
Expand Up @@ -247,7 +247,8 @@ static int usb_validate_ep_cfg_data(struct usb_ep_descriptor * const ep_descr,
ep_cfg.ep_addr = idx;
}
if (!usb_dc_ep_check_cap(&ep_cfg)) {
ep_descr->bEndpointAddress = ep_cfg.ep_addr;
UNALIGNED_PUT(ep_cfg.ep_addr,
&ep_descr->bEndpointAddress);
ep_data[i].ep_addr = ep_cfg.ep_addr;
if (ep_cfg.ep_addr & USB_EP_DIR_IN) {
*requested_ep |= (1 << (idx + 16));
Expand Down Expand Up @@ -354,12 +355,12 @@ static int usb_fix_descriptor(struct usb_desc_header *head)
if (str_descr_idx) {
ascii7_to_utf16le(head);
} else {
SYS_LOG_DBG("Now the wTotalLength is %d",
(u8_t *)head - (u8_t *)cfg_descr);
cfg_descr->wTotalLength =
sys_cpu_to_le16((u8_t *)head -
(u8_t *)cfg_descr);
cfg_descr->bNumInterfaces = numof_ifaces;
u16_t dlen = (u8_t *)head - (u8_t *)cfg_descr;

SYS_LOG_DBG("Now the wTotalLength is %d", dlen);
UNALIGNED_PUT(dlen, &cfg_descr->wTotalLength);
UNALIGNED_PUT(numof_ifaces,
&cfg_descr->bNumInterfaces);
}

str_descr_idx += 1;
Expand Down