aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSalvatore Bonaccorso <carnil@debian.org>2021-01-07 21:24:59 +0100
committerSalvatore Bonaccorso <carnil@debian.org>2021-01-07 21:25:43 +0100
commitfb806ced32bb0dad9d8e8b79b1bf82e9ff2d1cee (patch)
tree633560dee92ace41ac76f954c95a44e625aa260a
parent52454a3005a387f42bb90c7ce28f1f4ed21c10cf (diff)
downloadkernel_replicant_linux-fb806ced32bb0dad9d8e8b79b1bf82e9ff2d1cee.tar.gz
kernel_replicant_linux-fb806ced32bb0dad9d8e8b79b1bf82e9ff2d1cee.tar.bz2
kernel_replicant_linux-fb806ced32bb0dad9d8e8b79b1bf82e9ff2d1cee.zip
net: cdc_ncm: correct overhead in delayed_ndp_size
Closes: #970736
-rw-r--r--debian/changelog1
-rw-r--r--debian/patches/bugfix/all/net-cdc_ncm-correct-overhead-in-delayed_ndp_size.patch89
-rw-r--r--debian/patches/series1
3 files changed, 91 insertions, 0 deletions
diff --git a/debian/changelog b/debian/changelog
index d17a2c4e2503..ad3641a67145 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -71,6 +71,7 @@ linux (5.10.5-1) UNRELEASED; urgency=medium
[ Salvatore Bonaccorso ]
* Bluetooth: Fix attempting to set RPA timeout when unsupported
(Closes: #972968)
+ * net: cdc_ncm: correct overhead in delayed_ndp_size (Closes: #970736)
-- Luca Boccassi <bluca@debian.org> Sun, 03 Jan 2021 14:55:40 +0000
diff --git a/debian/patches/bugfix/all/net-cdc_ncm-correct-overhead-in-delayed_ndp_size.patch b/debian/patches/bugfix/all/net-cdc_ncm-correct-overhead-in-delayed_ndp_size.patch
new file mode 100644
index 000000000000..cd1640950af4
--- /dev/null
+++ b/debian/patches/bugfix/all/net-cdc_ncm-correct-overhead-in-delayed_ndp_size.patch
@@ -0,0 +1,89 @@
+From: =?UTF-8?q?Jouni=20K=2E=20Sepp=C3=A4nen?= <jks@iki.fi>
+Date: Tue, 5 Jan 2021 06:52:49 +0200
+Subject: net: cdc_ncm: correct overhead in delayed_ndp_size
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+Origin: https://git.kernel.org/pub/scm/linux/kernel/git/netdev/net.git/commit?id=7a68d725e4ea384977445e0bcaed3d7de83ab5b3
+Bug-Debian: https://bugs.debian.org/970736
+
+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: 4a0e3e989d66 ("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>
+---
+ drivers/net/usb/cdc_ncm.c | 8 ++++++--
+ 1 file changed, 6 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/usb/cdc_ncm.c b/drivers/net/usb/cdc_ncm.c
+index 3b816a4731f2..5a78848db93f 100644
+--- a/drivers/net/usb/cdc_ncm.c
++++ b/drivers/net/usb/cdc_ncm.c
+@@ -1199,7 +1199,10 @@ cdc_ncm_fill_tx_frame(struct usbnet *dev, struct sk_buff *skb, __le32 sign)
+ * accordingly. Otherwise, we should check here.
+ */
+ if (ctx->drvflags & CDC_NCM_FLAG_NDP_TO_END)
+- delayed_ndp_size = ALIGN(ctx->max_ndp_size, ctx->tx_ndp_modulus);
++ delayed_ndp_size = ctx->max_ndp_size +
++ max_t(u32,
++ ctx->tx_ndp_modulus,
++ ctx->tx_modulus + ctx->tx_remainder) - 1;
+ else
+ delayed_ndp_size = 0;
+
+@@ -1410,7 +1413,8 @@ cdc_ncm_fill_tx_frame(struct usbnet *dev, struct sk_buff *skb, __le32 sign)
+ if (!(dev->driver_info->flags & FLAG_SEND_ZLP) &&
+ skb_out->len > ctx->min_tx_pkt) {
+ padding_count = ctx->tx_curr_size - skb_out->len;
+- skb_put_zero(skb_out, padding_count);
++ if (!WARN_ON(padding_count > ctx->tx_curr_size))
++ skb_put_zero(skb_out, padding_count);
+ } else if (skb_out->len < ctx->tx_curr_size &&
+ (skb_out->len % dev->maxpacket) == 0) {
+ skb_put_u8(skb_out, 0); /* force short packet */
+--
+2.30.0
+
diff --git a/debian/patches/series b/debian/patches/series
index def3d493cc98..2521b61ec1d0 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -88,6 +88,7 @@ bugfix/all/partially-revert-usb-kconfig-using-select-for-usb_co.patch
debian/makefile-do-not-check-for-libelf-when-building-oot-module.patch
bugfix/all/partially-revert-net-socket-implement-64-bit-timestamps.patch
bugfix/all/Bluetooth-Fix-attempting-to-set-RPA-timeout-when-uns.patch
+bugfix/all/net-cdc_ncm-correct-overhead-in-delayed_ndp_size.patch
# Miscellaneous features