Skip to content

Commit 2a9a196

Browse files
ForstPaolo Abeni
authored andcommitted
usbnet: ipheth: refactor NCM datagram loop
Introduce an rx_error label to reduce repetitions in the header signature checks. Store wDatagramIndex and wDatagramLength after endianness conversion to avoid repeated le16_to_cpu() calls. Rewrite the loop to return on a null trailing DPE, which is required by the CDC NCM spec. In case it is missing, fall through to rx_error. This change does not fix any particular issue. Its purpose is to simplify a subsequent commit that fixes a potential OoB read by limiting the maximum amount of processed DPEs. Cc: [email protected] # 6.5.x Signed-off-by: Foster Snowhill <[email protected]> Reviewed-by: Jakub Kicinski <[email protected]> Signed-off-by: Paolo Abeni <[email protected]>
1 parent 86586dc commit 2a9a196

File tree

1 file changed

+23
-19
lines changed

1 file changed

+23
-19
lines changed

drivers/net/usb/ipheth.c

Lines changed: 23 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -213,9 +213,9 @@ static int ipheth_rcvbulk_callback_ncm(struct urb *urb)
213213
struct usb_cdc_ncm_ndp16 *ncm0;
214214
struct usb_cdc_ncm_dpe16 *dpe;
215215
struct ipheth_device *dev;
216+
u16 dg_idx, dg_len;
216217
int retval = -EINVAL;
217218
char *buf;
218-
int len;
219219

220220
dev = urb->context;
221221

@@ -227,39 +227,43 @@ static int ipheth_rcvbulk_callback_ncm(struct urb *urb)
227227
ncmh = urb->transfer_buffer;
228228
if (ncmh->dwSignature != cpu_to_le32(USB_CDC_NCM_NTH16_SIGN) ||
229229
/* On iOS, NDP16 directly follows NTH16 */
230-
ncmh->wNdpIndex != cpu_to_le16(sizeof(struct usb_cdc_ncm_nth16))) {
231-
dev->net->stats.rx_errors++;
232-
return retval;
233-
}
230+
ncmh->wNdpIndex != cpu_to_le16(sizeof(struct usb_cdc_ncm_nth16)))
231+
goto rx_error;
234232

235233
ncm0 = urb->transfer_buffer + sizeof(struct usb_cdc_ncm_nth16);
236-
if (ncm0->dwSignature != cpu_to_le32(USB_CDC_NCM_NDP16_NOCRC_SIGN)) {
237-
dev->net->stats.rx_errors++;
238-
return retval;
239-
}
234+
if (ncm0->dwSignature != cpu_to_le32(USB_CDC_NCM_NDP16_NOCRC_SIGN))
235+
goto rx_error;
240236

241237
dpe = ncm0->dpe16;
242-
while (le16_to_cpu(dpe->wDatagramIndex) != 0 &&
243-
le16_to_cpu(dpe->wDatagramLength) != 0) {
244-
if (le16_to_cpu(dpe->wDatagramIndex) < IPHETH_NCM_HEADER_SIZE ||
245-
le16_to_cpu(dpe->wDatagramIndex) >= urb->actual_length ||
246-
le16_to_cpu(dpe->wDatagramLength) > urb->actual_length -
247-
le16_to_cpu(dpe->wDatagramIndex)) {
238+
while (true) {
239+
dg_idx = le16_to_cpu(dpe->wDatagramIndex);
240+
dg_len = le16_to_cpu(dpe->wDatagramLength);
241+
242+
/* Null DPE must be present after last datagram pointer entry
243+
* (3.3.1 USB CDC NCM spec v1.0)
244+
*/
245+
if (dg_idx == 0 && dg_len == 0)
246+
return 0;
247+
248+
if (dg_idx < IPHETH_NCM_HEADER_SIZE ||
249+
dg_idx >= urb->actual_length ||
250+
dg_len > urb->actual_length - dg_idx) {
248251
dev->net->stats.rx_length_errors++;
249252
return retval;
250253
}
251254

252-
buf = urb->transfer_buffer + le16_to_cpu(dpe->wDatagramIndex);
253-
len = le16_to_cpu(dpe->wDatagramLength);
255+
buf = urb->transfer_buffer + dg_idx;
254256

255-
retval = ipheth_consume_skb(buf, len, dev);
257+
retval = ipheth_consume_skb(buf, dg_len, dev);
256258
if (retval != 0)
257259
return retval;
258260

259261
dpe++;
260262
}
261263

262-
return 0;
264+
rx_error:
265+
dev->net->stats.rx_errors++;
266+
return retval;
263267
}
264268

265269
static void ipheth_rcvbulk_callback(struct urb *urb)

0 commit comments

Comments
 (0)