Questa è una delle vulnerabilità più sfruttate per guadagnare accessi non
autorizzati al sistema (i cosiddetti \textit{exploit}), basta infatti inviare
una stringa sufficientemente lunga ed opportunamente forgiata per
-sovrascrivere gli indirizzi di ritorno nello \itindex{stack} \textit{stack}
-(supposto che la \func{gets} sia stata chiamata da una subroutine), in modo da
-far ripartire l'esecuzione nel codice inviato nella stringa stessa, che in
-genere contiene uno \textit{shell code}, cioè una sezione di programma che
-lancia una shell da cui si potranno poi eseguire altri programmi.
+sovrascrivere gli indirizzi di ritorno nello \textit{stack} (supposto che la
+\func{gets} sia stata chiamata da una subroutine), in modo da far ripartire
+l'esecuzione nel codice inviato nella stringa stessa, che in genere contiene
+uno \textit{shell code}, cioè una sezione di programma che lancia una shell da
+cui si potranno poi eseguire altri programmi.
La funzione \func{fgets} non ha i precedenti problemi di \func{gets} in quanto
prende in ingresso la dimensione del buffer \param{size}, che non verrà mai
Se il buffer di destinazione è sufficientemente ampio la stringa viene scritta
subito, altrimenti il buffer viene allargato usando \func{realloc} e la nuova
dimensione ed il nuovo puntatore vengono restituiti indietro, si noti infatti
-come entrambi gli argomenti siano dei \itindex{value~result~argument}
-\textit{value result argument}, per i quali vengono passati dei puntatori
-anziché i valori delle variabili, secondo quanto abbiamo descritto in
-sez.~\ref{sec:proc_var_passing}).
+come entrambi gli argomenti siano dei \textit{value result argument}, per i
+quali vengono passati dei puntatori anziché i valori delle variabili, secondo
+quanto abbiamo descritto in sez.~\ref{sec:proc_var_passing}).
Se si passa alla funzione l'indirizzo di un puntatore impostato a \val{NULL} e
\var{*n} è zero, la funzione provvede da sola all'allocazione della memoria
puntatore all'inizio del testo della linea letta. Un esempio di codice può
essere il seguente:
\includecodesnip{listati/getline.c}
-e per evitare \itindex{memory~leak} \textit{memory leak} occorre ricordarsi di
-liberare la memoria allocata dalla funzione eseguendo una \func{free} su
-\var{ptr}.
+e per evitare \textit{memory leak} occorre ricordarsi di liberare la memoria
+allocata dalla funzione eseguendo una \func{free} su \var{ptr}.
Il valore di ritorno di \func{getline} indica il numero di caratteri letti
dallo \textit{stream}, quindi compreso il \textit{newline}, ma non lo zero di
Le funzioni usano la stringa \param{format} come indicatore del formato con
-cui dovrà essere scritto il contenuto degli argomenti, il cui numero
-\index{funzioni!variadic} è variabile e dipende dal formato stesso.
+cui dovrà essere scritto il contenuto degli argomenti, il cui numero è
+variabile e dipende dal formato stesso.
Le prime due servono per scrivere su file (lo \itindex{standard~output}
\textit{standard output} o quello specificato) la terza permette di scrivere
La parte più complessa delle funzioni di scrittura formattata è il formato
della stringa \param{format} che indica le conversioni da fare, e da cui
deriva anche il numero degli argomenti che dovranno essere passati a seguire:
-si noti come tutte queste funzioni siano \index{funzioni!variadic}
-\textit{variadic}, prendendo un numero di argomenti variabile che dipende
-appunto da quello che si è specificato in \param{format}.
+si noti come tutte queste funzioni siano ``\textit{variadic}'', prendendo un
+numero di argomenti variabile che dipende appunto da quello che si è
+specificato in \param{format}.
La stringa di formato è costituita da caratteri normali (tutti eccetto
-``\texttt{\%}''), che vengono passati invariati all'output, e da direttive di
+``\texttt{\%}''), che vengono passati invariati in uscita, e da direttive di
conversione, in cui devono essere sempre presenti il carattere
``\texttt{\%}'', che introduce la direttiva, ed uno degli specificatori di
conversione (riportati in tab.~\ref{tab:file_format_spec}) che la conclude.
\cmd{L} & Una conversione in virgola mobile corrisponde a un
\ctyp{double}.\\
\cmd{q} & Sinonimo di \cmd{ll}.\\
- \cmd{j} & Una conversione intera corrisponde a un \type{intmax\_t} o
- \type{uintmax\_t}.\\
- \cmd{z} & Una conversione intera corrisponde a un \type{size\_t} o
- \type{ssize\_t}.\\
- \cmd{t} & Una conversione intera corrisponde a un \type{ptrdiff\_t}.\\
+ \cmd{j} & Una conversione intera corrisponde a un \ctyp{intmax\_t} o
+ \ctyp{uintmax\_t}.\\
+ \cmd{z} & Una conversione intera corrisponde a un \ctyp{size\_t} o
+ \ctyp{ssize\_t}.\\
+ \cmd{t} & Una conversione intera corrisponde a un \ctyp{ptrdiff\_t}.\\
\hline
\end{tabular}
\caption{Il modificatore di tipo di dato per il formato di \func{printf}}
Con queste funzioni diventa possibile selezionare gli argomenti che si
vogliono passare ad una funzione di stampa, passando direttamente la lista
tramite l'argomento \param{ap}. Per poter far questo ovviamente la lista
-variabile\index{funzioni!variadic} degli argomenti dovrà essere opportunamente
-trattata (l'argomento è esaminato in sez.~\ref{sec:proc_variadic}), e dopo
-l'esecuzione della funzione l'argomento
-\param{ap} non sarà più utilizzabile (in generale dovrebbe essere eseguito un
-\code{va\_end(ap)} ma in Linux questo non è necessario).
+variabile degli argomenti dovrà essere opportunamente trattata (l'argomento è
+esaminato in sez.~\ref{sec:proc_variadic}), e dopo l'esecuzione della funzione
+l'argomento \param{ap} non sarà più utilizzabile (in generale dovrebbe essere
+eseguito un \code{va\_end(ap)} ma in Linux questo non è necessario).
Come per \func{sprintf} anche per \func{vsprintf} esiste una analoga
\funcd{vsnprintf} che pone un limite sul numero di caratteri che vengono
Entrambe le funzioni prendono come argomento \param{strptr} che deve essere
l'indirizzo di un puntatore ad una stringa di caratteri, in cui verrà
restituito (si ricordi quanto detto in sez.~\ref{sec:proc_var_passing} a
-proposito dei \itindex{value~result~argument} \textit{value result argument})
-l'indirizzo della stringa allocata automaticamente dalle funzioni. Occorre
-inoltre ricordarsi di invocare \func{free} per liberare detto puntatore quando
-la stringa non serve più, onde evitare \itindex{memory~leak} \textit{memory
- leak}.
+proposito dei \textit{value result argument}) l'indirizzo della stringa
+allocata automaticamente dalle funzioni. Occorre inoltre ricordarsi di
+invocare \func{free} per liberare detto puntatore quando la stringa non serve
+più, onde evitare \textit{memory leak}.
% TODO verificare se mettere prototipi di \func{dprintf} e \func{vdprintf}
stato allocato e rimanere disponibile per tutto il tempo in cui si opera sullo
\textit{stream}. In genere conviene allocarlo con \func{malloc} e disallocarlo
dopo la chiusura del file; ma fintanto che il file è usato all'interno di una
-funzione, può anche essere usata una \index{variabili!automatiche} variabile
-automatica. In \headfile{stdio.h} è definita la macro \const{BUFSIZ}, che
-indica le dimensioni generiche del buffer di uno \textit{stream}, queste
-vengono usate dalla funzione \func{setbuf}. Non è detto però che tale
-dimensione corrisponda sempre al valore ottimale (che può variare a seconda
-del dispositivo).
+funzione, può anche essere usata una variabile automatica. In
+\headfile{stdio.h} è definita la macro \const{BUFSIZ}, che indica le
+dimensioni generiche del buffer di uno \textit{stream}, queste vengono usate
+dalla funzione \func{setbuf}. Non è detto però che tale dimensione
+corrisponda sempre al valore ottimale (che può variare a seconda del
+dispositivo).
Dato che la procedura di allocazione manuale è macchinosa, comporta dei
rischi, come delle scritture accidentali sul buffer, e non assicura la scelta