Ho menzionato "buffer overflow" in un commento alla risposta di Pythagras, dovrei probabilmente chiarire cosa intendevo un po '. In C, non è sufficiente sapere che lavorare direttamente con la memoria è pericoloso - devi anche capire i modi precisi in cui è pericoloso. Non mi piace molto la metafora di "sparare te stesso nel piede" per tutti questi casi - il più delle volte, non è tu che tira il grilletto, ma spesso è un attore con interessi contrari a tuo e / o dei tuoi utenti.
Ad esempio, in un'architettura con uno stack discendente (le architetture più popolari si adattano a questo disegno di legge - x86 e ARM generalmente inclusi), quando si chiama una funzione, l'indirizzo di ritorno per la funzione verrà inserito nello stack dopo le variabili locali definite nel corpo della funzione. Quindi se dichiari un buffer come variabile locale ed esporti quella variabile al mondo esterno senza controllare l'overflow del buffer, in questo modo:
void myFn(void) {
char buf[256];
gets(buf);
}
un utente esterno può inviarti una stringa che sovrascrive l'indirizzo di ritorno dallo stack - in pratica, può cambiare l'idea di runtime del programma del call-graph che conduce alla funzione corrente. Quindi l'utente ti fornisce una stringa che è la rappresentazione binaria di un codice eseguibile per la tua architettura, abbastanza padding da sovraccaricare lo stack da myFn
, e alcuni dati aggiuntivi da sovrascrivere l'indirizzo di ritorno per myFn
per puntare al codice che ha dato tu. Se ciò accade, quando myFn
normalmente avrebbe restituito il controllo al proprio chiamante, verrà invece sostituito al codice fornito dall'utente malintenzionato. Se scrivi codice C (o C ++) che ha il potenziale di essere esposto a utenti non fidati, devi capire questo vettore di attacco . Dovresti capire perché un buffer overflow rispetto allo stack è spesso (ma non sempre) più facilmente sfruttabile di uno contro lo heap, e dovresti capire come viene strutturata la memoria nell'heap (non in modo troppo dettagliato, necessariamente, ma idea che una regione malloc()
'ed abbia strutture di controllo che la circondano può aiutarti a capire perché il tuo programma si arresta in modo anomalo in un altro malloc()
o in free()
).
C ti espone a dettagli di basso livello su come funziona la tua macchina e ti dà un controllo più diretto sulla tua macchina rispetto a qualsiasi altra lingua modificata dall'utente oggi ampiamente utilizzata. Con un grande potere derivano grandi responsabilità - in realtà devi capire quei dettagli di basso livello per lavorare con C in modo sicuro ed efficace.