]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.19-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 17 Feb 2022 19:07:32 +0000 (20:07 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 17 Feb 2022 19:07:32 +0000 (20:07 +0100)
added patches:
makefile.extrawarn-move-wunaligned-access-to-w-1.patch
net-usb-ax88179_178a-fix-out-of-bounds-accesses-in-rx-fixup.patch

queue-4.19/makefile.extrawarn-move-wunaligned-access-to-w-1.patch [new file with mode: 0644]
queue-4.19/net-usb-ax88179_178a-fix-out-of-bounds-accesses-in-rx-fixup.patch [new file with mode: 0644]
queue-4.19/series [new file with mode: 0644]

diff --git a/queue-4.19/makefile.extrawarn-move-wunaligned-access-to-w-1.patch b/queue-4.19/makefile.extrawarn-move-wunaligned-access-to-w-1.patch
new file mode 100644 (file)
index 0000000..9321916
--- /dev/null
@@ -0,0 +1,45 @@
+From 1cf5f151d25fcca94689efd91afa0253621fb33a Mon Sep 17 00:00:00 2001
+From: Nathan Chancellor <nathan@kernel.org>
+Date: Wed, 2 Feb 2022 16:05:16 -0700
+Subject: Makefile.extrawarn: Move -Wunaligned-access to W=1
+
+From: Nathan Chancellor <nathan@kernel.org>
+
+commit 1cf5f151d25fcca94689efd91afa0253621fb33a upstream.
+
+-Wunaligned-access is a new warning in clang that is default enabled for
+arm and arm64 under certain circumstances within the clang frontend (see
+LLVM commit below). On v5.17-rc2, an ARCH=arm allmodconfig build shows
+1284 total/70 unique instances of this warning (most of the instances
+are in header files), which is quite noisy.
+
+To keep a normal build green through CONFIG_WERROR, only show this
+warning with W=1, which will allow automated build systems to catch new
+instances of the warning so that the total number can be driven down to
+zero eventually since catching unaligned accesses at compile time would
+be generally useful.
+
+Cc: stable@vger.kernel.org
+Link: https://github.com/llvm/llvm-project/commit/35737df4dcd28534bd3090157c224c19b501278a
+Link: https://github.com/ClangBuiltLinux/linux/issues/1569
+Link: https://github.com/ClangBuiltLinux/linux/issues/1576
+Signed-off-by: Nathan Chancellor <nathan@kernel.org>
+Reviewed-by: Nick Desaulniers <ndesaulniers@google.com>
+Signed-off-by: Masahiro Yamada <masahiroy@kernel.org>
+[nathan: Fix conflict due to lack of afe956c577b2d]
+Signed-off-by: Nathan Chancellor <nathan@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ scripts/Makefile.extrawarn |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/scripts/Makefile.extrawarn
++++ b/scripts/Makefile.extrawarn
+@@ -73,5 +73,6 @@ KBUILD_CFLAGS += $(call cc-disable-warni
+ KBUILD_CFLAGS += $(call cc-disable-warning, format-zero-length)
+ KBUILD_CFLAGS += $(call cc-disable-warning, uninitialized)
+ KBUILD_CFLAGS += $(call cc-disable-warning, pointer-to-enum-cast)
++KBUILD_CFLAGS += $(call cc-disable-warning, unaligned-access)
+ endif
+ endif
diff --git a/queue-4.19/net-usb-ax88179_178a-fix-out-of-bounds-accesses-in-rx-fixup.patch b/queue-4.19/net-usb-ax88179_178a-fix-out-of-bounds-accesses-in-rx-fixup.patch
new file mode 100644 (file)
index 0000000..92680bd
--- /dev/null
@@ -0,0 +1,137 @@
+From 57bc3d3ae8c14df3ceb4e17d26ddf9eeab304581 Mon Sep 17 00:00:00 2001
+From: Jann Horn <jannh@google.com>
+Date: Wed, 26 Jan 2022 14:14:52 +0100
+Subject: net: usb: ax88179_178a: Fix out-of-bounds accesses in RX fixup
+
+From: Jann Horn <jannh@google.com>
+
+commit 57bc3d3ae8c14df3ceb4e17d26ddf9eeab304581 upstream.
+
+ax88179_rx_fixup() contains several out-of-bounds accesses that can be
+triggered by a malicious (or defective) USB device, in particular:
+
+ - The metadata array (hdr_off..hdr_off+2*pkt_cnt) can be out of bounds,
+   causing OOB reads and (on big-endian systems) OOB endianness flips.
+ - A packet can overlap the metadata array, causing a later OOB
+   endianness flip to corrupt data used by a cloned SKB that has already
+   been handed off into the network stack.
+ - A packet SKB can be constructed whose tail is far beyond its end,
+   causing out-of-bounds heap data to be considered part of the SKB's
+   data.
+
+I have tested that this can be used by a malicious USB device to send a
+bogus ICMPv6 Echo Request and receive an ICMPv6 Echo Reply in response
+that contains random kernel heap data.
+It's probably also possible to get OOB writes from this on a
+little-endian system somehow - maybe by triggering skb_cow() via IP
+options processing -, but I haven't tested that.
+
+Fixes: e2ca90c276e1 ("ax88179_178a: ASIX AX88179_178A USB 3.0/2.0 to gigabit ethernet adapter driver")
+Cc: stable@kernel.org
+Signed-off-by: Jann Horn <jannh@google.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/usb/ax88179_178a.c |   68 +++++++++++++++++++++++------------------
+ 1 file changed, 39 insertions(+), 29 deletions(-)
+
+--- a/drivers/net/usb/ax88179_178a.c
++++ b/drivers/net/usb/ax88179_178a.c
+@@ -1373,59 +1373,69 @@ static int ax88179_rx_fixup(struct usbne
+       u16 hdr_off;
+       u32 *pkt_hdr;
+-      /* This check is no longer done by usbnet */
+-      if (skb->len < dev->net->hard_header_len)
++      /* At the end of the SKB, there's a header telling us how many packets
++       * are bundled into this buffer and where we can find an array of
++       * per-packet metadata (which contains elements encoded into u16).
++       */
++      if (skb->len < 4)
+               return 0;
+-
+       skb_trim(skb, skb->len - 4);
+       memcpy(&rx_hdr, skb_tail_pointer(skb), 4);
+       le32_to_cpus(&rx_hdr);
+-
+       pkt_cnt = (u16)rx_hdr;
+       hdr_off = (u16)(rx_hdr >> 16);
++
++      if (pkt_cnt == 0)
++              return 0;
++
++      /* Make sure that the bounds of the metadata array are inside the SKB
++       * (and in front of the counter at the end).
++       */
++      if (pkt_cnt * 2 + hdr_off > skb->len)
++              return 0;
+       pkt_hdr = (u32 *)(skb->data + hdr_off);
+-      while (pkt_cnt--) {
++      /* Packets must not overlap the metadata array */
++      skb_trim(skb, hdr_off);
++
++      for (; ; pkt_cnt--, pkt_hdr++) {
+               u16 pkt_len;
+               le32_to_cpus(pkt_hdr);
+               pkt_len = (*pkt_hdr >> 16) & 0x1fff;
+-              /* Check CRC or runt packet */
+-              if ((*pkt_hdr & AX_RXHDR_CRC_ERR) ||
+-                  (*pkt_hdr & AX_RXHDR_DROP_ERR)) {
+-                      skb_pull(skb, (pkt_len + 7) & 0xFFF8);
+-                      pkt_hdr++;
+-                      continue;
+-              }
+-
+-              if (pkt_cnt == 0) {
+-                      skb->len = pkt_len;
+-                      /* Skip IP alignment pseudo header */
+-                      skb_pull(skb, 2);
+-                      skb_set_tail_pointer(skb, skb->len);
+-                      skb->truesize = pkt_len + sizeof(struct sk_buff);
+-                      ax88179_rx_checksum(skb, pkt_hdr);
+-                      return 1;
+-              }
++              if (pkt_len > skb->len)
++                      return 0;
+-              ax_skb = skb_clone(skb, GFP_ATOMIC);
+-              if (ax_skb) {
++              /* Check CRC or runt packet */
++              if (((*pkt_hdr & (AX_RXHDR_CRC_ERR | AX_RXHDR_DROP_ERR)) == 0) &&
++                  pkt_len >= 2 + ETH_HLEN) {
++                      bool last = (pkt_cnt == 0);
++
++                      if (last) {
++                              ax_skb = skb;
++                      } else {
++                              ax_skb = skb_clone(skb, GFP_ATOMIC);
++                              if (!ax_skb)
++                                      return 0;
++                      }
+                       ax_skb->len = pkt_len;
+                       /* Skip IP alignment pseudo header */
+                       skb_pull(ax_skb, 2);
+                       skb_set_tail_pointer(ax_skb, ax_skb->len);
+                       ax_skb->truesize = pkt_len + sizeof(struct sk_buff);
+                       ax88179_rx_checksum(ax_skb, pkt_hdr);
++
++                      if (last)
++                              return 1;
++
+                       usbnet_skb_return(dev, ax_skb);
+-              } else {
+-                      return 0;
+               }
+-              skb_pull(skb, (pkt_len + 7) & 0xFFF8);
+-              pkt_hdr++;
++              /* Trim this packet away from the SKB */
++              if (!skb_pull(skb, (pkt_len + 7) & 0xFFF8))
++                      return 0;
+       }
+-      return 1;
+ }
+ static struct sk_buff *
diff --git a/queue-4.19/series b/queue-4.19/series
new file mode 100644 (file)
index 0000000..d8f98fe
--- /dev/null
@@ -0,0 +1,2 @@
+makefile.extrawarn-move-wunaligned-access-to-w-1.patch
+net-usb-ax88179_178a-fix-out-of-bounds-accesses-in-rx-fixup.patch