|
|
|
![]() |
|
Strumenti |
![]() |
#1 |
Senior Member
Iscritto dal: Mar 2002
Città: Italy/Usa
Messaggi: 2817
|
[C] Funzioni da evitare
Salve ragazzi, allora, posto quello che mi è venuto dopo aver spesso riflettuto su quanta informazione sia didattica che professionale è a disposizione di tutti i programmatori, di qualsiasi livello:
Capita di rado che si parli di funzioni da evitare per eliminare fastidiosi problemi come buffer overflow etc.. Proporrei quindi, se siete d'accordo, di farne un elenco che ritengo possa essere utile sia a chi comincia con la programmazione, in modo da adeguarsi subito ad un buon modo di pensare, sia per i + esperti come.....'ripasso' Poi, magari, volendo ampliare il discorso, si potrebbe fare che al posto della funzione da evitare si posti la 'buona' che la sostituisce. Saluti.
__________________
"Utilizzando atomi pentavalenti drogheremo il silicio di tipo n; Utilizzando atomi trivalenti drogheremo il silicio di tipo p; Utilizzando della cannabis ci drogheremo noi e vedremo il silicio fare cose impossibili" - DSDT-HowTo |
![]() |
![]() |
![]() |
#2 |
Senior Member
Iscritto dal: Apr 2000
Città: Roma
Messaggi: 15625
|
La "classica" gets; da sostituire con fgets o simili.
Cmq i buffer overflow più spesso dipendono da inaccurata programmazione, più che da funzioni di libreria pericolose.
__________________
0: or %edi, %ecx; adc %eax, (%edx); popf; je 0b-22; pop %ebx; fadds 0x56(%ecx); lds 0x56(%ebx), %esp; mov %al, %al andeqs pc, r1, #147456; blpl 0xff8dd280; ldrgtb r4, [r6, #-472]; addgt r5, r8, r3, ror #12 |
![]() |
![]() |
![]() |
#3 |
Senior Member
Iscritto dal: Apr 2000
Città: Vicino a Montecatini(Pistoia) Moto:Kawasaki Ninja ZX-9R Scudetti: 29
Messaggi: 53971
|
Anche la sprintf può essere pericola se il programma è fatto male (ad esempio dimensionando male la stringa)...
|
![]() |
![]() |
![]() |
#4 |
Senior Member
Iscritto dal: Sep 2002
Città: Celano (AQ) Segno_Zodiacale: Leone Ascendente: Cammello Segni_Particolari: Quello
Messaggi: 9302
|
per favore potere spiegare anche perchè la funzione è da evitare e scrivere anche i parametri delle funzioni "buone e cattive"? tutti coloro che sono niubbi come me ve ne saranno molto grati...
![]() |
![]() |
![]() |
![]() |
#5 |
Senior Member
Iscritto dal: Apr 2000
Città: Vicino a Montecatini(Pistoia) Moto:Kawasaki Ninja ZX-9R Scudetti: 29
Messaggi: 53971
|
Per la gets è semplicissimo:
char *gets( char *buffer ); Se buffer è stato allocato di dimensione più piccola di quella immessa allora c'è un buffer overflow (e non evitabile in alcun modo)... Lo stesso problema c'è con la (*)scanf leggendo una stringa... scanf("%s", buffer); Per evitare bisogna leggere le stringhe da file o dallo stdin tramite: char *fgets( char *string, int n, FILE *stream ); |
![]() |
![]() |
![]() |
#6 | |
Senior Member
Iscritto dal: Sep 2002
Città: Celano (AQ) Segno_Zodiacale: Leone Ascendente: Cammello Segni_Particolari: Quello
Messaggi: 9302
|
Quote:
![]() |
|
![]() |
![]() |
![]() |
#7 | ||
Moderatore
Iscritto dal: Nov 2003
Messaggi: 16209
|
Quote:
Quindi, il numero massimo di caratteri che si possono leggere e' n-1, perche' nel totale va messo il carattere nullo di fine stringa. Quote:
__________________
Ubuntu è un'antica parola africana che significa "non so configurare Debian" ![]() Scienza e tecnica: Matematica - Fisica - Chimica - Informatica - Software scientifico - Consulti medici REGOLAMENTO DarthMaul = Asus FX505 Ryzen 7 3700U 8GB GeForce GTX 1650 Win10 |
||
![]() |
![]() |
![]() |
#8 |
Senior Member
Iscritto dal: May 2001
Città: Milano
Messaggi: 3191
|
per la gets basta mettere una fflush(stdin) prima di usarla, anzi è molto comoda da usare,io la uso sempre
![]() |
![]() |
![]() |
![]() |
#9 | |
Senior Member
Iscritto dal: Apr 2000
Città: Roma
Messaggi: 15625
|
Quote:
scanf("%15s", s);
__________________
0: or %edi, %ecx; adc %eax, (%edx); popf; je 0b-22; pop %ebx; fadds 0x56(%ecx); lds 0x56(%ebx), %esp; mov %al, %al andeqs pc, r1, #147456; blpl 0xff8dd280; ldrgtb r4, [r6, #-472]; addgt r5, r8, r3, ror #12 |
|
![]() |
![]() |
![]() |
#10 | |
Moderatore
Iscritto dal: Nov 2003
Messaggi: 16209
|
Quote:
(Lo standard C89, per default, non definisce il comportamento di fflush su uno stream di input.) Io, di solito, quando devo assicurarmi la lettura di una riga "nuova", leggo un carattere per volta dallo stream di input (e lo scarto) finche' non trovo un EOF o un newline; ma mi sembra di ricordare che neanche questo metodo e' universale... E poi non mi e' chiaro (ma potrei aver capito male io) perche' questo dovrebbe risolvere il problema di buffer overflow con gets.
__________________
Ubuntu è un'antica parola africana che significa "non so configurare Debian" ![]() Scienza e tecnica: Matematica - Fisica - Chimica - Informatica - Software scientifico - Consulti medici REGOLAMENTO DarthMaul = Asus FX505 Ryzen 7 3700U 8GB GeForce GTX 1650 Win10 |
|
![]() |
![]() |
![]() |
#11 |
Senior Member
Iscritto dal: Jul 2002
Città: Roma
Messaggi: 806
|
Programmo in C da 15 anni ed ormai ritengo che non esiston funzioni pericolose.
Il pericolo viene determinato, secondo me, da chi le usa, ossia il programmatore che "non sa quello che fa". Per cvi capita il buffer overflow, la colpa non è della funzione in sé ma di chi ha sottodimensionato il buffer oppure ha non saputo gestire il particolare evento. E' chiaro che nel momento in cui utilizzo una primitiva devo fare attenzione a tutti le implicazioni... |
![]() |
![]() |
![]() |
#12 | |
Senior Member
Iscritto dal: Apr 2000
Città: Vicino a Montecatini(Pistoia) Moto:Kawasaki Ninja ZX-9R Scudetti: 29
Messaggi: 53971
|
Quote:
|
|
![]() |
![]() |
![]() |
#13 | |
Senior Member
Iscritto dal: Apr 2000
Città: Vicino a Montecatini(Pistoia) Moto:Kawasaki Ninja ZX-9R Scudetti: 29
Messaggi: 53971
|
Quote:
![]() Comunque fra le fuinzioni di input sicuramente quella più insicura è la gets...ma bisogna stare attenti su qualsiasi funzioen di input che non permette di specificare il numero di byte o strutture da leggere... |
|
![]() |
![]() |
![]() |
#14 | |
Senior Member
Iscritto dal: Jul 2002
Città: Roma
Messaggi: 806
|
Quote:
In generale, come già detto prima, meglio privilegiare quelle funzioni che consentano di specificare a priori la dimensione dei buffer |
|
![]() |
![]() |
![]() |
#15 | |
Senior Member
Iscritto dal: Apr 2000
Città: Roma
Messaggi: 15625
|
Quote:
...e c'è chi fa MOLTO peggio ![]() http://marc.theaimsgroup.com/?l=linu...9071114282&w=2
__________________
0: or %edi, %ecx; adc %eax, (%edx); popf; je 0b-22; pop %ebx; fadds 0x56(%ecx); lds 0x56(%ebx), %esp; mov %al, %al andeqs pc, r1, #147456; blpl 0xff8dd280; ldrgtb r4, [r6, #-472]; addgt r5, r8, r3, ror #12 |
|
![]() |
![]() |
![]() |
#16 | |
Senior Member
Iscritto dal: Sep 2002
Città: Celano (AQ) Segno_Zodiacale: Leone Ascendente: Cammello Segni_Particolari: Quello
Messaggi: 9302
|
Quote:
Codice:
fscanf(in, "%*[^\n]\n%*[^\n]"); /* skip two lines */ while (fscanf(in, " %16[^:]:%*[^\n]", name) == 1) ![]() |
|
![]() |
![]() |
![]() |
#17 | |
Senior Member
Iscritto dal: Mar 2002
Città: Italy/Usa
Messaggi: 2817
|
Quote:
![]() Ciò comunque vale perchè come già evidenziato dalla maggior parte di voi, è un utilizzo 'inconsapevole' della funzione a provocare problemi che non la funzione stessa.
__________________
"Utilizzando atomi pentavalenti drogheremo il silicio di tipo n; Utilizzando atomi trivalenti drogheremo il silicio di tipo p; Utilizzando della cannabis ci drogheremo noi e vedremo il silicio fare cose impossibili" - DSDT-HowTo |
|
![]() |
![]() |
![]() |
#18 | |
Senior Member
Iscritto dal: Jul 2002
Città: Roma
Messaggi: 806
|
Quote:
Però mi sono accorto di una cosa. Che il programmatore smaliziato (o esperto, fate voi), capisce al volo quali potrebbero essere i possibili problemi, mentre il neofita rischia di cadere nella trappola. A volte il "man" (sotto unix/linux) o l'help sotto windows o comunque una buona guida sul C, dovrebbero porre in evidenza questi problemi. Nel caso tanto discusso della gets(), ad esempio, il man() del compilatore C per Unix-Solaris mette in guardia l'utente proprio su questo aspetto, e cioè che un utilizzo improprio del buffer potrebbe portare a risultati impredicibili... e pertanto consigliano l'uso della fgets() ![]() Poi sta al buon uso di chi programma scegliere quella che fa al caso suo... |
|
![]() |
![]() |
![]() |
#19 |
Senior Member
Iscritto dal: Mar 2002
Città: Italy/Usa
Messaggi: 2817
|
Inoltre, se già compili con gcc anche senza l'opzione -Wall ed hai una gets, ti esce lo stesso il warning che indica la possibile problematica.
__________________
"Utilizzando atomi pentavalenti drogheremo il silicio di tipo n; Utilizzando atomi trivalenti drogheremo il silicio di tipo p; Utilizzando della cannabis ci drogheremo noi e vedremo il silicio fare cose impossibili" - DSDT-HowTo |
![]() |
![]() |
![]() |
Strumenti | |
|
|
Tutti gli orari sono GMT +1. Ora sono le: 09:50.