sez.~\ref{sec:proc_fork}), la directory di lavoro della shell diventa anche la
directory di lavoro di qualunque comando da essa lanciato.
-Dato che è il kernel che tiene traccia per ciascun processo
-dell'\textit{inode} della directory di lavoro, per ottenerne il
-\textit{pathname} occorre usare una apposita funzione,
-\funcd{getcwd},\footnote{con Linux \func{getcwd} è una \textit{system call}
- dalla versione 2.1.9, in precedenza il valore doveva essere ottenuto tramite
- il filesystem \texttt{/proc} da \procfile{/proc/self/cwd}.} il cui prototipo
-è:
+Dato che è il kernel che tiene traccia dell'\textit{inode} della directory di
+lavoro di ciascun processo, per ottenerne il \textit{pathname} occorre usare
+una apposita funzione, \funcd{getcwd},\footnote{con Linux \func{getcwd} è una
+ \textit{system call} dalla versione 2.1.9, in precedenza il valore doveva
+ essere ottenuto tramite il filesystem \texttt{/proc} da
+ \procfile{/proc/self/cwd}.} il cui prototipo è:
\begin{funcproto}{
\fhead{unistd.h}
\item[\errcode{ERANGE}] l'argomento \param{size} è più piccolo della
lunghezza del \textit{pathname}.
\end{errlist}
- ed inoltre \errcode{EFAULT} nel suo significato generico.}
+ ed inoltre \errcode{EFAULT} ed \errcode{ENOMEM} nel loro significato
+ generico.}
\end{funcproto}
La funzione restituisce il \textit{pathname} completo della directory di
esso ecceda le dimensioni specificate con \param{size} la funzione restituisce
un errore.
-Si può anche specificare un puntatore nullo come
-\param{buffer},\footnote{questa è un'estensione allo standard POSIX.1,
- supportata da Linux e dalla \acr{glibc}.} nel qual caso la stringa sarà
-allocata automaticamente per una dimensione pari a \param{size} qualora questa
-sia diversa da zero, o della lunghezza esatta del \textit{pathname}
-altrimenti. In questo caso ci si deve ricordare di disallocare la stringa con
-\func{free} una volta cessato il suo utilizzo.
+A partire dal kernel Linux 2.6.36 il nome può avere come prefisso la stringa
+\texttt{(unreachable)} se la directory di lavoro resta fuori dalla directory
+radice del processo dopo un \func{chroot} (torneremo su questi argomenti in
+sez.~\ref{sec:file_chroot}); pertanto è sempre opportuno controllare il primo
+carattere della stringa restituita dalla funzione per evitare di interpreare
+mare un \textit{pathname} irraggiungibile.
+
+Come estensione allo standard POSIX.1, supportata da Linux e dalla
+\acr{glibc}, si può anche specificare un puntatore nullo come \param{buffer}
+nel qual caso la stringa sarà allocata automaticamente per una dimensione pari
+a \param{size} qualora questa sia diversa da zero, o della lunghezza esatta
+del \textit{pathname} altrimenti. In questo caso ci si deve ricordare di
+disallocare la stringa con \func{free} una volta cessato il suo utilizzo.
Un uso comune di \func{getcwd} è quello di salvarsi la directory di lavoro
all'avvio del programma per poi potervi tornare in un tempo successivo, un
la ragione principale per cui questa funzione è deprecata, e non la tratteremo.
Una seconda funzione usata per ottenere la directory di lavoro è
-\funcm{get\_current\_dir\_name},\footnote{la funzione è una estensione GNU e
- presente solo nella \acr{glibc}.} che non prende nessun argomento ed è
-sostanzialmente equivalente ad una \code{getcwd(NULL, 0)}, con la differenza
-che se disponibile essa ritorna il valore della variabile di ambiente
-\envvar{PWD}, che essendo costruita dalla shell può contenere un
-\textit{pathname} comprendente anche dei collegamenti simbolici. Usando
-\func{getcwd} infatti, essendo il \textit{pathname} ricavato risalendo
-all'indietro l'albero della directory, si perderebbe traccia di ogni passaggio
-attraverso eventuali collegamenti simbolici.
+\funcm{get\_current\_dir\_name} (la funzione è una estensione GNU e presente
+solo nella \acr{glibc}) che non prende nessun argomento ed è sostanzialmente
+equivalente ad una \code{getcwd(NULL, 0)}, con la differenza che se
+disponibile essa ritorna il valore della variabile di ambiente \envvar{PWD},
+che essendo costruita dalla shell può contenere un \textit{pathname}
+comprendente anche dei collegamenti simbolici. Usando \func{getcwd} infatti,
+essendo il \textit{pathname} ricavato risalendo all'indietro l'albero della
+directory, si perderebbe traccia di ogni passaggio attraverso eventuali
+collegamenti simbolici.
Per cambiare la directory di lavoro si può usare la funzione di sistema
\funcd{chdir}, equivalente del comando di shell \cmd{cd}, il cui nome sta
\begin{errlist}
\item[\errcode{EACCES}] manca il permesso di ricerca su uno dei componenti
di \param{pathname}.
+ \item[\errcode{ENAMETOOLONG}] il nome indicato in \param{path} è troppo lungo.
\item[\errcode{ENOTDIR}] non si è specificata una directory.
\end{errlist}
- ed inoltre \errval{EFAULT}, \errval{EIO}, \errval{ELOOP},
- \errval{ENAMETOOLONG}, \errval{ENOENT} e \errval{ENOMEM} nel loro
- significato generico.}
+ ed inoltre \errval{EFAULT}, \errval{EIO}, \errval{ELOOP}, \errval{ENOENT} e
+ \errval{ENOMEM} nel loro significato generico.}
\end{funcproto}
La funzione cambia la directory di lavoro in \param{pathname} ed
Finora abbiamo parlato esclusivamente di file, directory e collegamenti
simbolici, ma in sez.~\ref{sec:file_file_types} abbiamo visto che il sistema
prevede anche degli altri tipi di file, che in genere vanno sotto il nome
-generico di \textsl{file speciali}, come i file di dispositivo, le \textit{fifo} ed i
-socket.
+generico di \textsl{file speciali}, come i file di dispositivo, le
+\textit{fifo} ed i socket.
La manipolazione delle caratteristiche di questi file speciali, il cambiamento
di nome o la loro cancellazione può essere effettuata con le stesse funzioni
la specifica \func{mkfifo}.} l'uso per la creazione di un file ordinario, di
una \textit{fifo} o di un socket è consentito anche agli utenti normali.
-I nuovi \textit{inode} creati con \func{mknod} apparterranno al proprietario e
-al gruppo del processo (usando \ids{UID} e \ids{GID} del gruppo effettivo) che
-li ha creati a meno non sia presente il bit \acr{sgid} per la directory o sia
+Gli \textit{inode} creati con \func{mknod} apparterranno al proprietario e al
+gruppo del processo (usando \ids{UID} e \ids{GID} del gruppo effettivo) che li
+ha creati a meno non sia presente il bit \acr{sgid} per la directory o sia
stata attivata la semantica BSD per il filesystem (si veda
sez.~\ref{sec:file_ownership_management}) in cui si va a creare
l'\textit{inode}, nel qual caso per il gruppo verrà usato il \ids{GID} del
``\textit{symlink attack}'' dove nell'intervallo fra la generazione di un nome
e l'accesso allo stesso, viene creato un collegamento simbolico con quel nome
verso un file diverso, ottenendo, se il programma sotto attacco ne ha la
-capacità, un accesso privilegiato.
+capacità, un accesso privilegiato.\footnote{dal kernel 3.6 sono state
+ introdotte delle contromisure, illustrate in
+ sez.~\ref{sec:procadv_security_misc}, che rendono impraticabili questo tipo
+ di attacchi, ma questa non è una buona scusa per ignorare il problema.}
\itindend{symlink~attack}
\end{errlist}}
\end{funcproto}
-
Come per \func{mktemp} anche in questo caso \param{template} non può essere
una stringa costante. La funzione apre un file in lettura/scrittura con la
funzione \func{open}, usando l'opzione \const{O\_EXCL} (si veda
\func{mkstemp}.}
\end{funcproto}
\noindent la cui sola differenza è la presenza dell'ulteriore argomento
-\var{flags} che consente di specificare i flag da passare ad \func{open}
-nell'apertura del file.
+\var{flags} che consente di specificare alcuni ulteriori flag (come
+\const{O\_APPEND}, \const{O\_CLOEXEC}, \const{O\_SYNC}, il cui significato
+vedremo in sez.~\ref{sec:file_open_close}) da passare ad \func{open}
+nell'apertura del file.\footnote{si tenga presente che \func{mkostemp}
+ utilizza già \const{O\_CREAT}, \const{O\_EXCL} e \const{O\_RDWR}, che non è
+ il caso di reindicare, dato che ciò potrebbe portare ad errori in altri
+ sistemi operativi.}
+
+Di queste due funzioni sono state poi introdotte, a partire dalla \acr{glibc}
+2.11 due varianti, \funcd{mkstemps} e \funcd{mkostemps}, che consentono di
+indicare anche un suffisso, i loro prototipi sono:
+\begin{funcproto}{
+\fhead{stlib.h}
+\fdecl{int mkstemps(char *template, int suffixlen)}
+\fdesc{Apre un file temporaneo.}
+\fdecl{int mkostemps(char *template, int suffixlen, int flags)}
+\fdesc{Apre un file temporaneo.}
+}
+
+{Le funzioni hanno gli stessi valori di ritorno e gli stessi errori di
+ \func{mkstemp} con lo stesso significato, tranne \errval{EINVAL} che viene
+ restituito se \param{template} non è di lunghezza pari ad almeno
+ $6+$\param{suffixlen} ed i 6 caratteri prima del suffisso non sono
+ \code{XXXXXX}.}
+\end{funcproto}
-In OpenBSD è stata introdotta un'altra funzione simile alle precedenti,
-\funcd{mkdtemp}, che crea invece una directory temporanea;\footnote{la
- funzione è stata introdotta nella \acr{glibc} a partire dalla versione
- 2.1.91 ed inserita nello standard POSIX.1-2008.} il suo prototipo è:
+Le due funzioni, un'estensione non standard fornita dalla \acr{glibc}, sono
+identiche a \funcd{mkstemp} e \funcd{mkostemp}, ma consentono di avere un nome
+del file nella forma \texttt{prefissoXXXXXXsuffisso} dove la lunghezza del
+suffisso deve essere indicata con \param{suffixlen}.
+
+Infine con OpenBSD è stata introdotta un'altra funzione simile alle
+precedenti, \funcd{mkdtemp}, che crea invece una directory
+temporanea;\footnote{la funzione è stata introdotta nella \acr{glibc} a
+ partire dalla versione 2.1.91 ed inserita nello standard POSIX.1-2008.} il
+suo prototipo è:
\begin{funcproto}{
\fhead{stlib.h}
La funzione crea una directory temporanea il cui nome è ottenuto sostituendo
le \code{XXXXXX} finali di \param{template} con permessi \code{0700} (si veda
sez.~\ref{sec:file_perm_overview} per i dettagli). Dato che la creazione della
-directory è sempre esclusiva i precedenti problemi di \textit{race condition}
+directory è sempre atomica i precedenti problemi di \textit{race condition}
non si pongono.
-
\section{La manipolazione delle caratteristiche dei file}
\label{sec:file_infos}
campi di \struct{stat} su cui non torneremo in maggior dettaglio nel resto di
questa sezione:
\begin{itemize*}
-
\item Il campo \var{st\_nlink} contiene il numero di \textit{hard link} che
fanno riferimento al file (il cosiddetto \textit{link count}) di cui abbiamo
già parlato in numerose occasioni.
-
\item Il campo \var{st\_ino} contiene il numero di \textit{inode} del file,
quello viene usato all'interno del filesystem per identificarlo e che può
essere usato da un programma per determinare se due \textit{pathname} fanno
riferimento allo stesso file.
-
\item Il campo \var{st\_dev} contiene il numero del dispositivo su cui risiede
il file (o meglio il suo filesystem). Si tratta dello stesso numero che si
usa con \func{mknod} e che può essere decomposto in \textit{major number} e
\textit{minor number} con le macro \macro{major} e \macro{minor} viste in
sez.~\ref{sec:file_mknod}.
-
\item Il campo \var{st\_rdev} contiene il numero di dispositivo associato al
file stesso ed ovviamente ha un valore significativo soltanto quando il file
è un dispositivo a caratteri o a blocchi.
-
\item Il campo \var{st\_blksize} contiene la dimensione dei blocchi di dati
usati nell'I/O su disco, che è anche la dimensione usata per la
bufferizzazione dei dati dalle librerie del C per l'interfaccia degli
\textit{stream}. Leggere o scrivere blocchi di dati in dimensioni inferiori
a questo valore è inefficiente in quanto le operazioni su disco usano
comunque trasferimenti di questa dimensione.
-
\end{itemize*}
-% TODO trattare anche statx, aggiunta con il kernel 4.11 (vedi
-% https://lwn.net/Articles/707602/ e
-% https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=a528d35e8bfcc521d7cb70aaf03e1bd296c8493f)
+Nell'evoluzione del kernel la \textit{system call} che fornisce \func{stat} è
+stata modificata più volte per tener conto dei cambiamenti fatti alla
+struttura \struct{stat},\footnote{questo ha significato l'utilizzo a basso
+ livello di diverse \textit{system call} e diverse versioni della struttura.}
+in particolare a riguardo ai tempi dei file, di cui è stata aumentata la
+precisione (torneremo su questo in sez.~\ref{sec:file_file_times}) ma anche
+per gli aggiornamenti fatti ai campi \var{st\_ino}, \var{st\_uid} e
+\var{st\_gid}. Sulle piattaforme a 32 bit questi cambiamenti, che han visto un
+aumento delle dimensioni dei campi della struttura per adattarli alle nuove
+esigenze, sono mascherati dalla \acr{glibc} che attraverso \func{stat} invoca
+la versione più recente della \textit{system call} e reimpacchetta i dati se
+questo è necessario per eseguire dei vecchi programmi. Nelle piattaforme a 64
+bit invece è presente un'unica versione della \textit{system call} e la
+struttura \struct{stat} ha campi di dimensione sufficiente.
+
+Infine a partire dal kernel 2.6.16 è stata introdutta una ulteriore funzione
+della famiglia, \func{fstatat} che consente di trattare con sicurezza i
+\textit{pathname} relativi, la tratteremo in sez.~\ref{sec:file_openat},
+insieme alla nuova \textit{system call} \func{statx}, introdotta dal kernel
+4.11 per estendere l'interfaccia di \func{stat} e le informazioni che essa può
+restituire.
\subsection{I tipi di file}
funzioni della famiglia \func{stat} all'interno del campo \var{st\_mode} di
una struttura \struct{stat}.
-Il campo \var{st\_mode} è una maschera binaria in cui l'informazione viene
-suddivisa nei vari bit che compongono, ed oltre a quelle sul tipo di file,
-contiene anche le informazioni relative ai permessi su cui torneremo in
-sez.~\ref{sec:file_perm_overview}. Dato che i valori numerici usati per
-definire il tipo di file possono variare a seconda delle implementazioni, lo
-standard POSIX definisce un insieme di macro che consentono di verificare il
-tipo di file in maniera standardizzata.
-
\begin{table}[htb]
\centering
\footnotesize
\label{tab:file_type_macro}
\end{table}
+Il campo \var{st\_mode} è una maschera binaria in cui l'informazione viene
+suddivisa nei vari bit che compongono, ed oltre a quelle sul tipo di file,
+contiene anche le informazioni relative ai permessi su cui torneremo in
+sez.~\ref{sec:file_perm_overview}. Dato che i valori numerici usati per
+definire il tipo di file possono variare a seconda delle implementazioni, lo
+standard POSIX definisce un insieme di macro che consentono di verificare il
+tipo di file in maniera standardizzata.
+
Queste macro vengono usate anche da Linux che supporta pure le estensioni allo
standard per i collegamenti simbolici e i socket definite da BSD.\footnote{le
ultime due macro di tab.~\ref{tab:file_type_macro}, che non sono presenti