Verificação de registro de pilha

0

link

O OpenBSD introduziu a verificação de registros de pilha

"É reforçado oportunisticamente pelo kernel." - > isso significa que é opcional?

"Quando uma chamada de sistema acontece, nós verificamos se o registrador de ponteiro de pilha aponta para essa página. Se isso não acontecer, o programa é morto. " - alguém pode explicar o stack-register para um não-programador com um pouco mais de detalhes? Se ele é opcional, como ele mataria todos os programas que não o possuem?

    
por Hessnov 11.03.2018 / 08:22

2 respostas

1

O registrador de ponteiro de pilha é um registrador de hardware. Ele aponta para um local de memória * que está em uma área usada para uma pilha. O registrador de ponteiro de pilha é usado ao endereçar dados na pilha, geralmente incrementando ou diminuindo o valor do ponteiro antes ou depois do acesso à memória. A verificação, que é executada quando ocorre uma chamada do sistema, verifica se o registrador aponta para um endereço de pilha válido. "Oportunamente" não significa "opcional".

[*]: um endereço válido também pode ser um após o último endereço da página da pilha em algumas arquiteturas.

    
por 11.03.2018 / 08:51
0

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

    
por 15.04.2018 / 02:38