Forma canônica do endereço e aritmética do ponteiro

Nas arquiteturas compatíveis com AMD64, os endereços precisam estar em formato canônico antes de serem desreferenciados.

DeManual Intel, seção 3.3.7.1:

No modo de 64 bits, um endereço é considerado em formato canônico se os bits de endereço 63 até o bit implementado mais significativo pela microarquitetura forem configurados para todos ou todos os zeros.

Agora, o bit mais significativo implementado nos sistemas operacionais e arquiteturas atuais é o 47º bit. Isso nos deixa com um espaço de endereço de 48 bits.

Especialmente quandoASLR está ativado, os programas do usuário podem esperar receber um endereço com o conjunto de 47 bits.

Se otimizações como marcação de ponteiro forem usadas e os bits superiores forem usados para armazenar informações, o programa deverá garantir que os 48º a 63º bits sejam retornados para o que o 47º bit estivesse antes de desferir o endereço.

Mas considere este código:

int main()
{
    int* intArray = new int[100];

    int* it = intArray;

    // Fill the array with any value.
    for (int i = 0; i < 100; i++)
    {
        *it = 20;
        it++;   
    }

    delete [] intArray;
    return 0;
}

Agora considere issointArray é, diga:

0000 0000 0000 00000111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1100

Após a configuraçãoit paraintArray e aumentandoit uma vez, e considerandosizeof(int) == 4, se tornará:

0000 0000 0000 00001000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000

O 47º bit está em negrito. O que acontece aqui é que o segundo ponteiro recuperado pela aritmética do ponteiro é inválido porque não está na forma canônica. O endereço correto deve ser:

1111 1111 1111 11111000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000

Como os programas lidam com isso? Existe uma garantia do sistema operacional de que você nunca terá memória alocada cujo intervalo de endereços não varie no 47º bit?

questionAnswers(1)

yourAnswerToTheQuestion