ASA-2019-00365 – Linux kernel: Integer overflow while processing SACK blocks allows remote denial of service (SACK Panic)


Allele Security Alert

ASA-2019-00365

Identifier(s)

ASA-2019-00365, CVE-2019-11477, NFLX-2019-001

Title

Integer overflow while processing SACK blocks allows remote denial of service (SACK Panic)

Vendor(s)

Linux foundation

Product(s)

Linux kernel

Affected version(s)

Linux >= 2.6.29

Linux kernel with the following commit applied:

tcp: Try to restore large SKBs while SACK processing
https://git.kernel.org/pub/scm/linux/kernel/git/davem/net.git/commit/?id=832d11c5cd076abc0aa1eaf7be96c81d1a59ce41

Fixed version(s)

Linux kernel stable version 4.4.182
Linux kernel stable version 4.9.182
Linux kernel stable version 4.14.127
Linux kernel stable version 4.19.52
Linux kernel stable version 5.1.11

Linux kernel with the following commit applied:

tcp: limit payload size of sacked skbs
https://git.kernel.org/pub/scm/linux/kernel/git/davem/net.git/commit/?id=3b4929f65b0d8249f19a50245cd88ed1a2f78cff

Proof of concept

Unknown

Description

An integer overflow flaw was found in the way the Linux kernel’s networking subsystem processed TCP Selective Acknowledgment (SACK) segments. While processing SACK segments, the Linux kernel’s socket buffer (SKB) data structure becomes fragmented. Each fragment is about TCP maximum segment size (MSS) bytes. To efficiently process SACK blocks, the Linux kernel merges multiple fragmented SKBs into one, potentially overflowing the variable holding the number of segments. A remote attacker could use this flaw to crash the Linux kernel by sending a crafted sequence of SACK segments on a TCP connection with small value of TCP MSS, resulting in a denial of service (DoS).

Technical details

Socket Buffer (SKB) is the most central data structure used in the Linux TCP/IP implementation. It is a linked list of buffers, which holds network packets. Such list can act as a Transmission queue, Receive queue, SACK’d queue, Retransmission queue, etc. SKB can hold packet data into fragments. Linux SKB can hold up to 17 fragments.

linux/include/linux/skbuff.h
define MAX_SKB_FRAGS (65536/PAGE_SIZE + 1)  => 17

With each fragment holding up to 32KB on x86 (64KB on PowerPC) of data. When packet is due to be sent, it’s placed on the Send queue and it’s details are kept in a control buffer structure like

    linux/include/linux/skbuff.h
struct tcp_skb_cb {
__u32       seq;                    /* Starting sequence number */
__u32       end_seq;    /* SEQ + FIN + SYN + datalen */
__u32       tcp_tw_isn;
struct {
u16 tcp_gso_segs;
u16 tcp_gso_size;
};
__u8        tcp_flags;  /2* TCP header flags. (tcp[13])  */

}

Of these, ‘tcp_gso_segs’ and ‘tcp_gso_size’ fields are used to tell device driver about segmentation offload.

When Segmentation offload is on and SACK mechanism is also enabled, due to packet loss and selective retransmission of some packets, SKB could end up holding multiple packets, counted by ‘tcp_gso_segs’. Multiple such SKB in the list are merged together into one to efficiently process different SACK blocks. It involves moving data from one SKB to another in the list. During this movement of data, the SKB structure can reach its maximum limit of 17 fragments and ‘tcp_gso_segs’ parameter can overflow and hit the BUG_ON() call below resulting in the said kernel panic issue.

static bool tcp_shifted_skb (struct sock *sk, …, unsigned int pcount, …)
{

tcp_skb_pcount_add(prev, pcount);
BUG_ON(tcp_skb_pcount(skb) < pcount);   <= SACK panic
tcp_skb_pcount_add(skb, -pcount);

}

A remote user can trigger this issue by setting the Maximum Segment Size (MSS) of a TCP connection to its lowest limit of 48 bytes and sending a sequence of specially crafted SACK packets. Lowest MSS leaves merely 8 bytes of data per segment, thus increasing the number of TCP segments required to send all data.

Note that tcp_sendmsg() builds skbs with less than 64KB of payload, so this problem needs SACK to be enabled. SACK blocks allow TCP to coalesce multiple skbs in the retransmit queue, thus filling the 17 fragments to maximal capacity.

Workaround

1 – Block connections with a low MSS using one of the supplied filters. (The values in the filters are examples. You can apply a higher or lower limit, as appropriate for your environment.) Note that these filters may break legitimate connections which rely on a low MSS. Also, note that this mitigation is only effective if TCP probing is disabled (that is, the net.ipv4.tcp_mtu_probing sysctl is set to 0, which appears to be the default value for that sysctl).

2- Disable SACK processing (/proc/sys/net/ipv4/tcp_sack set to 0).

Credits

Jonathan Looney (Netflix Information Security)

Reference(s)

Linux and FreeBSD Kernel: Multiple TCP-based remote denial of service vulnerabilities
https://github.com/Netflix/security-bulletins/blob/master/advisories/third-party/2019-001.md

Linux and FreeBSD Kernel: Multiple TCP-based remote denial of
service issues
https://www.openwall.com/lists/oss-security/2019/06/17/5

TCP SACK PANIC – Kernel vulnerabilities – CVE-2019-11477, CVE-2019-11478 & CVE-2019-11479
https://access.redhat.com/security/vulnerabilities/tcpsack

SACK Panic and Other TCP Denial of Service Issues
https://wiki.ubuntu.com/SecurityTeam/KnowledgeBase/SACKPanic

CVE-2019-11477, CVE-2019-11478, CVE-2019-11479
https://blog.mikrotik.com/security/cve-2019-11477-cve-2019-11478-cve-2019-11479.html

tcp: limit payload size of sacked skbs
https://git.kernel.org/pub/scm/linux/kernel/git/davem/net.git/commit/?id=3b4929f65b0d8249f19a50245cd88ed1a2f78cff

tcp: Try to restore large SKBs while SACK processing
https://git.kernel.org/pub/scm/linux/kernel/git/davem/net.git/commit/?id=832d11c5cd076abc0aa1eaf7be96c81d1a59ce41

ASA-2019-00406 – VMware: Selective Acknowledgement (SACK) Panic
https://allelesecurity.com/asa-2019-00406/

Advisory: TCP SACK PANIC kernel vulnerability
https://community.sophos.com/kb/en-us/134237

CVE-2019-11477 - Red Hat Customer Portal
https://access.redhat.com/security/cve/CVE-2019-11477

CVE-2019-11477 | SUSE
https://www.suse.com/security/cve/CVE-2019-11477

CVE-2019-11477 in Ubuntu
https://people.canonical.com/~ubuntu-security/cve/CVE-2019-11477.html

CVE-2019-11477
https://security-tracker.debian.org/tracker/CVE-2019-11477

CVE-2019-11477
https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-11477

CVE-2019-11477
https://nvd.nist.gov/vuln/detail/CVE-2019-11477

If there is any error in this alert or you wish a comprehensive analysis, let us know.

Last modified: July 23, 2019

We are not responsible for any data loss, device corruption or any other type of issue due to the use of any information mentioned in our security alerts.