CVE-2013-2094
Prioritize patching. It under exploitation confirmed by CISA and has a public proof of concept.
Apply updates per vendor instructions.
Summary
Falha de escalonamento de privilégio local no kernel Linux, causada por um erro de tipo de dado na função perf_swevent_init() do subsistema de performance events (perf). Qualquer usuário sem privilégios que consiga chamar a syscall perf_event_open (disponível por padrão na maioria das distribuições) pode forçar um acesso fora dos limites de um array interno do kernel e obter execução com privilégios de root. É explorada ativamente, está no catálogo KEV da CISA e tem PoC pública — apesar de exigir só acesso local, o impacto é total (confidencialidade, integridade e disponibilidade) e o pré-requisito de acesso é baixo em qualquer sistema multiusuário ou com processos não confiáveis em contêineres/sandboxes fracas.
Technical detail
O bug está em kernel/events/core.c, na função perf_swevent_init(), que trata o campo event->attr.config — um valor de 64 bits (u64) fornecido pelo usuário via struct perf_event_attr na chamada perf_event_open(). Antes da correção, o código armazenava esse valor em uma variável do tipo int (32 bits): `int event_id = event->attr.config;`. Isso trunca os 32 bits superiores do valor de 64 bits controlado pelo chamador.
A função usa event_id logo depois para validar limites (comparação contra PERF_COUNT_SW_MAX) e para indexar um array interno de contadores de software (swhash->events, referenciado também em sw_perf_event_destroy). Como a checagem de limite opera sobre o valor já truncado para 32 bits, um atacante consegue escolher um attr.config de 64 bits cujos bits baixos passam a validação, mas cujo valor real de 64 bits (ou o efeito da truncagem/sinal) resulta em um índice fora dos limites do array quando a lógica de kernel trata o valor internamente como u64 em outros pontos do código. O resultado é um acesso a memória fora dos limites do array — leitura e potencialmente escrita fora de bounds — dentro do contexto do kernel.
A classe de falha é erro de tipo/truncamento de inteiro (CWE-681 Incorrect Conversion between Numeric Types, correlato a CWE-190/CWE-197), um bug clássico de 'attacker controla o tamanho do campo, kernel usa o tipo errado para validá-lo'. O atacante controla integralmente o valor de attr.config passado no attr.type = PERF_TYPE_SOFTWARE, o que é suficiente para acionar o caminho vulnerável sem precisar de nenhuma outra capability.
A correção oficial (commit 8176cced706b5e5d15887584150764894e94e02f) é trivial em forma, mas resolve a causa raiz: troca o tipo da variável local de `int` para `u64`, eliminando a truncagem e fazendo a checagem de limites operar sobre o valor real de 64 bits fornecido pelo usuário.
How it’s exploited
O vetor é 100% local: o atacante precisa apenas de uma sessão de usuário sem privilégios (shell, processo em contêiner, aplicação comprometida) capaz de invocar a syscall perf_event_open com attr.type = PERF_TYPE_SOFTWARE e um attr.config manipulado. Não há necessidade de interação do usuário, de configuração não padrão, nem de capabilities especiais — perf_event_open para eventos de software costuma estar acessível a qualquer processo por padrão, o que é justamente o que torna essa falha crítica mesmo com AV:L.
A exploração pública demonstrada usa o acesso fora dos limites do array de contadores para corromper ou ler memória do kernel de forma controlada, e a partir daí escalar para execução com privilégios de root — o padrão típico de exploits de 'out-of-bounds no kernel via syscall exposta' documentados na época (2013) e amplamente replicados depois. A complexidade de exploração é considerada baixa: PoCs públicas existem e a CISA confirma exploração ativa registrada no catálogo KEV, o que indica uso real fora de laboratório, não apenas prova de conceito acadêmica.
O impacto final documentado é escalonamento completo de privilégio local — de usuário comum para root — o que é particularmente relevante em ambientes multiusuário, hosts compartilhados, contêineres com kernel compartilhado e qualquer cenário onde código não confiável roda como usuário de baixo privilégio no mesmo kernel.
Versions
How to protect
A correção definitiva é atualizar para um kernel Linux 3.8.9 ou posterior, que incorpora o commit 8176cced706b5e5d15887584150764894e94e02f (mudança de `int` para `u64` em perf_swevent_init). Distribuições com kernels próprios de longo prazo publicaram backports específicos — por exemplo, a RHEL/CentOS 6 corrigiu na série de pacotes kernel-2.6.32-358.6.2.el6 (RHSA-2013:0830), e o openSUSE publicou múltiplos avisos de segurança (2013-05 e 2013-06) para suas respectivas branches de kernel. Verifique o advisory da sua distribuição/branch específica para o número exato de build corrigido, já que o número de versão 'upstream' 3.8.9 não corresponde diretamente aos esquemas de versionamento de kernels distro (RHEL, SUSE, Ubuntu, Debian usam numeração própria com o patch backportado).
Como paliativo quando a atualização imediata não é viável, restringir o acesso à syscall perf_event_open via sysctl kernel.perf_event_paranoid (elevando o nível para restringir eventos de CPU/software a usuários privilegiados) reduz a superfície de exposição, mas não é uma correção — é um controle compensatório com custo operacional (ferramentas de profiling/monitoramento locais deixam de funcionar para usuários não privilegiados). Não existe mitigação via WAF ou controle de rede, porque a falha não tem componente de rede: qualquer filtro de tráfego é irrelevante aqui.
O mito a evitar: acreditar que a falta de acesso root ou a ausência de rede exposta torna o sistema seguro. A falha não depende de rede nem de privilégio prévio — qualquer processo local não confiável (inclusive dentro de contêineres compartilhando o mesmo kernel host) é vetor suficiente.
How to detect
Como o vetor é uma syscall local (perf_event_open) e não há tráfego de rede envolvido, não há assinatura de rede aplicável. Em nível de host, auditoria detalhada de syscalls (auditd/eBPF) pode registrar chamadas perf_event_open com attr.type = PERF_TYPE_SOFTWARE e valores de attr.config fora da faixa esperada de PERF_COUNT_SW_MAX, mas isso não é logado por padrão na maioria dos sistemas e exige instrumentação prévia — ou seja, sem monitoramento de syscall configurado antecipadamente, não há sinal retroativo confiável de tentativa de exploração. A presença de crashes inesperados no subsistema perf ou mensagens de kernel oops relacionadas a perf_swevent_init/perf_event pode ser indício de tentativas mal-sucedidas, mas não é um indicador definitivo.