From: Greg Kroah-Hartman Date: Thu, 17 Feb 2022 19:03:46 +0000 (+0100) Subject: 4.14-stable patches X-Git-Tag: v4.9.303~90 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=f6d43864dd4deefe3da1b7c88b5e7af244201317;p=thirdparty%2Fkernel%2Fstable-queue.git 4.14-stable patches added patches: makefile.extrawarn-move-wunaligned-access-to-w-1.patch net-usb-ax88179_178a-fix-out-of-bounds-accesses-in-rx-fixup.patch --- diff --git a/queue-4.14/makefile.extrawarn-move-wunaligned-access-to-w-1.patch b/queue-4.14/makefile.extrawarn-move-wunaligned-access-to-w-1.patch new file mode 100644 index 00000000000..9321916edb0 --- /dev/null +++ b/queue-4.14/makefile.extrawarn-move-wunaligned-access-to-w-1.patch @@ -0,0 +1,45 @@ +From 1cf5f151d25fcca94689efd91afa0253621fb33a Mon Sep 17 00:00:00 2001 +From: Nathan Chancellor +Date: Wed, 2 Feb 2022 16:05:16 -0700 +Subject: Makefile.extrawarn: Move -Wunaligned-access to W=1 + +From: Nathan Chancellor + +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 +Reviewed-by: Nick Desaulniers +Signed-off-by: Masahiro Yamada +[nathan: Fix conflict due to lack of afe956c577b2d] +Signed-off-by: Nathan Chancellor +Signed-off-by: Greg Kroah-Hartman + +--- + 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.14/net-usb-ax88179_178a-fix-out-of-bounds-accesses-in-rx-fixup.patch b/queue-4.14/net-usb-ax88179_178a-fix-out-of-bounds-accesses-in-rx-fixup.patch new file mode 100644 index 00000000000..92680bd7204 --- /dev/null +++ b/queue-4.14/net-usb-ax88179_178a-fix-out-of-bounds-accesses-in-rx-fixup.patch @@ -0,0 +1,137 @@ +From 57bc3d3ae8c14df3ceb4e17d26ddf9eeab304581 Mon Sep 17 00:00:00 2001 +From: Jann Horn +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 + +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 +Signed-off-by: Greg Kroah-Hartman +--- + 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.14/series b/queue-4.14/series new file mode 100644 index 00000000000..d8f98fe6660 --- /dev/null +++ b/queue-4.14/series @@ -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