Falhas em bibliotecas de DSP da Qualcomm expõem Android com Snapdragon a bypass de correções

Falhas em bibliotecas de DSP da Qualcomm expõem Android com Snapdragon a bypass de correções

Problemas no modelo FastRPC, em bibliotecas skeleton assinadas e no código gerado pelo Hexagon SDK permitem acionar crashes e contornar atualizações de DSP ao carregar versões antigas vulneráveis.

ComponenteQualcomm Hexagon DSP em SoCs Snapdragon, bibliotecas skeleton de DSP, FastRPC, QuRT e código gerado pelo Hexagon SDK.
VetorChamadas FastRPC para métodos de bibliotecas skeleton, com argumentos remote_arg e comprimentos controlados, além do carregamento de bibliotecas assinadas antigas por alteração de ADSP_LIBRARY_PATH.
ImpactoCrashes em bibliotecas de DSP, leitura fora dos limites de heap, cópia de memória com tamanho inconsistente e bypass de correções quando uma versão assinada vulnerável é carregada antes da biblioteca atualizada do dispositivo.
PrioridadeInventariar bibliotecas DSP expostas, restringir carregamento por lista de aprovação, validar versões assinadas, revisar acesso aos drivers RPC e aplicar atualizações de firmware e políticas SELinux quando disponíveis.
VersõesO contexto cita Snapdragon 855 e 865 para objetos dinâmicos sem assinatura no cDSP com baixos privilégios, Snapdragon 855 em aparelhos como Pixel 4, Samsung S10, Xiaomi Mi 9, LG G8 e OnePlus 7, e Hexagon SDK 3.5.1 no exemplo hexagon_nn.
ArtefatosBibliotecas e caminhos citados incluem libadsprpc.so, libcdsprpc.so, libfastcvadsp_skel.so, libhexagon_nn_skel.so, /dsp, /vendor/dsp, /vendor/lib/rfsa/adsp e /vendor/firmware.
Resumo técnico

A superfície analisada envolve o subsistema de Digital Signal Processor da Qualcomm em SoCs Snapdragon, especialmente o Hexagon DSP, que executa bibliotecas especializadas para áudio, computação, modem, sensores e outros fluxos de processamento. Em arquiteturas como a do Snapdragon 855, o SoC combina CPU Kryo, GPU Adreno, modem, processador de imagem e múltiplos DSPs dedicados. O problema central não está em um único aplicativo Android, mas na forma como chamadas remotas são encaminhadas do lado Android para bibliotecas skeleton executadas no DSP por meio do mecanismo proprietário FastRPC.

FastRPC funciona como uma camada de chamada remota entre CPU e DSP. No Android, bibliotecas como libadsprpc.so e libcdsprpc.so expõem funções para abrir sessões e invocar métodos no DSP. Essas chamadas transportam identificadores de método, escalares e arrays de argumentos remote_arg. O stub gerado pelo SDK normalmente organiza os parâmetros, mas o fluxo permite que um cliente pule essa camada e acione diretamente funções de bibliotecas skeleton, desde que conheça o índice do método e o formato esperado dos buffers. Essa característica cria uma superfície prática para fuzzing e para exploração de erros de validação.

O modelo de segurança tenta limitar a execução de código no DSP por assinatura e por domínios de proteção. Bibliotecas e componentes do QuRT são assinados, e aplicativos Android comuns não têm permissão para executar código próprio livremente no DSP. Há, porém, exceções nos SoCs Snapdragon 855 e 865 para objetos dinâmicos sem assinatura no cDSP em um domínio com baixos privilégios. Além disso, bibliotecas skeleton assinadas pela Qualcomm podem ser carregadas por um aplicativo se forem distribuídas como ativo do app e se o caminho de busca for manipulado para priorizar essa cópia. A ausência de verificação de versão nesse carregamento abre uma classe importante de bypass de correção.

Fluxo técnico

Cada processo Android que inicia uma invocação remota faz com que o QuRT crie um processo correspondente no DSP. O shell FastRPC, localizado como fastrpc_shell_0 para aDSP e fastrpc_shell_3 para cDSP, carrega bibliotecas skeleton e bibliotecas de objeto. As bibliotecas skeleton atuam como camada de unmarshalling: recebem os escalares e os remote_arg, reconstroem tipos esperados e chamam a implementação real do método. Quando a validação dessa camada é fraca, valores controlados pelo chamador podem atravessar a fronteira CPU-DSP em formato aparentemente válido, mas semanticamente inconsistente.

O ponto crítico é que os parâmetros scalars e pra são transferidos para o driver RPC e para o framework do DSP sem uma normalização forte baseada no stub. Entradas extras no array de argumentos são ignoradas pela biblioteca skeleton quando não são necessárias, e o índice do método é suficiente para direcionar a chamada. Como o nome da função, os tipos formais e a contagem de argumentos não precisam ser reapresentados em uma interface fortemente tipada, bibliotecas skeleton proprietárias tornam-se alvos convenientes para fuzzing baseado em índices e buffers.

Os exemplos em hexagon_nn, componente aberto relacionado ao Hexagon SDK 3.5.1, mostram falhas de geração de código. Em uma função que recebe uma string e retorna um identificador, o stub armazena o comprimento da string em uma entrada auxiliar de remote_arg e também no buffer de entrada. O código skeleton compara esses comprimentos como inteiros com sinal. Um valor grande interpretado como negativo pode contornar a validação e ser reutilizado como deslocamento de memória, resultando em leitura fora dos limites do heap e crash.

Outro exemplo envolve uma função que usa um buffer tanto como entrada quanto como saída. O stub separa o buffer em duas regiões e registra comprimentos auxiliares. Antes de chamar a função real, o skeleton copia o conteúdo de entrada para a saída com base no tamanho informado em uma entrada auxiliar. Como esse tamanho é controlável e as verificações podem ser contornadas com comprimento negativo, a rotina passa a operar com uma condição de cópia inconsistente. O impacto confirmado no material analisado é instabilidade e crash, não uma cadeia completa de execução arbitrária demonstrada.

A pesquisa também identificou um problema arquitetural de atualização. Bibliotecas DSP são assinadas e normalmente não podem ser modificadas, mas uma versão antiga assinada continua aceita se for localizada primeiro no caminho de busca. Como remote_handle_open procura em locais como /dsp, /vendor/dsp e /vendor/lib/rfsa/adsp, e como ADSP_LIBRARY_PATH pode receber um caminho adicional, um app consegue priorizar uma cópia antiga assinada em seu diretório de dados. Assim, uma correção presente no firmware do aparelho pode ser contornada pelo carregamento de uma versão vulnerável, desde que a assinatura ainda seja válida e não exista controle de versão ou lista de bloqueio.

Superfície afetada

A superfície é ampla porque muitos aparelhos Android baseados em Snapdragon incluem bibliotecas skeleton pré-instaladas. Algumas, como libfastcvadsp_skel.so e libscveBlobDescriptor_skel.so, aparecem em grande variedade de dispositivos. Outras são associadas a SoCs mais modernos, como libVC1DecDsp_skel.so e libsysmon_cdsp_skel.so. Há ainda bibliotecas específicas de OEM, como libedge_smooth_skel.so em Samsung S7 Edge e libdepthmap_skel.so em OnePlus 6T. A ausência de listas de aprovação ou negação por dispositivo significa que uma biblioteca destinada a um aparelho pode ser carregada em outro aparelho Qualcomm se continuar assinada e compatível com o fluxo de carga.

A segmentação por domínios de proteção no DSP reduz privilégios para objetos sem assinatura, mas não elimina o risco de bibliotecas assinadas vulneráveis. O domínio não assinado foi desenhado para aplicações gerais de computação e tem acesso limitado a drivers subjacentes e prioridades de thread. Já as bibliotecas skeleton assinadas participam do fluxo normal do framework DSP e recebem dados do cliente via FastRPC. A proteção depende, portanto, de validação robusta no unmarshalling, de controle de origem e versão da biblioteca e de políticas do sistema operacional que impeçam aplicativos de acessar drivers RPC quando isso não for necessário.

Há um limite importante: dispositivos Pixel são citados com proteção por política SELinux que bloqueia o acesso de aplicativos de terceiros e de shell ADB aos drivers DSP RPC. Essa restrição reduz a exposição prática nesses aparelhos. Em outros ambientes, a exposição depende de quais drivers RPC estão acessíveis, quais bibliotecas skeleton estão presentes, quais versões assinadas podem ser carregadas e se o fabricante restringe ou não a resolução de bibliotecas por caminho configurável.

  • SoCs Snapdragon com Hexagon DSP, incluindo configurações com aDSP e cDSP acessados por FastRPC.
  • Bibliotecas skeleton Qualcomm e de OEM em /dsp, /vendor/dsp e /vendor/lib/rfsa/adsp.
  • Aplicativos Android capazes de iniciar chamadas RPC para DSP quando a política do dispositivo permite acesso aos drivers correspondentes.
  • Cadeias de atualização em que versões antigas assinadas permanecem carregáveis sem verificação de versão ou lista de bloqueio.
Hunting e telemetria

A detecção deve começar pelo inventário de bibliotecas DSP e pela comparação entre versões esperadas no firmware e bibliotecas carregadas a partir de caminhos não padrão. O comportamento de risco não exige necessariamente um binário malicioso novo no DSP; uma biblioteca antiga e assinada pode ser suficiente para reintroduzir uma falha já corrigida. Por isso, a telemetria deve observar alterações em ADSP_LIBRARY_PATH, carregamentos de skeleton fora dos diretórios de firmware esperados e sessões FastRPC iniciadas por aplicativos que não deveriam usar aceleração DSP.

Em endpoints Android gerenciados, sinais úteis incluem crashes repetidos em processos relacionados ao DSP, falhas associadas a fastrpc_shell_0 ou fastrpc_shell_3, abertura incomum de handles RPC por apps de baixa reputação, extração de bibliotecas .so para diretórios privados de aplicativo e presença de bibliotecas skeleton Qualcomm antigas empacotadas como assets. Em engenharia de firmware, a análise deve comparar o conjunto de bibliotecas fornecido pelo OEM com versões antigas conhecidas internamente e avaliar se o carregador aceita componentes destinados a outro fabricante.

O fuzzing descrito encontrou crashes em todas as bibliotecas DSP escolhidas para teste, com centenas de crashes únicos apenas em libfastcvadsp_skel.so. Para defesa, esse dado deve orientar testes internos de robustez em bibliotecas skeleton próprias e de terceiros. O foco não deve ser reproduzir payloads, mas validar se comprimentos, índices de método, buffers de entrada e saída e handles são rejeitados antes de chegarem a operações de cópia, cálculo de deslocamento ou leitura de heap.

  • Mudanças ou valores incomuns em ADSP_LIBRARY_PATH durante a inicialização de sessões DSP.
  • Bibliotecas skeleton assinadas carregadas a partir de diretórios privados de aplicativos ou caminhos não previstos pelo firmware.
  • Crashes recorrentes vinculados a bibliotecas como libfastcvadsp_skel.so, libhexagon_nn_skel.so ou shells FastRPC.
  • Chamadas RPC para métodos skeleton por aplicativos sem necessidade funcional clara de DSP.
  • Empacotamento de bibliotecas Qualcomm ou de OEM antigas dentro de APKs, especialmente quando duplicam nomes já presentes no dispositivo.
Mitigação

A mitigação mais importante é impedir que assinatura válida seja tratada como autorização suficiente. O carregamento de bibliotecas DSP precisa combinar assinatura, versão, destino de dispositivo e política de aprovação. Uma biblioteca antiga assinada não deve substituir uma versão corrigida apenas por aparecer antes no caminho de busca. Fabricantes devem manter listas de aprovação e bloqueio por dispositivo, validar metadados de versão e rejeitar bibliotecas destinadas a outro OEM ou a outra família de firmware quando não houver compatibilidade explicitamente autorizada.

No Android, políticas SELinux devem restringir acesso aos drivers DSP RPC a processos com necessidade comprovada. O modelo citado em aparelhos Pixel mostra que bloquear terceiros e shell ADB contra esses drivers reduz bastante a superfície de ataque. Em dispositivos corporativos, MDM e EDR móvel podem complementar essa barreira monitorando APKs que carregam bibliotecas DSP próprias, solicitam acesso a recursos de aceleração incomuns ou apresentam crashes nativos repetidos após invocações de FastRPC.

Equipes que desenvolvem bibliotecas DSP ou integram componentes Qualcomm devem revisar o código skeleton gerado pelo Hexagon SDK, especialmente em funções com strings, buffers compartilhados de entrada e saída, comprimentos auxiliares e conversões com sinal. Toda validação de tamanho deve ocorrer antes de qualquer cálculo de deslocamento ou cópia de memória, e os valores duplicados entre entradas auxiliares e buffers devem ser comparados com tipos sem ambiguidade. Testes de fuzzing em emulador podem ser usados como etapa defensiva para aumentar cobertura, mas os resultados devem ser tratados como insumo de correção, não como material operacional de exploração.

A resposta operacional para um ambiente já exposto deve priorizar inventário e contenção. Primeiro, identificar quais modelos usam Snapdragon com aDSP ou cDSP acessível por FastRPC e quais bibliotecas skeleton estão presentes. Depois, verificar se há aplicativos distribuindo bibliotecas DSP próprias ou versões antigas de componentes Qualcomm. Em seguida, aplicar firmware do fabricante, revisar política de acesso aos drivers RPC e validar se uma biblioteca antiga assinada ainda consegue ser priorizada por caminho configurável. Quando houver indício de abuso, remover o aplicativo suspeito, coletar logs de crash e eventos de carregamento nativo, preservar a lista de bibliotecas extraídas pelo app e acompanhar novas falhas de DSP após a contenção.

  • Bloquear carregamento de bibliotecas skeleton por versão antiga quando já existir componente corrigido no firmware.
  • Implementar listas de aprovação e bloqueio para bibliotecas DSP por modelo, OEM e família de SoC.
  • Restringir drivers DSP RPC por SELinux e permitir acesso apenas a processos autorizados.
  • Auditar APKs que empacotam bibliotecas DSP assinadas e verificá-los contra o inventário oficial do dispositivo.
  • Revisar código gerado por Hexagon SDK para strings, buffers, comprimentos com sinal e operações de cópia.
  • Usar fuzzing defensivo em bibliotecas skeleton próprias para localizar crashes antes da distribuição em firmware.

Postar um comentário

0 Comentários