From: Simone Piccardi Date: Sun, 20 Jan 2019 20:44:27 +0000 (+0100) Subject: Revisione at-functions e altro X-Git-Url: https://gapil.gnulinux.it/gitweb/?p=gapil.git;a=commitdiff_plain;h=aeebfb3d7a3482d1255aeb318d01bbdd92829f4c Revisione at-functions e altro --- diff --git a/fileio.tex b/fileio.tex index 024cc34..e6a904f 100644 --- a/fileio.tex +++ b/fileio.tex @@ -1671,8 +1671,8 @@ gli altri dati contenuti nell'\textit{inode} che si leggono con \func{fstat}, come i tempi del file. Se lo scopo dell'operazione, come avviene spesso per i database, è assicurarsi che i dati raggiungano il disco e siano rileggibili immediatamente in maniera corretta, è sufficiente l'uso di \func{fdatasync} -che non comporta anche l'esecuzione di operazioni non necessarie all'integrità -dei dati, come l'aggiornamento dei tempi di ultima modifica ed ultimo accesso. +che evita le scritture non necessarie per avere l'integrità dei dati, come +l'aggiornamento dei tempi di ultima modifica ed ultimo accesso. Si tenga presente che l'uso di queste funzioni non comporta la sincronizzazione della directory che contiene il file e la scrittura della @@ -1688,12 +1688,12 @@ all'esecuzione di una \func{write} (come NFS o altri filesystem di rete) per cui l'errore viene rilevato quando la scrittura viene effettivamente eseguita. -L'uso di \func{sync} presenta in certi casi, quando ci sono più filesystem -montati, problemi di prestazioni dovute al fatto che la funzione provoca la -sincronizzazione dei dati su tutti quanti i filesystem, anche quando -interesserebbe che questo avvenga soltanto su quello dei file su cui si sta -lavorando. se i dati in attesa sono molti questo può causare seri problemi di -prestazioni. +L'uso di \func{sync} può causare, quando ci sono più filesystem montati, +problemi di prestazioni dovuti al fatto che effettua la sincronizzazione dei +dati su tutti i filesystem, anche quando sarebbe sufficiente eseguirla +soltanto su quello dei file su cui si sta lavorando; quando i dati in attesa +sono molti questo può causare una alta attività di I/O ed i relativi problemi +di prestazioni. Per questo motivo è stata introdotta una nuova funzione di sistema, \funcd{syncfs},\footnote{la funzione è stata introdotta a partire dal kernel @@ -1718,11 +1718,11 @@ prototipo è: \end{funcproto} La funzione richiede che si specifichi nell'argomento \param{fd} un file -descriptor su cui si sta operando, e lo scarico dei dati sarà limitato al -filesystem su cui il file ad esso corrispondente si trova. +descriptor su cui si sta operando, e la registrazione immediata dei dati sarà +limitata al filesystem su cui il file ad esso corrispondente si trova. -\subsection{Le \textit{at-functions}: \func{openat} e affini} +\subsection{Le \textit{at-functions}: \func{openat} e compagnia} \label{sec:file_openat} \itindbeg{at-functions} @@ -1734,53 +1734,69 @@ diretto ad un file posto nella directory di lavoro corrente, che alcuni dei componenti dello stesso vengano modificati in parallelo alla chiamata a \func{open}, cosa che lascia aperta la possibilità di una \textit{race condition} in cui c'è spazio per un \textit{symlink attack} (si ricordi -quanto visto per \func{access} in sez.~\ref{sec:file_perm_management}). +quanto visto per \func{access} in sez.~\ref{sec:file_perm_management}) +cambiando una delle directory sovrastanti il file fra un controllo e la +successiva apertura. -Inoltre come già accennato, la directory di lavoro corrente è una proprietà +Inoltre, come già accennato, la directory di lavoro corrente è una proprietà associata al singolo processo; questo significa che quando si lavora con i \textit{thread} questa sarà sempre la stessa per tutti \textit{thread}, ed un -cabiamento di directory di lavoro effettuato all'interno di un \textit{thread} -verrà applicato a tutti, non esiste quindi con le funzioni classiche un modo -semplice per far si che i singoli \textit{thread} possano aprire file usando -una propria directory per risolvere i \textit{pathname} relativi. +cambiamento di directory di lavoro effettuato all'interno di un \textit{thread} +verrà applicato a tutti gli altri. Non esiste quindi con le funzioni classiche +un modo semplice per far si che i singoli \textit{thread} possano aprire file +usando una propria directory di lavoro per risolvere i \textit{pathname} +relativi. Per risolvere questi problemi, riprendendo una interfaccia già presente in Solaris, a fianco delle normali funzioni che operano sui file (come \func{open}, \func{mkdir}, ecc.) sono state introdotte delle ulteriori -funzioni di sistema, chiamate ``\textit{at-functions}'' in quanto quasi tutte -sono contraddistinte dal suffisso \texttt{at}, che permettono l'apertura di un -file (o le rispettive altre operazioni) usando un \textit{pathname} relativo -ad una directory specificata.\footnote{l'introduzione è avvenuta su proposta - dello sviluppatore principale della \acr{glibc} Urlich Drepper e le - corrispondenti \textit{system call} sono state inserite nel kernel a partire - dalla versione 2.6.16, in precedenza era disponibile una emulazione che, sia - pure con prestazioni inferiori, funzionava facendo ricorso all'uso del - filesystem \textit{proc} con l'apertura del file attraverso il riferimento a +funzioni di sistema, chiamate in maniera generica ``\textit{at-functions}'' in +quanto quasi tutte sono contraddistinte dal suffisso \texttt{at}, che +permettono l'apertura di un file (o le rispettive altre operazioni) usando un +\textit{pathname} relativo ad una directory +specificata.\footnote{l'introduzione è avvenuta su proposta dello sviluppatore + principale della \acr{glibc} Urlich Drepper e le corrispondenti + \textit{system call} sono state inserite nel kernel a partire dalla versione + 2.6.16, in precedenza era disponibile una emulazione che, sia pure con + prestazioni inferiori, funzionava facendo ricorso all'uso del filesystem + \textit{proc} con l'apertura del file attraverso il riferimento a \textit{pathname} del tipo di \texttt{/proc/self/fd/dirfd/relative\_path}.} Benché queste funzioni non siano presenti negli standard tradizionali esse sono state adottate da altri sistemi unix-like come Solaris, i vari BSD, fino -ad essere incluse in una recente revisione (la POSIX.1-2008) dello standard -POSIX.1. Con la \acr{glibc} per l'accesso a queste funzioni è necessario -definire la macro \macro{\_ATFILE\_SOURCE} (attiva di default). - -L'uso di queste funzioni prevede una apertura iniziale della directory che si -intende usare come base per la risoluzione dei \textit{pathname} relativi, -dopo di che si dovrà passare il suddetto file descriptor alle stesse, che -useranno quella directory come punto di partenza per la risoluzione. In questo -modo, anche quando si lavora con i \textit{thread}, si può mantenere una -directory di lavoro diversa per ciascuno di essi. - -Questo metodo, oltre a risolvere i problemi di \textit{race condition} dovuti -al possibile cambiamento di uno dei componenti del \textit{pathname}, consente -anche di ottenere aumenti di prestazioni significativi quando si devono -eseguire molte operazioni su sezioni dell'albero dei file che prevedono delle -gerarchie di sottodirectory molto profonde. Infatti in questo caso basta -eseguire la risoluzione del \textit{pathname} di una qualunque directory di -partenza una sola volta (nell'apertura iniziale) e non tutte le volte che si -deve accedere a ciascun file che essa contiene. - -La sintassi generale di queste nuove funzioni è l'utilizzo come primo +ad essere incluse in una recente revisione dello standard POSIX.1 (la +POSIX.1-2008). Con la \acr{glibc} per l'accesso a queste funzioni è necessario +definire la macro \macro{\_ATFILE\_SOURCE} (comunque attiva di default). + +L'uso di queste funzioni richiede una apertura preliminare della directory che +si intende usare come base per la risoluzione dei \textit{pathname} relativi +(ad esempio usando \func{open} con il flag \const{O\_PATH} visto in +sez.~\ref{sec:file_open_close}) per ottenere un file descriptor che dovrà +essere passato alle stesse. Tutte queste funzioni infatti prevedono la +presenza un apposito argomento, in genere il primo, che negli esempi seguenti +chiameremo sempre \param{dirfd}. + +In questo modo, una volta aperta la directory di partenza, si potranno +effettuare controlli ed aperture solo con \textit{pathname} relativi alla +stessa, e tutte le \textit{race condition} dovute al possibile cambiamento di +uno dei componenti posti al di sopra della stessa cesseranno di esistere. +Inoltre, pur restando la directory di lavoro una proprietà comune del +processo, si potranno usare queste funzioni quando si lavora con i +\textit{thread} per eseguire la risoluzione dei \textit{pathname} relativi ed +avere una directory di partenza diversa in ciascuno di essi. + +Questo metodo consente inoltre di ottenere aumenti di prestazioni +significativi quando si devono eseguire molte operazioni su sezioni +dell'albero dei file che prevedono delle gerarchie di sottodirectory molto +profonde. Infatti in questo caso basta eseguire la risoluzione del +\textit{pathname} di una qualunque directory di partenza una sola volta +(nell'apertura iniziale) e non tutte le volte che si deve accedere a ciascun +file che essa contiene. Infine poter identificare una directory di partenza +tramite il suo file descriptor consente di avere un riferimento stabile alla +stessa anche qualora venisse rinominata, e tiene occupato il filesystem dove +si trova, come per la directory di lavoro di un processo. + +La sintassi generica di queste nuove funzioni prevede l'utilizzo come primo argomento del file descriptor della directory da usare come base per la risoluzione dei nomi, mentre gli argomenti successivi restano identici a quelli della corrispondente funzione ordinaria. Come esempio prendiamo in @@ -1810,17 +1826,11 @@ directory indicata da \param{dirfd}. Qualora invece si usi un \textit{pathname} assoluto \param{dirfd} verrà semplicemente ignorato. Infine se per \param{dirfd} si usa il valore speciale \constd{AT\_FDCWD}, la risoluzione sarà effettuata rispetto alla directory di lavoro corrente del -processo. Si tenga presente però che questa, come le altre costanti +processo. Si tenga presente però che questa costante, come le altre costanti \texttt{AT\_*}, è definita in \headfile{fcntl.h}, pertanto se la si vuole usare occorrerà includere comunque questo file, anche per le funzioni che non sono definite in esso. -Si tenga comunque presente che l'uso di \func{openat} non risolve in generale -tutte le possibili \textit{race condition} legati all'apertura di un file, -dopo un eventuale controllo di accesso o esistenza, ma consente comunque di -difendersi da tutti gli attacchi eseguiti modificando le componenti superiori -del suo \textit{pathname}. Inoltre una ... - Così come il comportamento, anche i valori di ritorno e le condizioni di errore delle nuove funzioni sono gli stessi delle funzioni classiche, agli errori si aggiungono però quelli dovuti a valori errati per \param{dirfd}; in @@ -1843,6 +1853,7 @@ di \param{dirfd} sarà completamente ignorato. \funcm{fchmodat} &$\bullet$&\func{chmod} \\ \func{fchownat} &$\bullet$&\func{chown},\func{lchown}\\ \funcm{fstatat} &$\bullet$&\func{stat},\func{lstat} \\ + \funcm{futimesat}& -- & obsoleta \\ \func{linkat} &$\bullet$\footnotemark&\func{link} \\ \funcm{mkdirat} & -- &\func{mkdir} \\ \funcm{mkfifoat} & -- &\func{mkfifo} \\ @@ -1850,6 +1861,8 @@ di \param{dirfd} sarà completamente ignorato. \func{openat} & -- &\func{open} \\ \funcm{readlinkat}& -- &\func{readlink}\\ \funcm{renameat} & -- &\func{rename} \\ + \funcm{renameat2}& -- &\func{rename} \\ + \funcm{scandirat}& -- &\func{scandir} \\ \funcm{statx} &$\bullet$&\func{stat} \\ \funcm{symlinkat}& -- &\func{symlink} \\ \func{unlinkat} &$\bullet$&\func{unlink},\func{rmdir} \\ @@ -1874,40 +1887,22 @@ parte di queste, indicate dal contenuto della omonima colonna di tab.~\ref{tab:file_atfunc_corr}, oltre al nuovo argomento iniziale, è prevista anche l'aggiunta di un ulteriore argomento finale, \param{flags}. +Per le funzioni che lo prevedono l'ulteriore argomento \param{flag} è stato +introdotto per fornire un meccanismo con cui modificarne il comportamento. Il +solo caso generale, valido per tutte, è quello in cui si sta operando su un +collegamento simbolico, e si vuole poter scegliere se far agire la funzione +direttamente sullo stesso o sul file da esso referenziato. Ma oltre a questo +caso generico, l'argomento viene usato per controllare ulteriori +caratteristiche di funzionamento, dipendenti dalla funzione stessa, per cui +deve essere comunque passato come maschera binaria ed impostato usando i +valori delle appropriate costanti \texttt{AT\_*}, definite in +\headfile{fcntl.h}. -% TODO trattare fstatat e con essa -% 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) - -% TODO manca prototipo di linkat, verificare se metterlo o metter menzione -% altre modifiche al riguardo nel 3.11 (AT_EMPTY_PATH?) vedi -% http://lwn.net/Articles/562488/ - -% TODO: Trattare esempio di inzializzazione di file e successivo collegamento -% con l'uso di O_TMPFILE e linkat, vedi man open - - -% TODO manca prototipo di utimensat, verificare se metterlo o metter menzione -% TODO manca prototipo di renameat2, introdotta nel 3.15, vedi -% http://lwn.net/Articles/569134/ -% TODO manca prototipo di execveat, introdotta nel 3.19, vedi -% https://lwn.net/Articles/626150/ cerca anche fexecve +%% Verificare uso generico di AT_EMPTY_XX - -Per tutte le funzioni che lo prevedono, a parte \func{unlinkat} e -\funcd{faccessat}, l'ulteriore argomento è stato introdotto solo per fornire -un meccanismo con cui modificarne il comportamento nel caso si stia operando -su un collegamento simbolico, così da poter scegliere se far agire la funzione -direttamente sullo stesso o sul file da esso referenziato. Dato che in certi -casi esso può fornire ulteriori indicazioni per modificare il comportamento -delle funzioni, \param{flags} deve comunque essere passato come maschera -binaria, ed impostato usando i valori delle appropriate costanti -\texttt{AT\_*}, definite in \headfile{fcntl.h}. - -Come esempio di questo secondo tipo di funzioni possiamo considerare -\funcd{fchownat}, che può essere usata per sostituire sia \func{chown} -che \func{lchown}; il suo prototipo è: +Come esempio delle funzioni che lo utilizzano solo nel caso generico possiamo +considerare \funcd{fchownat}, che può essere usata per sostituire sia +\func{chown} che \func{lchown}; il suo prototipo è: \begin{funcproto}{ \fhead{unistd.h} @@ -2025,20 +2020,28 @@ costanti utilizzabili per i valori di \param{flags}. \textbf{Costante} & \textbf{Significato} \\ \hline \hline - \constd{AT\_SYMLINK\_NOFOLLOW}& Se impostato la funzione non esegue la - dereferenziazione dei collegamenti - simbolici.\\ - \constd{AT\_SYMLINK\_FOLLOW}& Se impostato la funzione esegue la - dereferenziazione dei collegamenti simbolici - (usato esplicitamente solo da - \func{linkat}).\\ \constd{AT\_EACCES} & Usato solo da \func{faccessat}, richiede che il controllo dei permessi sia fatto usando l'\ids{UID} effettivo invece di quello reale.\\ + \constd{AT\_EMPTY\_PATH} & Usato da varie funzioni per operare + direttamente (specificando una stringa vuota + per il \texttt{pathname}) sul file descriptor + \param{dirfd} che in questo caso deve essere + ottenuto aprendo un file, che + può non essere una directory, con il flag + \param{O\_PATH} (vedi + sez.~\ref{sec:file_open_close}).\\ \constd{AT\_REMOVEDIR} & Usato solo da \func{unlinkat}, richiede che la funzione si comporti come \func{rmdir} invece che come \func{unlink}.\\ + \constd{AT\_SYMLINK\_FOLLOW}& Se impostato la funzione esegue la + dereferenziazione dei collegamenti simbolici + (usato esplicitamente solo da + \func{linkat}).\\ + \constd{AT\_SYMLINK\_NOFOLLOW}& Se impostato la funzione non esegue la + dereferenziazione dei collegamenti + simbolici.\\ \hline \end{tabular} \caption{Le costanti utilizzate per i bit dell'argomento @@ -2047,6 +2050,27 @@ costanti utilizzabili per i valori di \param{flags}. \end{table} + + +% TODO trattare fstatat e con essa +% 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) + +% TODO manca prototipo di linkat, verificare se metterlo o metter menzione +% altre modifiche al riguardo nel 3.11 (AT_EMPTY_PATH?) vedi +% http://lwn.net/Articles/562488/ + +% TODO: Trattare esempio di inzializzazione di file e successivo collegamento +% con l'uso di O_TMPFILE e linkat, vedi man open + + +% TODO manca prototipo di renameat2, introdotta nel 3.15, vedi +% http://lwn.net/Articles/569134/ +% TODO manca prototipo di execveat, introdotta nel 3.19, vedi +% https://lwn.net/Articles/626150/ cerca anche fexecve + + \texttt{ATTENZIONE PARTE DA RIVEDERE} @@ -4525,4 +4549,5 @@ con uno dei valori \const{FSETLOCKING\_INTERNAL} o % LocalWords: nell' du vm Documentation Urlich Drepper futimesat times l'I % LocalWords: futimens fs Tread all'I ll TMPFILE EDQUOT extN Minix UDF XFS % LocalWords: shmem Btrfs ubifs tmpfile fchmod fchown fsetxattr fchdir PF -% LocalWords: fstatfs sull' SIGTTIN EDESTADDRREQ datagram connect +% LocalWords: fstatfs sull' SIGTTIN EDESTADDRREQ datagram connect seal +% LocalWords: dirty execveat execve scandirat statx