usb_dc_dw: Correctness: use bytewise I/O in FIFO fill
The Designware FIFO is filled in units of 32 bit words, but the buffer we are passed is not guaranteed to be a multiple of 4 bytes long, nor aligned on a 4-byte boundary. So in theory we are reading 0-3 bytes of unused garbage from the end of the array. That's currently benign on supported platforms with this hardware, which all support misaligned reads. But not all do. And the incoming arrival of memory protection opens the possibility that those extra bytes would cross a protection boundary and cause a crash or security bug. Do this right. (Note that this is fixed to little endian byte order. The Designware databook is frustratingly silent on the endianness it expects, but existing hardware I can see is definitely LE and I see a few spots in the Linux dwc2 driver that likewise assume LE). Signed-off-by: Andy Ross <andrew.j.ross@intel.com>
This commit is contained in:
parent
f591e58211
commit
eebb17ca52
@ -486,7 +486,18 @@ static int usb_dw_tx(u8_t ep, const u8_t *const data,
|
||||
* before accessing the register."
|
||||
*/
|
||||
for (i = 0; i < data_len; i += 4) {
|
||||
USB_DW_EP_FIFO(ep_idx) = *(u32_t *)(data + i);
|
||||
u32_t val = data[i];
|
||||
|
||||
if (i + 1 < data_len) {
|
||||
val |= ((u32_t)data[i+1]) << 8;
|
||||
}
|
||||
if (i + 2 < data_len) {
|
||||
val |= ((u32_t)data[i+2]) << 16;
|
||||
}
|
||||
if (i + 3 < data_len) {
|
||||
val |= ((u32_t)data[i+3]) << 24;
|
||||
}
|
||||
USB_DW_EP_FIFO(ep_idx) = val;
|
||||
}
|
||||
irq_unlock(key);
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user