Use after free in SNDRV_CTL_IOCTL_ELEM in Linux Kernel
Prioritize patching. It under exploitation confirmed by CISA and has a public proof of concept.
Apply updates per vendor instructions.
Summary
Use-after-free no subsistema de controle ALSA (sound/core/control_compat.c) do kernel Linux, explorável por um usuário local sem privilégios via ioctls de compatibilidade 32 bits (SNDRV_CTL_IOCTL_ELEM_READ32/WRITE32) sobre um dispositivo /dev/snd/controlCx. A falha foi descoberta por um pesquisador do Google (Clement Lecigne) e está no catálogo KEV da CISA com exploração confirmada e PoC pública — o que a torna relevante mesmo com EPSS baixo, porque é um caminho clássico de escalada local para root em sistemas com ALSA habilitado (praticamente todos os desktops/servidores Linux com áudio e muitos dispositivos embarcados/Android).
Technical detail
O bug é uma race condition / use-after-free (CWE-416) causada por bloqueio ausente. O caminho 64 bits (snd_ctl_elem_read_user, em sound/core/control.c) adquire corretamente o rwsem card->controls_rwsem antes de chamar snd_ctl_elem_read(), que resolve o snd_kcontrol correspondente ao ID informado pelo usuário e chama seus callbacks get/put. O caminho de compatibilidade 32 bits em sistema 64 bits, porém — ctl_elem_write_read() em sound/core/control_compat.c, acionado por SNDRV_CTL_IOCTL_ELEM_READ32/WRITE32 — chamava snd_ctl_elem_read()/snd_ctl_elem_write() sem adquirir esse rwsem.
Sem a trava, um segundo thread/processo pode remover ou alterar o snd_kcontrol referenciado (por exemplo via remoção de um controle de mixer, hot-unplug de dispositivo de áudio, ou outra operação concorrente sobre a mesma card) entre o momento em que o kctl é localizado e o momento em que seus callbacks (kctl->get / kctl->put) são invocados. Isso libera a estrutura kcontrol enquanto ainda há um ponteiro em uso, criando a janela clássica de UAF: o atacante controla o timing da corrida (via múltiplas threads chamando os ioctls) e, em exploits de UAF no kernel, tipicamente também controla o conteúdo do objeto realocado no mesmo slot de memória para sequestrar ponteiros de função ou estruturas de controle, obtendo execução de código em modo kernel (ring 0).
A correção upstream (commit 56b88b50565cd8b946a2d00b0c83927b7ebb055e) reestrutura o código movendo a aquisição do rwsem para dentro de snd_ctl_elem_read(), unificando os caminhos 64 e 32 bits sob a mesma disciplina de lock; um segundo commit (becf9e5d553c2389d857a3c178ce80fdb34a02e1) refatora snd_ctl_elem_write() de forma equivalente. Para ramos estáveis antigos (5.12 e anteriores), os mantenedores aplicaram um patch mais simples que apenas adiciona down_read()/up_read() e down_write()/up_write() diretamente em ctl_elem_read_user() e ctl_elem_write_user() dentro de control_compat.c, produzindo o mesmo efeito sem a reestruturação maior.
How it’s exploited
O vetor é local: o atacante precisa conseguir abrir um nó de dispositivo /dev/snd/controlCx e emitir os ioctls SNDRV_CTL_IOCTL_ELEM_READ/WRITE em modo de compatibilidade 32 bits (kernel 64 bits com CONFIG_COMPAT, ou processo 32 bits rodando sob syscalls compat) — não há indicação nas fontes de que a variante 64 bits nativa seja vulnerável, já que ali o lock já era adquirido corretamente antes da correção. Em muitas distribuições esses dispositivos de controle ALSA são acessíveis a usuários comuns (grupo audio ou permissões mais abertas), o que reduz a barreira de pré-requisito de privilégio — condizente com PR:L no vetor CVSS.
Na prática, a exploração exige ganhar a corrida: uma thread aciona repetidamente o ioctl de leitura/escrita de elemento enquanto outra força a remoção/realocação do snd_kcontrol referenciado (por exemplo manipulando a topologia de controles da placa de som), de modo que o objeto seja liberado entre a localização do kctl e a chamada do seu callback. Exploração confiável de UAF em kernel normalmente combina isso com técnicas de heap grooming para controlar o que ocupa a memória liberada, elevando de uma corrupção de memória para controle de fluxo de execução em modo kernel.
O CVSS de 7.9 (AV:A, AC:H, PR:L) reflete complexidade alta de ataque — é preciso ganhar uma race condition, não apenas emitir uma chamada. Mesmo assim, a presença no catálogo KEV da CISA indica exploração confirmada em campo, e a atribuição da descoberta a um pesquisador de threat intelligence do Google é consistente com uso da falha em cadeias de escalada de privilégio local, tipicamente após um comprometimento inicial ou em contexto de spyware/malware que já tem execução de código em espaço de usuário e busca root/ring0.
Versions
How to protect
Atualizar o kernel para uma versão que inclua os commits de correção é o único remédio real: no ramo mainline, os commits 56b88b50565cd8b946a2d00b0c83927b7ebb055e e becf9e5d553c2389d857a3c178ce80fdb34a02e1; em ramos estáveis mais antigos (5.12 e anteriores), o patch equivalente que adiciona down_read()/down_write() em control_compat.c. Distribuições publicaram seus próprios backports — por exemplo o Debian LTS corrigiu no pacote linux para a série 4.19 (DLA-3403-1, versão 4.19.282-1); confira o advisory da sua distribuição para a versão de pacote específica corrigida, pois as fontes aqui não cobrem todas as distribuições.
Como paliativo sem atualizar o kernel, restringir o acesso aos nós /dev/snd/controlCx (removendo usuários não confiáveis do grupo audio ou aplicando ACLs mais restritivas) reduz a superfície, mas não elimina o risco para quem já tem esse acesso — e áudio costuma ser considerado funcionalidade legítima de usuário comum, então essa mitigação tem custo de usabilidade real. Desabilitar CONFIG_COMPAT (suporte a syscalls 32 bits) removeria o caminho vulnerável específico descrito nas fontes, mas é uma mudança de configuração de kernel que quebra compatibilidade com binários/processos 32 bits — inviável na maioria dos sistemas de produção sem testes extensivos.
Não existe mitigação via WAF ou controle de rede, já que a falha é local e não depende de tráfego de rede (apesar do vetor CVSS indicar AV:A). Restringir acesso via seccomp/apparmor aos ioctls SNDRV_CTL_IOCTL_ELEM_READ32/WRITE32 é uma opção de controle compensatório mais cirúrgica que desabilitar compat inteiramente, mas exige política customizada e não foi validada nas fontes consultadas.
How to detect
Não há uma assinatura de rede a procurar, pois a exploração é inteiramente local via ioctl em /dev/snd/controlCx. Sinais indiretos incluem: relatórios de crash do kernel (dmesg/kdump) com KASAN ou 'use-after-free' referenciando sound/core/control_compat.c, snd_ctl_elem_read ou snd_ctl_elem_write; chamadas de auditoria (auditd/seccomp) para os ioctls SNDRV_CTL_IOCTL_ELEM_READ32 e SNDRV_CTL_IOCTL_ELEM_WRITE32 emitidas por processos rodando em modo de compatibilidade 32 bits, especialmente em alta frequência ou concorrência com operações de hot-plug/remoção de dispositivos de som; e monitoramento de escalonamento de privilégio inesperado (processo não privilegiado obtendo capacidades de root) em hosts onde ALSA está acessível a usuários comuns. Sem essas fontes de log específicas habilitadas, não há sinal confiável de tentativa de exploração.