2009-11-15 1 views
7

Così ho questo semplice pezzo di codice che dimostra un semplice buffer overflow:Quale strumento può catturare buffer overflow in C?

#include <stdio.h> 

int main(void) 
{ 
    char c[4] = { 'A', 'B', 'C', 'D' }; 
    char d[4] = { 'W', 'X', 'Y', 'Z' }; 

    printf("c[0] is '%c'\n", c[0]); 

    d[4] = 'Z'; /* Overflow that overwrites c[0] */ 

    printf("c[0] is '%c'\n", c[0]); 

    return 0; 
} 

L'output:

$ ./a.out 
c[0] is 'A' 
c[0] is 'Z' 

ho provato la compilazione di questo codice con le seguenti opzioni gcc ed è passato con il volo colori:

gcc -Wall -Wextra -Wformat=2 -Wswitch-default -Wcast-align -Wpointer-arith \ 
    -Wbad-function-cast -Wstrict-prototypes -Winline -Wundef -Wnested-externs \ 
    -Wcast-qual -Wshadow -Wwrite-strings -Wconversion -Wunreachable-code \ 
    -Wstrict-aliasing=2 -ffloat-store -fno-common -fstrict-aliasing \ 
    -Wstack-protector -fstack-protector-all -std=c99 -pedantic -O0 -ggdb3 

ho anche provato libefence e Valgrind. Mi aspettavo che la libefence passasse dal momento che è stata creata per catturare i limiti di lettura/scrittura sull'heap, ma sono rimasto sorpreso dal fatto che valgrind sia passato.

Questo codice non produce un Segfault dal c [4] e d [0] capita di sovrapporsi e penso che sia questo che sta causando strumenti perdere.

Quindi, che cosa c'è CAN prendere questo? Qualcosa di gratuito che funziona su Linux sarebbe bello.

+0

L'ultima versione di valgrind della stecca non prendere questo, purtroppo. –

+0

Hai ragione, è sfortunato, ma fa 'cppcheck'! – SiegeX

+0

Deludente per il fatto che gcc non se ne accorga, considerato che un po 'di tempo fa ho dovuto aggirare un bug del compilatore in cui si trattava di falsi allarmi su un puntatore end-of-array che non era nemmeno referenziato. Vedi http://stackoverflow.com/questions/1168525/c-gcc4-4-warning-array-subscript-is-above-array-bounds. Penso che gcc * cerchi * di diagnosticare questo problema, anche se non è richiesto, quindi le tue opzioni lo disabilitano oppure hai trovato il bug del compilatore opposto ... –

risposta

5

Prova cppcheck. Ha funzionato per me.

+0

Buona chiamata su 'cppcheck'. Non ho mai sentito di questo analizzatore di sorgenti prima ma * ESSO * trova l'errore! – SiegeX

+1

Il nuovo URL è: http://cppcheck.sourceforge.net/ –

+0

@AndrewSchools Grazie; URL aggiornato. – Teddy

0

Se è su Linux proverei fuori valgrind prima, penso che sarà gestire la cosa.

Edit: se è come dice SiegeX Credo valgrind non lo fa (che ha un senso, perché non hanno modo di inserire protezioni in pila come è coinvolto solo nella fase di esecuzione del processo). È comunque un buon strumento comunque che vale la pena avere nella tua cassetta degli attrezzi quindi terrò il post.

+3

Valgrind * NON * cattura questo come chiaramente indicato nella domanda . Per favore, smettila di votare. – SiegeX

+0

-1 dopo che la modifica non è stata davvero giusta. – Fredrik

+0

@SiegeX: "Valgrind passa anche" sembra, per me, mentre lo cattura. Devo dire che sono rimasto un po 'sorpreso, dal momento che non mi aspettavo che si occupasse di questo, dato che è progettato per catturare la memoria che è stata allocata all'heap. – Vatine

-1

Penso che ci sia un carattere null implicito in questo caso, dato che si sta riferimento a una stringa letterale. Quindi, d [4] è ancora nei limiti (immagina d come const char *) .... Tuttavia, potrei non essere corretto.

+1

Se l'avessi dichiarato come c [5] = "ABCD"; quindi il compilatore avrebbe gettato il byte NUL alla fine. Ma poiché non c'è spazio per il byte NUL con solo 4 caratteri, viene scartato. Tuttavia, ho modificato il codice per utilizzare esplicitamente i caratteri per l'inizializzazione per ridurre la confusione. – SiegeX

2

Come valgrind funziona su binario, non ha visto nulla di sbagliato con questo codice. Controllare questi (http://www.thefreecountry.com/programming/debuggers.shtml) analizzatori di codice sorgente statici, dovrebbero trovarli. Se non funzionano, PC-lint (http://www.gimpel.com/html/pcl.htm) gestirà questo ....

+0

+1 per la raccomandazione di analizzatori di sorgenti statiche ... Quelle e/o recensioni peer sono probabilmente le più probabili da catturare se cose come valgrind non lo fanno (e pensandoci, mi rendo conto che non c'è modo in cui valgrind possa trovarlo a meno viene coinvolto nel processo di compilazione) – Fredrik

+0

Sebbene il collegamento "debuggers.shtml" non parli di "cppcheck" (risposta accettata), questo è un link molto valido altrimenti. Grazie – SiegeX

+0

Non ho mai sentito parlare di cppcheck prima. La versione più vecchia era il 2007, quindi è relativamente nuova. Soprattutto se confrontato con PC-Lint ... – Malkocoglu

1

Rational Purify funziona piuttosto bene con il rilevamento di overflow del buffer, perdite di memoria, corruzioni, ecc. È piuttosto costoso, però.

Il pacchetto mem menzionato in this SO answer può essere un'altra opzione.

1

La copertura (uno strumento di analisi statico) lo catturerà.

0

Gli overflow del buffer sono piuttosto difficili da rilevare in C poiché non si verificano fino al runtime. Per ridurre al minimo la possibilità di causarne uno, è necessario utilizzare le funzioni di libreria standard un po 'più sicure che eseguono alcuni controlli di verifica, ad es. fgets() invece di gets().

Se la manipolazione di un sacco di array manualmente probabilmente si dovrebbe scrivere unit test per verificare i casi limite nei vostri algoritmi. Cmockery è un esempio di un quadro unit test per C.

+0

Questo buffer overrun specifico può essere compilato in fase di compilazione, poiché il codice (staticamente) accede a * (c + 4), con un'allocazione dove c + 3 è l'ultimo indirizzo valido. – Vatine

0

Valgrind non prende in overflow memorizzazione automatica o statica. Almeno non di default. IIRC per farlo funzionare dovresti attivare un'opzione o eseguire degli strumenti "in sviluppo" che vengono con esso, non il "memcheck" predefinito.

+0

Ho eseguito l'aggiornamento all'ultima versione di valgrind 3.5.0 e ho utilizzato il comando --tool = exp-ptrcheck e questo è ancora passato con zero avvisi ed errori. – SiegeX

0

visual studio (con -Zi penso, ma potrei sbagliarmi) cattura questo tipo di compito con il suo correttore dello stack di runtime. Non è la soluzione Linux gratuita che preferisci, ma funziona bene.

2

Prova con Bugfighter C/C++.

Lo uso tutti i giorni e funziona perfettamente, anche con array multidimensionali come array[5][5][5].

La pagina Web di Bugfighter è www.bugfighter-soft.com. memcheck

2

di valgrind rileva la memoria heap

Per lo stack, è possibile provare SGCheck