[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: Migliorare Debian e il software libero: trovare bug con valgrind e scrivere le patch



Ciao,

Il 2020-11-28 01:51 Sabrewolf ha scritto:
Il 24/11/20 21:32, Davide Prina ha scritto:
Ho installato il pacchetto piglit

Se l'obiettivo è il debugging e il software è open source sarebbe meglio
compilare i sorgenti con le opzioni che abilitano debug e profiling ed
eseguire i binari con gdb. I pacchetti precompilati quasi sempre sono
"strippati", cioè senza i simboli di debug.

Le opzioni di "profiling" per cercare errori nel software servono abbastanza poco, ma certamente le opzioni di debug sono molto utili. Proprio per questo esistono pacchetti i Debian, soprattutto per le librerie fondamentali ma anche per programmi , che forniscono i "simboli di debug". Per fare degli esempi: libc6-dbg o gimp-dbg.

Comunque io sono d'accordo con Davide, oltre a gdb, anche valgrind è un validissimo strumento per la ricerca di errori nel software. Alcuni tipi di errori, che con gdb andrebbero stanati con ricerche piuttosto complicate, con valgrind vengono evidenziati direttamente!

Le variabili di memoria non inizializzate in c/c++ non sono un bug se
non causano comportamenti del programma imprevisti o vulnerabilità
sfruttabili.

Le variabili non inizializzate, non sono un bug se il loro valore non viene usato :-)

Senza entrare troppo nei dettagli, ci sono un sacco di casi in cui operando su un valore indeterminato (per esempio quello che si legge da una variabile non inizializzata) può portare, secondo gli standard C/C++ a comportamenti indefiniti (undefined behavior), che sono sempre bug.

Direi anche che le vulnerabilità sono bug. Sempre. Anche prima che qualcuno scopra come sfruttarle. Soprattutto lo sono quando qualcuno ha già scoperto come sfruttarle e tu ancora non lo sai :-)

Proprio in quest'ottica valgrind è uno strumento utile per eliminare bug e vulnerabilità anche solo potenziali.

Tra l'altro valgrind non è un giocattolino scritto da principianti, non segnala (sarebbe errato) quando banalmente si legge un valore indefinito, ma solo se lo si usa. E ti dirò di più, in una variabile potenzialmente indefinita, tiene traccia dei singoli bit che sono o meno indefiniti.

Nel seguito un esempio:

$ cat prova.c
int main() {
  unsigned a;

  for (int i = 8; i > 0; --i)
    a = (a << 1) + (i & 1);

#ifdef ESCI_CORRETTAMENTE
  if ((a & 0xf) == 5)
    return 0;
#endif

  if ((a & 0xf00) == 0x500)
    return 3;

  return 6;
}
$ gcc -DESCI_CORRETTAMENTE prova.c -o prova&&valgrind -q ./prova
$ gcc prova.c -o prova&&valgrind -q ./prova
==1122820== Conditional jump or move depends on uninitialised value(s)
==1122820==    at 0x109162: main (in /home/bodrato/src/gmp-repo/prova)
==1122820==

Seguendo l'esempio, si può vedere che il valore della variabile a all'inizio è indefinito, poi nel ciclo for il valore indefinito viene progressivamente fatto slittare, inserendo alcuni bit ben definiti: 01010101. Se si controlla il valore dei bit meno significativi che sono sicuri, valgrind non fa una piega. Se la scelta del valore da restituire dipende dai bit non definiti, solo in questo caso valgrind segnala la criticità.
C'è una notevole raffinatezza in questa modalità di comportamento.

In conclusione, concordo con Davide sul fatto che valgrind è un ottimo strumento.

Anche se a volte capita di litigarci e anche se evidenzia solo una specifica categoria di potenziali problemi.

Ĝis,
m


Reply to: