Um estouro de pilha é detectado por hardware ou software?


26

É tarefa do software (sistema operacional) detectar estouros de pilha ou é detectado um estouro de pilha no hardware, causando uma exceção na CPU?


Eu diria hardware, através de falhas de MMU na maioria das CPUs. O x86 no modo de 32 bits tinha segmentação além da paginação, e o "Segmento de pilha" está associado, como os segmentos Código, Dados, Ext ... com um endereço base e um tamanho. Qualquer acesso fora desse intervalo provocaria uma falha.
TEMLIB 22/02

Respostas:


25

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.


4
Eu não chamaria acesso de matriz fora dos limites a um estouro de pilha, mesmo que a matriz estivesse na pilha. É apenas um caso especial de estouro de buffer.
CodesInChaos

Não alocar para os itens principais da pilha que são referenciados em relação a um ponteiro que não seja de pilha / quadro ou deslocamento não constante evitaria o excesso de pilha tradicional. O uso de uma pilha de endereços de retorno separada (ou pilha de derramamento de registros / RA como Itanium) reduziria pelo menos significativamente as oportunidades de programação orientada a retornos.
Paul A. Clayton

O acesso fora dos limites é mais adequadamente chamado de excedente , não de excedente.
Ben Voigt

3
@ awesomebing1 nem toda plataforma detecta estouros de pilha. Você pode simplesmente substituir o que estiver após a pilha (semelhante a qualquer outro estouro de buffer).
user253751

11
@CodesInChaos, às vezes o estouro de buffer nos buffers alocados à pilha é chamado de "estouro de pilha" (abreviado). É verdade que essa terminologia pode ser um pouco confusa sem contexto.
DW
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.