mirror of
https://github.com/Fishwaldo/u-boot.git
synced 2025-03-21 14:41:31 +00:00
usb: dwc2: Fix out-of-bounds access, fix chunk size
Fix two errors in transfer len calculation, move loop invariant code out of loop. If xfer_len is equal to CONFIG_DWC2_MAX_TRANSFER_SIZE (or slightly smaller), the xfer_len will be to large, e.g.: xfer_len = MAX_TRANSFER_SIZE = 65535 max packet size = 512 => num_packets = 128 => IN xfer_len = 65536 For OUT transactions larger than (65536 - mps) bytes, the xfer_len determination is quite awkward, it is only correct due to: - max_packet_size for control/bulk/interrupt is required to be power-of-two. - (CONFIG_DWC2_MAX_TRANSFER_SIZE + 1) % max-packet-size is zero for all allowed (2^3 ... 2^9) packet sizes As the max xfer len is loop invariant, it can be moved out of the loop. Signed-off-by: Stefan Brüns <stefan.bruens@rwth-aachen.de>
This commit is contained in:
parent
12f229ea8f
commit
56a7bbd741
1 changed files with 15 additions and 15 deletions
|
@ -786,34 +786,34 @@ int chunk_msg(struct dwc2_priv *priv, struct usb_device *dev,
|
|||
uint32_t xfer_len;
|
||||
uint32_t num_packets;
|
||||
int stop_transfer = 0;
|
||||
uint32_t max_xfer_len;
|
||||
|
||||
debug("%s: msg: pipe %lx pid %d in %d len %d\n", __func__, pipe, *pid,
|
||||
in, len);
|
||||
|
||||
max_xfer_len = CONFIG_DWC2_MAX_PACKET_COUNT * max;
|
||||
if (max_xfer_len > CONFIG_DWC2_MAX_TRANSFER_SIZE)
|
||||
max_xfer_len = CONFIG_DWC2_MAX_TRANSFER_SIZE;
|
||||
if (max_xfer_len > DWC2_DATA_BUF_SIZE)
|
||||
max_xfer_len = DWC2_DATA_BUF_SIZE;
|
||||
|
||||
/* Make sure that max_xfer_len is a multiple of max packet size. */
|
||||
num_packets = max_xfer_len / max;
|
||||
max_xfer_len = num_packets * max;
|
||||
|
||||
do {
|
||||
/* Initialize channel */
|
||||
dwc_otg_hc_init(regs, DWC2_HC_CHANNEL, dev, devnum, ep, in,
|
||||
eptype, max);
|
||||
|
||||
xfer_len = len - done;
|
||||
if (xfer_len > CONFIG_DWC2_MAX_TRANSFER_SIZE)
|
||||
xfer_len = CONFIG_DWC2_MAX_TRANSFER_SIZE - max + 1;
|
||||
if (xfer_len > DWC2_DATA_BUF_SIZE)
|
||||
xfer_len = DWC2_DATA_BUF_SIZE - max + 1;
|
||||
|
||||
/* Make sure that xfer_len is a multiple of max packet size. */
|
||||
if (xfer_len > 0) {
|
||||
if (xfer_len > max_xfer_len)
|
||||
xfer_len = max_xfer_len;
|
||||
else if (xfer_len > max)
|
||||
num_packets = (xfer_len + max - 1) / max;
|
||||
if (num_packets > CONFIG_DWC2_MAX_PACKET_COUNT) {
|
||||
num_packets = CONFIG_DWC2_MAX_PACKET_COUNT;
|
||||
xfer_len = num_packets * max;
|
||||
}
|
||||
} else {
|
||||
else
|
||||
num_packets = 1;
|
||||
}
|
||||
|
||||
if (in)
|
||||
xfer_len = num_packets * max;
|
||||
|
||||
debug("%s: chunk: pid %d xfer_len %u pkts %u\n", __func__,
|
||||
*pid, xfer_len, num_packets);
|
||||
|
|
Loading…
Add table
Reference in a new issue