linux/drivers/net/usb
Jouni K. Seppänen 7a68d725e4 net: cdc_ncm: correct overhead in delayed_ndp_size
Aligning to tx_ndp_modulus is not sufficient because the next align
call can be cdc_ncm_align_tail, which can add up to ctx->tx_modulus +
ctx->tx_remainder - 1 bytes. This used to lead to occasional crashes
on a Huawei 909s-120 LTE module as follows:

- the condition marked /* if there is a remaining skb [...] */ is true
  so the swaps happen
- skb_out is set from ctx->tx_curr_skb
- skb_out->len is exactly 0x3f52
- ctx->tx_curr_size is 0x4000 and delayed_ndp_size is 0xac
  (note that the sum of skb_out->len and delayed_ndp_size is 0x3ffe)
- the for loop over n is executed once
- the cdc_ncm_align_tail call marked /* align beginning of next frame */
  increases skb_out->len to 0x3f56 (the sum is now 0x4002)
- the condition marked /* check if we had enough room left [...] */ is
  false so we break out of the loop
- the condition marked /* If requested, put NDP at end of frame. */ is
  true so the NDP is written into skb_out
- now skb_out->len is 0x4002, so padding_count is minus two interpreted
  as an unsigned number, which is used as the length argument to memset,
  leading to a crash with various symptoms but usually including

> Call Trace:
>  <IRQ>
>  cdc_ncm_fill_tx_frame+0x83a/0x970 [cdc_ncm]
>  cdc_mbim_tx_fixup+0x1d9/0x240 [cdc_mbim]
>  usbnet_start_xmit+0x5d/0x720 [usbnet]

The cdc_ncm_align_tail call first aligns on a ctx->tx_modulus
boundary (adding at most ctx->tx_modulus-1 bytes), then adds
ctx->tx_remainder bytes. Alternatively, the next alignment call can
occur in cdc_ncm_ndp16 or cdc_ncm_ndp32, in which case at most
ctx->tx_ndp_modulus-1 bytes are added.

A similar problem has occurred before, and the code is nontrivial to
reason about, so add a guard before the crashing call. By that time it
is too late to prevent any memory corruption (we'll have written past
the end of the buffer already) but we can at least try to get a warning
written into an on-disk log by avoiding the hard crash caused by padding
past the buffer with a huge number of zeros.

Signed-off-by: Jouni K. Seppänen <jks@iki.fi>
Fixes: 4a0e3e989d ("cdc_ncm: Add support for moving NDP to end of NCM frame")
Link: https://bugzilla.kernel.org/show_bug.cgi?id=209407
Reported-by: kernel test robot <lkp@intel.com>
Reviewed-by: Bjørn Mork <bjorn@mork.no>
Signed-off-by: David S. Miller <davem@davemloft.net>
2021-01-05 16:49:04 -08:00
..
aqc111.c net: usb: switch to dev_get_tstats64 and remove usbnet_get_stats64 alias 2020-11-12 14:58:27 -08:00
aqc111.h net: usb: aqc111: Use the correct style for SPDX License Identifier 2019-11-27 11:27:01 -08:00
asix_common.c net: usb: Fix uninit-was-stored issue in asix_read_phy_addr() 2020-08-27 07:37:19 -07:00
asix_devices.c net: usb: switch to dev_get_tstats64 and remove usbnet_get_stats64 alias 2020-11-12 14:58:27 -08:00
asix.h treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 13 2019-05-21 11:28:45 +02:00
ax88172a.c net: usb: switch to dev_get_tstats64 and remove usbnet_get_stats64 alias 2020-11-12 14:58:27 -08:00
ax88179_178a.c net: usb: switch to dev_get_tstats64 and remove usbnet_get_stats64 alias 2020-11-12 14:58:27 -08:00
catc.c treewide: Use fallthrough pseudo-keyword 2020-08-23 17:36:59 -05:00
cdc_eem.c treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 13 2019-05-21 11:28:45 +02:00
cdc_ether.c net: cdc_ether: export usbnet_cdc_update_filter 2020-07-17 12:42:47 -07:00
cdc_mbim.c net: usb: switch to dev_get_tstats64 and remove usbnet_get_stats64 alias 2020-11-12 14:58:27 -08:00
cdc_ncm.c net: cdc_ncm: correct overhead in delayed_ndp_size 2021-01-05 16:49:04 -08:00
cdc_subset.c treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 13 2019-05-21 11:28:45 +02:00
cdc-phonet.c net: usb: convert comma to semicolon 2020-12-09 16:23:08 -08:00
ch9200.c net: ch9200: remove unnecessary return 2020-01-07 13:30:36 -08:00
cx82310_eth.c cx82310_eth: fix error return code in cx82310_bind() 2020-11-16 15:23:44 -08:00
dm9601.c net: usb: switch to dev_get_tstats64 and remove usbnet_get_stats64 alias 2020-11-12 14:58:27 -08:00
gl620a.c treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 13 2019-05-21 11:28:45 +02:00
hso.c usb: hso: remove bogus check for EINPROGRESS 2020-08-05 17:43:39 -07:00
huawei_cdc_ncm.c net: huawei_cdc_ncm: remove redundant assignment to variable ret 2020-05-10 11:13:07 -07:00
int51x1.c net: usb: switch to dev_get_tstats64 and remove usbnet_get_stats64 alias 2020-11-12 14:58:27 -08:00
ipheth.c usbnet: ipheth: fix connectivity with iOS 14 2020-11-21 14:01:34 -08:00
kalmia.c net: kalmia: fix memory leaks 2019-08-18 13:03:21 -07:00
kaweth.c net: usb: kaweth: Remove last user of kaweth_control() 2020-09-29 14:02:54 -07:00
Kconfig r8153_ecm: avoid to be prior to r8152 driver 2020-11-19 08:23:46 -08:00
lan78xx.c net: usb: lan78xx: Remove lots of set but unused 'ret' variables 2020-11-03 16:37:44 -08:00
lan78xx.h
lg-vl600.c net: usb: Delete unnecessary checks before the macro call “dev_kfree_skb” 2019-08-22 16:22:03 -07:00
Makefile r8153_ecm: avoid to be prior to r8152 driver 2020-11-19 08:23:46 -08:00
mcs7830.c net: usb: switch to dev_get_tstats64 and remove usbnet_get_stats64 alias 2020-11-12 14:58:27 -08:00
net1080.c net: usb: net1080: Remove in_interrupt() comment 2020-09-29 14:02:54 -07:00
pegasus.c USB/PHY/Thunderbolt driver patches for 5.10-rc1 2020-10-15 09:51:18 -07:00
pegasus.h treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 500 2019-06-19 17:09:55 +02:00
plusb.c treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 13 2019-05-21 11:28:45 +02:00
qmi_wwan.c net: usb: qmi_wwan: add Quectel EM160R-GL 2021-01-04 13:37:43 -08:00
r8152.c net/usb/r8153_ecm: support ECM mode for RTL8153 2020-11-05 16:58:48 -08:00
r8153_ecm.c net/usb/r8153_ecm: support ECM mode for RTL8153 2020-11-05 16:58:48 -08:00
rndis_host.c net: usb: switch to dev_get_tstats64 and remove usbnet_get_stats64 alias 2020-11-12 14:58:27 -08:00
rtl8150.c net: usb: rtl8150: don't incorrectly assign random MAC addresses 2020-10-18 12:57:30 -07:00
sierra_net.c net: usb: switch to dev_get_tstats64 and remove usbnet_get_stats64 alias 2020-11-12 14:58:27 -08:00
smsc75xx.c net: usb: switch to dev_get_tstats64 and remove usbnet_get_stats64 alias 2020-11-12 14:58:27 -08:00
smsc75xx.h treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 13 2019-05-21 11:28:45 +02:00
smsc95xx.c net: usb: switch to dev_get_tstats64 and remove usbnet_get_stats64 alias 2020-11-12 14:58:27 -08:00
smsc95xx.h treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 13 2019-05-21 11:28:45 +02:00
sr9700.c net: usb: switch to dev_get_tstats64 and remove usbnet_get_stats64 alias 2020-11-12 14:58:27 -08:00
sr9700.h treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 500 2019-06-19 17:09:55 +02:00
sr9800.c net: usb: switch to dev_get_tstats64 and remove usbnet_get_stats64 alias 2020-11-12 14:58:27 -08:00
sr9800.h
usbnet.c usbnet: switch to core handling of rx/tx byte/packet counters 2020-11-12 14:58:27 -08:00
zaurus.c treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 13 2019-05-21 11:28:45 +02:00