Google is committed to advancing racial equity for Black communities. See how.
Esta página foi traduzida pela API Cloud Translation.
Switch to English

Sanitização de estouro de inteiro

Estouros de inteiros não intencionais 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 o UndefinedBehaviorSanitizer (UBSan) assinado e não assinado, desinfetantes de estouro de inteiro 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 do sistema de construção para ele.

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 sanitizantes podem mitigar uma classe inteira 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 Stagefright original.

Exemplos e fonte

O Integer Overflow Sanitization (IntSan) é fornecido pelo compilador e adiciona instrumentação ao binário durante o tempo de compilação para detectar estouros aritméticos. Ele é habilitado por padrão em vários componentes em toda a plataforma, por exemplo /platform/external/libnl/Android.bp .

Implementação

IntSan usa sanitizadores de estouro de inteiros assinados e não assinados do UBSan. Essa mitigação é ativada em um nível por módulo. Isso ajuda a manter os componentes críticos do Android seguros e não deve ser desativado.

Recomendamos que você habilite o Integer Overflow Sanitization para componentes adicionais. Os candidatos ideais são código nativo privilegiado ou código nativo que analisa a entrada de usuário não confiável. Há uma pequena sobrecarga de desempenho associada ao sanitizer que depende do uso do código e da prevalência de operações aritméticas. Espere uma pequena porcentagem de overhead e teste se o desempenho é uma preocupação.

Suportando IntSan em makefiles

Para habilitar IntSan em um makefile, adicione:

LOCAL_SANITIZE := integer_overflow
# Optional features
LOCAL_SANITIZE_DIAG := integer_overflow
LOCAL_SANITIZE_BLACKLIST := modulename_blacklist.txt
  • LOCAL_SANITIZE leva uma lista separada por vírgulas de desinfetantes, com integer_overflow sendo um conjunto pré-empacotado de opções para desinfetantes de estouro de inteiros assinados e não assinados individuais com uma lista negra padrão .
  • LOCAL_SANITIZE_DIAG ativa o modo de diagnóstico para os sanitizantes. Use o modo de diagnóstico apenas durante o teste, pois isso não abortará em estouros, anulando completamente a vantagem de segurança da mitigação. Consulte Solução de problemas para obter detalhes adicionais.
  • LOCAL_SANITIZE_BLACKLIST permite que você especifique um arquivo de lista negra para evitar que funções e arquivos de origem sejam limpos. Consulte Solução de problemas para obter detalhes adicionais.

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

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

Apoiando IntSan em arquivos de blueprint

Para ativar a sanitização de estouro de inteiro em um arquivo de blueprint, como /platform/external/libnl/Android.bp , adicione:

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

Assim como acontece com os arquivos make, a propriedade integer_overflow é um conjunto pré-empacotado de opções para os sanitizadores de estouro de inteiros assinados e não assinados individuais com uma lista negra padrão .

O diag conjunto de propriedades permite modo de diagnóstico para os desinfetantes. Use o modo de diagnóstico apenas durante o teste. O modo de diagnóstico não aborta em estouros, o que nega completamente a vantagem de segurança da mitigação em compilações de usuário. 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 limpos. Consulte Solução de problemas para obter detalhes adicionais.

Para ativar os higienizadores 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 habilitando a sanitização de estouro de inteiros em novos componentes, ou confiar em bibliotecas de plataforma que tiveram sanitização de estouro de inteiros, você pode encontrar alguns problemas com estouros de inteiros benignos causando abortos. Você deve testar os componentes com a higienização ativada para garantir que transbordamentos benignos possam surgir.

Para encontrar abortos causados ​​por sanitização em compilações de usuário, pesquise por SIGABRT travamentos com mensagens de aborto 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 aborto; no entanto, estouros que ocorrem em funções embutidas podem não ser evidentes no rastreamento de pilha.

Para determinar a causa raiz com mais facilidade, ative os diagnósticos na biblioteca que acionam a interrupção e tente reproduzir o erro. Com o diagnóstico habilitado, o processo não será abortado e continuará em execução. Não abortar ajuda a maximizar o número de transbordamentos benignos em um determinado caminho de execução sem ter que recompilar após corrigir cada bug. O diagnóstico produz uma mensagem de erro que inclui o número da linha e o arquivo de origem que causou o aborto:

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, certifique-se de que o estouro seja benigno e intencional (por exemplo, não tem implicações de segurança). Você pode resolver o aborto do higienizador:

  • Refatorando o código para evitar o estouro ( exemplo )
  • Overflow explicitamente por meio das funções de overflow __builtin _ * _ do Clang ( exemplo )
  • Desativando a higienização na função especificando o atributo no_sanitize ( exemplo )
  • Desativar 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 de estouro deve ter a única operação refatorada em vez de toda a função na lista negra.

Os padrões comuns que podem resultar em transbordamentos benignos incluem:

  • Casts implícitos onde ocorre um estouro não assinado antes de ser convertido para um tipo assinado ( exemplo )
  • Exclusões de lista ligada que diminui o índice de loop na exclusão ( exemplo )
  • Atribuir um tipo sem sinal a -1 em vez de especificar o valor máximo real ( exemplo )
  • Loops que diminuem um número inteiro sem sinal na condição ( exemplo , exemplo )

É recomendado que os desenvolvedores garantam que os casos em que o higienizador detecta um estouro sejam realmente benignos, sem efeitos colaterais indesejados ou implicações de segurança, antes de desabilitar a higienização.

Desativando IntSan

Você pode desativar o IntSan com listas negras ou atributos de função. Desative moderadamente e apenas quando a refatoração do código não for razoável ou se houver sobrecarga de desempenho problemática.

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

Validação

Atualmente, não há nenhum teste CTS especificamente para Sanitização de estouro de número inteiro. Em vez disso, certifique-se de que os testes CTS sejam aprovados com ou sem IntSan habilitado para verificar se ele não está afetando o dispositivo.