Nota
O acesso a esta página requer autorização. Podes tentar iniciar sessão ou mudar de diretório.
O acesso a esta página requer autorização. Podes tentar mudar de diretório.
Resumimos brevemente o conceito de shadow bytes e como eles podem ser usados pela implementação de tempo de execução do /fsanitize=address. Para mais detalhes, encaminhamos para a pesquisa inicial AddressSanitizer - Serebryany, et al e a documentação atual do algoritmo AddressSanitizer.
Conceito central
Cada 8 bytes no espaço de endereço virtual do seu aplicativo pode ser descrito usando um byte de sombra.
Um byte de sombra descreve quantos bytes estão atualmente acessíveis da seguinte maneira:
- 0 significa todos os 8 bytes
- 1-7 significa um a sete bytes
- Números negativos codificam o contexto para o tempo de execução a ser usado para relatar diagnósticos.
Observação
Por padrão, as entradas na memória de sombra são inicializadas a zero. Portanto, o ASan assume que a memória é endereçável por padrão, ou seja, válida para leitura e gravação. Os bytes de sombra serão preenchidos com valores diferentes de zero à medida que o programa é executado e o tempo de vida das variáveis e outras alocações chega ao fim.
Legenda de byte de sombra
Considere esta legenda de byte de sombra onde todos os números negativos são definidos:
Mapeamento - descrevendo seu espaço de endereçamento
Cada 8 bytes no espaço de endereço virtual do aplicativo alinhado "0-mod-8" pode ser mapeado para o byte de sombra que descreve esse slot no espaço de endereço virtual. Este mapeamento pode ser realizado com um simples deslocamento e adição.
Em x86:
char shadow_byte_value = *((Your_Address >> 3) + 0x30000000)
Em x64:
char shadow_byte_value = *((Your_Address >> 3) + _asan_runtime_assigned_offset)
Geração de código - testes
Considere como bytes de sombra específicos podem ser gravados, seja pelo código gerado pelo compilador, dados estáticos ou o tempo de execução. Este pseudo-código mostra como é possível gerar uma verificação que precede qualquer carregamento ou armazenamento:
ShadowAddr = (Addr >> 3) + Offset;
if (*ShadowAddr != 0) {
ReportAndCrash(Addr);
}
Ao instrumentar uma referência de memória com menos de 8 bytes de largura, a instrumentação é um pouco mais complexa. Se o valor de sombra for positivo (o que significa que apenas os primeiros k bytes na palavra de 8 bytes podem ser acessados), precisamos comparar os últimos 3 bits do endereço com k.
ShadowAddr = (Addr >> 3) + Offset;
k = *ShadowAddr;
if (k != 0 && ((Addr & 7) + AccessSize > k)) {
ReportAndCrash(Addr);
}
O tempo de execução e o código gerado pelo compilador gravam bytes de sombra. Esses bytes de sombra permitem ou revogam o acesso quando os escopos terminam ou o armazenamento é liberado. As verificações acima leem bytes de sombra que descrevem "slots" de 8 bytes no espaço de endereçamento do seu aplicativo, em um determinado momento da execução do programa. Além dessas verificações geradas explicitamente, o tempo de execução também verifica bytes de sombra depois de intercetar (ou "ganchos") muitas funções no CRT.
Para obter mais informações, consulte a lista de funções intercetadas.
Definindo bytes de sombra
Tanto o código que o compilador gera quanto o tempo de execução do AddressSanitizer podem gravar bytes de sombra. Por exemplo, o compilador pode definir bytes de sombra para permitir acesso de tamanho fixo a locais de pilha definidos em um escopo interno. O tempo de execução pode cercar variáveis globais na seção de dados com bytes de sombra.
Consulte também
Visão geral do AddressSanitizer
Problemas conhecidos do AddressSanitizer
Compilação e referência de linguagem AddressSanitizer
de referência de tempo de execução AddressSanitizer
AddressSanitizer nuvem ou testes distribuídos
Integração do depurador AddressSanitizer
Exemplos de erro AddressSanitizer