Skip to content

Gestione degli Errori e Vulnerabilità

Usare la memoria dinamica dà grandi poteri, ma anche grandi responsabilità. Errori nell’uso di malloc e free sono alcune delle cause più frequenti di falle di sicurezza (exploits) nei programmi software mondiali.

Un memory leak avviene quando si alloca memoria dinamicamente ma ci si dimentica di chiamare free(). Il blocco di memoria rimane etichettato come “occupato” dal sistema, ma il programma non ha più un puntatore per raggiungerlo. Se il leak avviene all’interno di un ciclo molto lungo, il programma consumerà inesorabilmente tutta la RAM fino a subire un crash (OOM - Out of Memory).

Come discusso nella lezione precedente, malloc restituisce memoria “sporca”. Leggere quella memoria prima di scriverci sopra causerà Undefined Behavior.

Chiamare free() due volte sullo stesso puntatore è un errore fatale. Questo corrompe le strutture interne del memory manager (l’heap), provocando quasi certamente il crash istantaneo dell’applicazione, oppure offrendo a un hacker la possibilità di manipolare e sovrascrivere i metadati dell’heap.

Un puntatore pendente è un puntatore che conserva un indirizzo di memoria verso un blocco che è già stato deallocato (freed).

Continuare ad usare il puntatore per leggere o scrivere causerà il fenomeno dell’Use-After-Free (UAF). Se nel frattempo il sistema ha riutilizzato quello spazio per qualcos’altro, il tuo programma sovrascriverà memoria che non gli appartiene!

Per mitigare i dangling pointers e il double-free, esiste un’ottima pratica: assegnare NULL al puntatore non appena viene liberato.

free(ptr);
ptr = NULL; // Da ora in poi il puntatore è "sicuro"
// Se per errore qualcuno chiama di nuovo free:
free(ptr); // Chiamare free su NULL non fa niente! (È legale e sicuro)

💻 Esercizio Pratico: Bug-Hunting (Memory Leak)

Section titled “💻 Esercizio Pratico: Bug-Hunting (Memory Leak)”

Trova e correggi il memory leak in questa funzione e proteggiti contro il dangling pointer.