Domanda

Da man gets:

uso non viene mai (). Perchè è impossibile dire senza conoscere il i dati in anticipo quanti caratteri gets () leggerà, e perché gets () continuerà a negozio caratteri oltre la fine del buffer, è estremamente pericoloso utilizzare. E 'stato utilizzato per rompere del computer sicurezza. Utilizzare fgets (), invece.

Quasi ovunque vedo scanf utilizzato in un modo che dovrebbe avere lo stesso problema ( buffer overflow / tampone overrun ): scanf("%s",string). Questo problema esiste in questo caso? Perché non ci sono riferimenti su di esso nella pagina man scanf? Perché gcc non avvisa quando si compila questo con -Wall?

ps: so che c'è un modo per specificare nella stringa di formato la lunghezza massima della stringa con scanf:

char str[10];
scanf("%9s",str);

modifica: Io non sto chiedendo di Determe se il codice precedente è giusto o no. La mia domanda è:? Se scanf("%s",string) è sempre sbagliato, perciò non ci sono avvertimenti e non c'è nulla a questo proposito nella pagina man

È stato utile?

Soluzione

La risposta è semplicemente che nessuno ha scritto il codice in GCC per la produzione di questo avvertimento.

Come fai notare, un avvertimento per il caso specifico di "%s" (senza larghezza del campo) è del tutto appropriato.

Tuttavia, tenere a mente che questo è solo il caso per il caso di scanf(), vscanf(), fscanf() e vfscanf(). Questa specificazione formato può essere perfettamente sicuro con sscanf() e vsscanf(), quindi l'avviso non dovrebbe essere emesso in quel caso. Ciò significa che non si può semplicemente aggiungere al codice esistente analisi "scanf-style-format-string"; si dovrà dividere che in "fscanf-style-format-string" e le opzioni "sscanf-style-format-string".

Sono sicuro che se si produce una patch per la versione più recente di GCC che ha buone possibilità di essere accettato (e, naturalmente, è necessario inviare le patch per i file header glibc troppo).

Altri suggerimenti

Utilizzando gets() non è mai al sicuro. scanf() può essere utilizzato in modo sicuro, come ha detto nella sua interrogazione. Tuttavia, determinare se si sta utilizzando è in modo sicuro un problema più difficile per il compilatore a lavorare fuori (ad esempio, se si sta chiamando scanf() in una funzione in cui si passa nel buffer e un conteggio dei caratteri come argomenti, non sarà in grado di dire); in tal caso, deve presumere che si sa cosa si sta facendo.

Quando gli sguardi del compilatore alla formattazione delle stringhe di scanf, si vede una stringa! Si assume che la stringa di formattazione non si inserisce in fase di esecuzione. Alcuni compilatori GCC come hanno alcune funzionalità in più per analizzare la stringa di formattazione se inserito in fase di compilazione. Che funzionalità extra non è completo, perché in alcune situazioni è necessario un sovraccarico di run-time, che è un NO NO per linguaggi come C. Ad esempio, si può rilevare un utilizzo non sicuro, senza l'inserimento di un codice nascosto in più in questo caso:

char* str;
size_t size;
scanf("%z", &size);
str = malloc(size);
scanf("%9s"); // how can the compiler determine if this is a safe call?!

Naturalmente, ci sono modi per scrivere codice sicuro con scanf se si specifica il numero di caratteri da leggere, e che ci sia memoria sufficiente per contenere la stringa. Nel caso di gets, non c'è modo di specificare il numero di caratteri da leggere.

Io non sono sicuro perché la pagina man per scanf non menziona la probabilità di un sovraccarico del buffer, ma la vaniglia scanf non è un'opzione sicura. Un link piuttosto datato - http: //blogs.msdn .com / b / rsamona / archive / 2005/10/24 / 484449.aspx spettacoli questo come il caso. Inoltre, controllare questo (non gcc ma informativo comunque) - http://blogs.msdn.com/b/parthas/archive/2006/12/06/application-crash-on-replacing-sscanf-with-sscanf- s.aspx

Può essere semplicemente che scanf allocherà spazio sul mucchio base a quanto dati viene letto. Poiché non alloca il buffer e poi leggere finché viene letto il carattere nullo, non rischia sovrascrivendo il buffer . Invece, si legge nel proprio buffer fino a trovare il carattere nullo, e presumibilmente copie che tampone in un'altra delle dimensioni corrette alla fine della lettura.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top