| From bippy-5f407fcff5a0 Mon Sep 17 00:00:00 2001 |
| From: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| To: <linux-cve-announce@vger.kernel.org> |
| Reply-to: <cve@kernel.org>, <linux-kernel@vger.kernel.org> |
| Subject: CVE-2024-43897: net: drop bad gso csum_start and offset in virtio_net_hdr |
| |
| Description |
| =========== |
| |
| In the Linux kernel, the following vulnerability has been resolved: |
| |
| net: drop bad gso csum_start and offset in virtio_net_hdr |
| |
| Tighten csum_start and csum_offset checks in virtio_net_hdr_to_skb |
| for GSO packets. |
| |
| The function already checks that a checksum requested with |
| VIRTIO_NET_HDR_F_NEEDS_CSUM is in skb linear. But for GSO packets |
| this might not hold for segs after segmentation. |
| |
| Syzkaller demonstrated to reach this warning in skb_checksum_help |
| |
| offset = skb_checksum_start_offset(skb); |
| ret = -EINVAL; |
| if (WARN_ON_ONCE(offset >= skb_headlen(skb))) |
| |
| By injecting a TSO packet: |
| |
| WARNING: CPU: 1 PID: 3539 at net/core/dev.c:3284 skb_checksum_help+0x3d0/0x5b0 |
| ip_do_fragment+0x209/0x1b20 net/ipv4/ip_output.c:774 |
| ip_finish_output_gso net/ipv4/ip_output.c:279 [inline] |
| __ip_finish_output+0x2bd/0x4b0 net/ipv4/ip_output.c:301 |
| iptunnel_xmit+0x50c/0x930 net/ipv4/ip_tunnel_core.c:82 |
| ip_tunnel_xmit+0x2296/0x2c70 net/ipv4/ip_tunnel.c:813 |
| __gre_xmit net/ipv4/ip_gre.c:469 [inline] |
| ipgre_xmit+0x759/0xa60 net/ipv4/ip_gre.c:661 |
| __netdev_start_xmit include/linux/netdevice.h:4850 [inline] |
| netdev_start_xmit include/linux/netdevice.h:4864 [inline] |
| xmit_one net/core/dev.c:3595 [inline] |
| dev_hard_start_xmit+0x261/0x8c0 net/core/dev.c:3611 |
| __dev_queue_xmit+0x1b97/0x3c90 net/core/dev.c:4261 |
| packet_snd net/packet/af_packet.c:3073 [inline] |
| |
| The geometry of the bad input packet at tcp_gso_segment: |
| |
| [ 52.003050][ T8403] skb len=12202 headroom=244 headlen=12093 tailroom=0 |
| [ 52.003050][ T8403] mac=(168,24) mac_len=24 net=(192,52) trans=244 |
| [ 52.003050][ T8403] shinfo(txflags=0 nr_frags=1 gso(size=1552 type=3 segs=0)) |
| [ 52.003050][ T8403] csum(0x60000c7 start=199 offset=1536 |
| ip_summed=3 complete_sw=0 valid=0 level=0) |
| |
| Mitigate with stricter input validation. |
| |
| csum_offset: for GSO packets, deduce the correct value from gso_type. |
| This is already done for USO. Extend it to TSO. Let UFO be: |
| udp[46]_ufo_fragment ignores these fields and always computes the |
| checksum in software. |
| |
| csum_start: finding the real offset requires parsing to the transport |
| header. Do not add a parser, use existing segmentation parsing. Thanks |
| to SKB_GSO_DODGY, that also catches bad packets that are hw offloaded. |
| Again test both TSO and USO. Do not test UFO for the above reason, and |
| do not test UDP tunnel offload. |
| |
| GSO packet are almost always CHECKSUM_PARTIAL. USO packets may be |
| CHECKSUM_NONE since commit 10154dbded6d6 ("udp: Allow GSO transmit |
| from devices with no checksum offload"), but then still these fields |
| are initialized correctly in udp4_hwcsum/udp6_hwcsum_outgoing. So no |
| need to test for ip_summed == CHECKSUM_PARTIAL first. |
| |
| This revises an existing fix mentioned in the Fixes tag, which broke |
| small packets with GSO offload, as detected by kselftests. |
| |
| The Linux kernel CVE team has assigned CVE-2024-43897 to this issue. |
| |
| |
| Affected and fixed versions |
| =========================== |
| |
| Issue introduced in 5.15.165 with commit 27874ca77bd2b05a3779c7b3a5c75d8dd7f0b40f and fixed in 5.15.167 with commit 413e785a89f8bde0d4156a54b8ac2fa003c06756 |
| Issue introduced in 6.1.103 with commit 5b1997487a3f3373b0f580c8a20b56c1b64b0775 and fixed in 6.1.107 with commit f01c5e335fbb7fb612d40f14a3c02e2612a43d3b |
| Issue introduced in 6.6.44 with commit 90d41ebe0cd4635f6410471efc1dd71b33e894cf and fixed in 6.6.46 with commit 6772c4868a8e7ad5305957cdb834ce881793acb7 |
| Issue introduced in 6.10.3 with commit e9164903b8b303c34723177b02fe91e49e3c4cd7 and fixed in 6.10.5 with commit 2edbb3e8838c672cd7e247e47989df9d03fc6668 |
| |
| Please see https://www.kernel.org for a full list of currently supported |
| kernel versions by the kernel community. |
| |
| Unaffected versions might change over time as fixes are backported to |
| older supported kernel versions. The official CVE entry at |
| https://cve.org/CVERecord/?id=CVE-2024-43897 |
| will be updated if fixes are backported, please check that for the most |
| up to date information about this issue. |
| |
| |
| Affected files |
| ============== |
| |
| The file(s) affected by this issue are: |
| include/linux/virtio_net.h |
| net/ipv4/tcp_offload.c |
| net/ipv4/udp_offload.c |
| |
| |
| Mitigation |
| ========== |
| |
| The Linux kernel CVE team recommends that you update to the latest |
| stable kernel version for this, and many other bugfixes. Individual |
| changes are never tested alone, but rather are part of a larger kernel |
| release. Cherry-picking individual commits is not recommended or |
| supported by the Linux kernel community at all. If however, updating to |
| the latest release is impossible, the individual changes to resolve this |
| issue can be found at these commits: |
| https://git.kernel.org/stable/c/413e785a89f8bde0d4156a54b8ac2fa003c06756 |
| https://git.kernel.org/stable/c/f01c5e335fbb7fb612d40f14a3c02e2612a43d3b |
| https://git.kernel.org/stable/c/6772c4868a8e7ad5305957cdb834ce881793acb7 |
| https://git.kernel.org/stable/c/2edbb3e8838c672cd7e247e47989df9d03fc6668 |
| https://git.kernel.org/stable/c/89add40066f9ed9abe5f7f886fe5789ff7e0c50e |