É tarefa do software (sistema operacional) detectar estouros de pilha ou é detectado um estouro de pilha no hardware, causando uma exceção na CPU?
É tarefa do software (sistema operacional) detectar estouros de pilha ou é detectado um estouro de pilha no hardware, causando uma exceção na CPU?
Respostas:
Pode ser software ou hardware, ou ambos, ou nenhum.
Existem dois tipos de estouro: estouro ao aumentar a pilha (ao inserir uma função) e estouro ao acessar uma matriz na pilha. Estouros ao aumentar a pilha podem ser detectados fazendo uma verificação de limites na entrada da função, para verificar se há espaço suficiente (e sinalizar um erro ou aumentar a pilha, se não houver). Estouros ao acessar uma matriz na pilha são apenas um problema em idiomas de baixo nível que não verificam os limites da matriz; a solução existe para verificar os limites da matriz.
Essas abordagens de software têm a vantagem de funcionar de maneira totalmente confiável: você pode ter certeza de que qualquer excesso de pilha será detectado. A desvantagem é que eles aumentam o tamanho do código e o tempo de execução. O hardware pode ajudar, fornecendo um método para detectar a maioria dos transbordamentos sem nenhum custo, desde que não ocorra transbordamento. Em uma arquitetura com uma MMU ¹, o ambiente de tempo de execução pode organizar o mapeamento da pilha em um limite de página, com a próxima página permanecendo não mapeada.
+---------------+---------------+---------------+---------------+
| stack | unmapped | other stuff |
| ----> direction of growth | | |
+---------------+---------------+---------------+---------------+
^ ^ ^ ^ ^ page boundaries
Dessa forma, se o software tentar acessar dados além do limite da página (seja porque o ponteiro da pilha foi além do limite ou porque o acesso à matriz está fora dos limites e além do limite), ele causará uma falha ao acessar uma área não mapeada . Isso só acontece se o excesso for pequeno o suficiente: se a quantidade de excesso for muito grande, o programa pode acabar acessando outras coisas do outro lado da lacuna no espaço de endereço.
A desvantagem da abordagem de hardware é que ela não é totalmente confiável, pois um excesso de quantidade pode não ser detectado e que não detecta estouros de matriz que permanecem no espaço endereçável.
Para detectar estouros de matriz, outra técnica de software é um canário : coloque um valor especial no topo da pilha ou entre os quadros e verifique se o valor do canário não mudou no retorno da função. Essa também é uma técnica imperfeita, pois o excesso pode evitar o canário por completo ou pode não ser detectado porque o valor do canário foi restaurado no momento em que é verificado. No entanto, é útil dificultar a exploração de algumas vulnerabilidades de segurança.
A maneira mais segura e barata de evitar estouros de pilha é calcular a quantidade de pilha que o programa precisará antes de começar a executá-la, por análise estática. No entanto, isso nem sempre é prático: a quantidade de pilha necessária para um programa é indecidível em geral e depende dos dados que são manipulados pelo programa.
¹ O mesmo princípio também pode ser aplicado com apenas uma MPU, ou sem proteção de memória, se houver um único encadeamento cuja pilha esteja na borda dos mapeamentos físicos existentes.