O Google está comprometido em promover a equidade racial para as comunidades negras. Veja como.
Esta página foi traduzida pela API Cloud Translation.
Switch to English

Sanitização de Estouro Inteiro

Estouros não intencionais de números inteiros podem causar corrupção de memória ou vulnerabilidades de divulgação de informações em variáveis ​​associadas a acessos ou alocações de memória. Para combater isso, adicionamos desinfetantes de excesso de número inteiro assinados e não assinados de Clang's UndefinedBehaviorSanitizer (UBSan) para fortalecer a estrutura de mídia no Android 7.0. No Android 9, expandimos o UBSan para cobrir mais componentes e melhoramos o suporte ao sistema de compilação.

Isso foi projetado para adicionar verificações em torno de operações / instruções aritméticas - que podem estourar - para abortar com segurança um processo se ocorrer um estouro. Esses desinfetantes podem atenuar toda uma classe de vulnerabilidades de corrupção de memória e divulgação de informações, onde a causa raiz é um estouro de número inteiro, como a vulnerabilidade original Stagefright.

Exemplos e fonte

A Desinfecção por Estouro Inteiro (IntSan) é fornecida pelo compilador e adiciona instrumentação ao binário durante o tempo de compilação para detectar estouros aritméticos. É ativado por padrão em vários componentes em toda a plataforma, por exemplo /platform/external/libnl/Android.bp .

Implementação

O IntSan usa desinfetantes de excesso inteiro com e sem sinal de assinatura do UBSan. Essa atenuação é ativada em um nível por módulo. Ajuda a manter seguros os componentes críticos do Android e não deve ser desativado.

Recomendamos enfaticamente que você ative a Desinfecção por Estouro Inteiro para componentes adicionais. Os candidatos ideais são código nativo privilegiado ou código nativo que analisa a entrada não confiável do usuário. Há uma pequena sobrecarga de desempenho associada ao desinfetante que depende do uso do código e da prevalência de operações aritméticas. Espere uma pequena porcentagem de despesas gerais e teste se o desempenho é uma preocupação.

Suporte ao IntSan em makefiles

Para habilitar o IntSan em um makefile, adicione:

LOCAL_SANITIZE := integer_overflow
# Optional features
LOCAL_SANITIZE_DIAG := integer_overflow
LOCAL_SANITIZE_BLACKLIST := modulename_blacklist.txt
  • LOCAL_SANITIZE usa uma lista de desinfetantes separados por vírgula, com integer_overflow sendo um conjunto pré-empacotado de opções para os desinfetantes de estouro de número inteiro assinados e não assinados com uma lista negra padrão .
  • LOCAL_SANITIZE_DIAG ativa o modo de diagnóstico para os desinfetantes. Use o modo de diagnóstico apenas durante o teste, pois isso não interromperá estouros, negando completamente a vantagem de segurança da mitigação. Consulte Solução de problemas para obter detalhes adicionais.
  • LOCAL_SANITIZE_BLACKLIST permite especificar um arquivo de lista negra para impedir que funções e arquivos de origem sejam limpos. Consulte Solução de problemas para obter detalhes adicionais.

Se você deseja um controle mais granular, ative os desinfetantes individualmente usando um ou ambos os sinalizadores:

LOCAL_SANITIZE := signed-integer-overflow, unsigned-integer-overflow
LOCAL_SANITIZE_DIAG := signed-integer-overflow, unsigned-integer-overflow

Suporte ao IntSan em arquivos de blueprint

Para habilitar a limpeza de excesso de número inteiro em um arquivo blueprint, como /platform/external/libnl/Android.bp , adicione:

   sanitize: {
      integer_overflow: true,
      diag: {
          integer_overflow: true,
      },
      blacklist: "modulename_blacklist.txt",
   },

Como nos arquivos make, a propriedade integer_overflow é um conjunto pré-empacotado de opções para os desinfetantes de estouro inteiro assinados e não assinados, com uma lista negra padrão .

O conjunto de propriedades diag habilita o modo de diagnóstico para os desinfetantes. Use o modo de diagnóstico apenas durante o teste. O modo de diagnóstico não interrompe os estouros, o que nega completamente a vantagem de segurança da mitigação nas compilações de usuários. Consulte Solução de problemas para obter detalhes adicionais.

A propriedade blacklist permite a especificação de um arquivo de lista negra que permite aos desenvolvedores impedir que funções e arquivos de origem sejam higienizados. Consulte Solução de problemas para obter detalhes adicionais.

Para ativar os desinfetantes individualmente, use:

   sanitize: {
      misc_undefined: ["signed-integer-overflow", "unsigned-integer-overflow"],
      diag: {
          misc_undefined: ["signed-integer-overflow",
                           "unsigned-integer-overflow",],
      },
      blacklist: "modulename_blacklist.txt",
   },

Solução de problemas

Se você estiver ativando a higienização por excesso de número inteiro em novos componentes ou confiar em bibliotecas de plataformas que tiveram higienização por excesso de número inteiro, poderá encontrar alguns problemas com estouros de número inteiro benignos que causam interrupções. Você deve testar os componentes com a higienização ativada para garantir que estouros benignos possam surgir.

Para localizar abortamentos causados ​​pela higienização nas compilações de usuários, procure por falhas no SIGABRT com mensagens Abort indicando um estouro capturado pelo UBSan, como:

pid: ###, tid: ###, name: Binder:###  >>> /system/bin/surfaceflinger <<<
signal 6 (SIGABRT), code -6 (SI_TKILL), fault addr --------
Abort message: 'ubsan: sub-overflow'

O rastreamento de pilha deve incluir a função que causa o cancelamento, no entanto, os estouros que ocorrem nas funções embutidas podem não ser evidentes no rastreamento de pilha.

Para determinar com mais facilidade a causa raiz, ative o diagnóstico na biblioteca que aciona o cancelamento e tente reproduzir o erro. Com o diagnóstico ativado, o processo não será interrompido e continuará sendo executado. A não interrupção ajuda a maximizar o número de estouros benignos em um caminho de execução específico sem precisar recompilar após a correção de cada bug. Diagnostics produz uma mensagem de erro que inclui o número da linha e o arquivo de origem que causam o cancelamento:

frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp:2188:32: runtime error: unsigned integer overflow: 0 - 1 cannot be represented in type 'size_t' (aka 'unsigned long')

Depois que a operação aritmética problemática for localizada, verifique se o estouro é benigno e intencional (por exemplo, sem implicações de segurança). Você pode resolver o cancelamento do desinfetante por:

  • Refatorando o código para evitar o estouro ( exemplo )
  • Estouro explicitamente através das funções de estouro __builtin _ * _ de Clang ( exemplo )
  • Desativando a higienização na função especificando o atributo no_sanitize ( exemplo )
  • Desativando a higienização de uma função ou arquivo de origem por meio de um arquivo de lista negra ( exemplo )

Você deve usar a solução mais granular possível. Por exemplo, uma função grande com muitas operações aritméticas e uma única operação excedente deve ter a única operação refatorada em vez de toda a função na lista negra.

Padrões comuns que podem resultar em estouros benignos incluem:

  • Transmissões implícitas onde ocorre um estouro não assinado antes de serem convertidas para um tipo assinado ( exemplo )
  • Exclusões de lista vinculada que diminuem o índice de loop na exclusão ( exemplo )
  • Atribuindo um tipo não assinado a -1 em vez de especificar o valor máximo real ( exemplo )
  • Loops que decrementam um número inteiro não assinado na condição ( exemplo , exemplo )

É recomendável que os desenvolvedores garantam que, nos casos em que o desinfetante detecte um estouro, ele seja realmente benigno, sem efeitos colaterais indesejados ou implicações de segurança antes de desabilitar a desinfecção.

Desativando o IntSan

Você pode desativar o IntSan com listas negras ou atributos de função. Desative com moderação e somente ao refatorar o código não é razoável ou se houver sobrecarga de desempenho problemática.

Consulte a documentação do Clang upstream para obter mais informações sobre como desativar o IntSan com atributos de função e formatação de arquivo da lista negra . A lista negra deve ter o escopo definido para o desinfetante específico, usando nomes de seção que especificam o desinfetante de destino para evitar impactar outros desinfetantes.

Validação

Atualmente, não há teste CTS especificamente para higienização de excesso de número inteiro. Em vez disso, verifique se os testes do CTS passam com ou sem o IntSan ativado para verificar se não está afetando o dispositivo.