Memória mal gerenciada II

David García    17 junio, 2020
Memoria mal gestionada 2

Se tivéssemos que escolher uma vulnerabilidade particularmente prejudicial, provavelmente seria a execução arbitrária de código, principalmente, se ela puder ser explorada remotamente.  No post anterior, apresentamos os problemas que podem ser causados ​​por memória mal gerenciada. Agora veremos alguns exemplos concretos.

Double Free, Um exemplo Básico.

Essa falha ocorre quando liberamos duas vezes o mesmo bloco de memória reservada. Vamos ver um programa que faz isso muito «bem»:

Reservamos dois blocos, copiamos cadeias para eles e eles são liberados porque não precisamos mais deles (observe as chamadas para «Free«). Vamos ver a execução:

Tudo certo, agora nós vamos propositalmente deixar o deslize de liberar o bloco que já havíamos lançado. Isso não demonstra a vulnerabilidade em si (que é mais complexa de se explorar), mas verifica o que acontece quando fazemos algo errado nas estruturas de memória dinâmica da pilha.

Vamos executar e ver o que acontece:

Como podemos ver, a segunda string não foi impressa no terminal, como no programa anterior. O que aconteceu?

Ao liberar um bloco do heap essa lacuna foi deixada livre. Nós exigimos outro espaço para a variável p2 e nos foi atribuído outro bloco, mas lembre-se de que p1, embora tenha sido liberado, ainda aponta para seu bloco original … que agora pertence a p2.

Como relançamos p uma segunda vez, o que realmente fazemos é liberar memória que está sendo usada por outro ponteiro que não está relacionado ao objeto p. O uso de p2 se torna instável, pois estamos usando uma região de memória que já está liberada. Vejamos agora como os endereços de memória foram formados:

Como podemos ver, p2 pega o endereço do bloco que já tinha p, mas foi liberado. Vamos ver a mesma situação, mas liberando os dois blocos no final da função:

Se bem gerenciada a situação, os dois indicadores irão apontar para blocos diferentes, desta forma os recursos não serão liberados ao mesmo tempo e tudo irá ocorrer conforme o planejado.

Nós repetimos. O gerenciamento manual de memória é complexo, muito complexo. E deve-se prestar atenção à ordem das operações, onde os recursos são obtidos e onde paramos de usá-los, para liberá-los em boas (e seguras) condições.

No próximo post, veremos os dangling pointers ou ponteiros pendurados


David García
@dgn1729

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *