ASA-2019-00365 – Linux kernel: Integer overflow ao processar blocos SACK permite negação de serviço remota (SACK Panic)


For the English version of this alert, click here.

Allele Security Alert

ASA-2019-00365

Identificador(es)

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

Título

Integer overflow ao processar blocos SACK permite negação de serviço remota (SACK Panic)

Fabricante(s)

Linux foundation

Produto(s)

Linux kernel

Versão(ões) afetada(s)

Linux >= 2.6.29

Linux kernel com o seguinte commit aplicado:

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

Versão(ões) corrigida(s)

Linux kernel stable versão 4.4.182
Linux kernel stable versão 4.9.182
Linux kernel stable versão 4.14.127
Linux kernel stable versão 4.19.52
Linux kernel stable versão 5.1.11

Linux kernel com o seguinte commit aplicado:

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

Prova de conceito

Desconhecido

Descrição

Uma falha de integer overflow foi encontrada na maneira como o subsistema de rede do kernel do Linux processava segmentos TCP de Selective Acknowledgment (SACK). Ao processar segmentos SACK, a estrutura de dados do buffer de soquete (SKB) do kernel do Linux fica fragmentada. Cada fragmento é aproximadamente do tamanho máximo do segmento TCP (MSS). Para processar com eficiência blocos SACK, o kernel do Linux mescla vários SKBs fragmentados em um, potencialmente estourando a variável que contém o número de segmentos. Um atacante remoto pode usar essa falha para travar o kernel do Linux, enviando uma sequência de segmentos SACK em uma conexão TCP com pequeno valor de TCP MSS, resultando em uma negação de serviço (DoS).

Detalhes técnicos

O Socket Buffer (SKB) é a estrutura de dados mais central usada na implementação do TCP/IP do Linux. É uma lista encadeada de buffers, que contém pacotes de rede. Essa lista pode atuar como uma fila de transmissão, fila de recebimento, fila de SACK, fila de retransmissão etc. O SKB pode armazenar os dados de pacote em fragmentos. O Linux SKB pode conter até 17 fragmentos.

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

Com cada fragmento armazenando até 32 KB em x86 (64 KB no PowerPC) de dados. Quando o pacote deve ser enviado, ele é colocado na fila de envio e seus detalhes são mantidos em uma estrutura de buffer de controle, como

    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])  */

}

Destes, os campos “tcp_gso_segs” e “tcp_gso_size” são usados para informar ao driver de dispositivo sobre segmentation offload.

Quando o segmentation offload está ativado e o mecanismo SACK também está ativado, devido à perda de pacotes e à retransmissão seletiva de alguns pacotes, o SKB pode conter vários pacotes, contados por “tcp_gso_segs”. Múltiplos SKB desse tipo na lista são mesclados em um para processar com eficiência os diferentes blocos do SACK. Envolve a movimentação de dados de um SKB para outro na lista. Durante esse movimento de dados, a estrutura do SKB pode atingir seu limite máximo de 17 fragmentos e o parâmetro “tcp_gso_segs” pode estourar e atingir a chamada BUG_ON() abaixo, resultando no problema de kernel panic.

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);

}

Um usuário remoto pode acionar esse problema definindo o Maximum Segment Size (MSS) de uma conexão TCP para o seu limite mínimo de 48 bytes e enviando uma sequência de pacotes SACK especialmente criados. O MSS mais baixo deixa apenas 8 bytes de dados por segmento, aumentando assim o número de segmentos TCP necessários para enviar todos os dados.

Note que tcp_sendmsg() constrói skbs com menos de 64KB de payload, então esse problema precisa que o SACK esteja habilitado. Blocos SACK permitem que o TCP combine vários skbs na retransmissão fila, enchendo assim os 17 fragmentos à capacidade máxima.

Solução alternativa

1 – Bloqueie conexões com um MSS baixo usando filtros. Observe que esses filtros podem quebrar conexões legítimas que dependem de um MSS baixo. Além disso, observe que essa mitigação só é efetiva se o teste TCP estiver desabilitado (ou seja, o sysctl net.ipv4.tcp_mtu_probing é definido como 0, que parece ser o valor padrão para esse sysctl).

2- Desativar o processamento do SACK (/proc/sys/net/ipv4/tcp_sack definido como 0).

Créditos

Jonathan Looney (Netflix Information Security)

Referência(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
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

Se encontrou algum erro neste alerta ou deseja uma análise compreensiva, entre em contato.

Última modificação: 23 julho 2019

Não somos responsáveis por qualquer perda de dados, corrupção de dispositivos ou qualquer outro tipo de problema devido ao uso de qualquer informação mencionada em nossos alertas de segurança.