Cada segmento tem pilha. Stack é uma região speical da memória usada pelo thread para armazenar variáveis locais,
functon endereço de retorno, etc Quando a CPU executa thread, ele deve ter seu registrador (SP) apontando para o endereço de memória com a pilha.
Na maioria dos casos, o kernel aloca pilha de thread, mas às vezes pilhas são criadas pelo aplicativo:
Aplicativos podem criar pilha personalizada para manipuladores de sinal (código que é executado quando o kernel envia sinal para processar)
ou eles podem fazer isso para implementar a biblioteca de threads.
Para fazer isso, o aplicativo solicita ao kernel por região da memória e, em seguida, marca-o como stack, portanto o kernel sabe que esta região é stack.
Mas devido a erros do desenvolvedor, o aplicativo pode pedir ao kernel para usar alguma memória para a pilha que não foi registrada para
naquela. Neste caso, algo de ruim pode acontecer: o kernel pode sobrescrever dados úteis porque acha que ele pode empilhar, mas
não é pilha! Os hackers podem usá-lo para quebrar programas.
No OpenBSD quando você reserva memória (usando mmap por exemplo) você deve EXPLICITAMENTE dizer que:
Cenário do dia de sol:
- App: kernel, posso ter alguma memória que usarei como pilha?
- Kernel: claro, aqui está sua memória
- App: ok, por favor use como pilha de sinais
- Kernel: ok (configura estruturas internas para fazer com que o registrador SP da CPU aponte para essa memória quando o sinal será processado)
Cenário de dias chuvosos:
- App: kernel, posso ter alguma memória?
- Kernel: claro, aqui está sua memória
- App: ok, por favor use como pilha de sinais
- Kernel: mas esta memória não é para pilha! Você está tentando me enganar!
- (o Kernel mata o aplicativo)
Aqui estão mais alguns exemplos de tais sinalizadores:
PROT_EXEC: pede ao kernel para reservar memória para armazenar código (algo que a CPU pode executar)
PROT_WRITE: pede ao kernel para reservar memória para dados graváveis
Então, você não pode executar seus dados ou escrever em seu código (isso se chama W ^ X e OpenBSD, pessoas orgulhosas disso)
Você pode ler man mmap
e map sigaltstack
para mais exemplos