From: Simone Piccardi Date: Tue, 24 Jan 2012 00:50:25 +0000 (+0000) Subject: Trattazione del significato di immutable e di append-only X-Git-Url: https://gapil.gnulinux.it/gitweb/?a=commitdiff_plain;h=ac55941f7ae7823e62c277d6be313147ef950f7b;p=gapil.git Trattazione del significato di immutable e di append-only --- diff --git a/filedir.tex b/filedir.tex index 9eff764..fcc0c59 100644 --- a/filedir.tex +++ b/filedir.tex @@ -538,10 +538,10 @@ Oltre alle caratteristiche standard, \acr{ext2} fornisce alcune estensioni che non sono presenti su un classico filesystem di tipo Unix; le principali sono le seguenti: \begin{itemize} -\item i \textit{file attributes} consentono di modificare il comportamento del - kernel quando agisce su gruppi di file. Possono essere impostati su file e - directory e in quest'ultimo caso i nuovi file creati nella directory - ereditano i suoi attributi. +\item gli attributi estesi (vedi sez.~\ref{sec:file_xattr}) che consentono di + estendere le informazioni salvabili come metadati e le ACL (vedi + sez.~\ref{sec:file_ACL}) che consentono di estendere il modello tradizionale + dei permessi sui file. \item sono supportate entrambe le semantiche di BSD e SVr4 come opzioni di montaggio. La semantica BSD comporta che i file in una directory sono creati con lo stesso identificatore di gruppo della directory che li contiene. La @@ -558,11 +558,12 @@ le seguenti: dell'\textit{inode} (evitando letture multiple e spreco di spazio), non tutti i nomi però possono essere gestiti così per limiti di spazio (il limite è 60 caratteri). -\item vengono supportati i file immutabili (che possono solo essere letti) per - la protezione di file di configurazione sensibili, o file - \textit{append-only} che possono essere aperti in scrittura solo per - aggiungere dati (caratteristica utilizzabile per la protezione dei file di - log). +\item vengono supportati \itindex{file~attributes} i cosiddetti \textit{file + attributes} che attivano comportamenti specifici per i file su cui vengono + attivati come marcarli come immutabili (che possono cioè essere soltanto + letti) per la protezione di file di configurazione sensibili, o come + \textit{append-only} (che possono essere aperti in scrittura solo per + aggiungere dati) per la protezione dei file di log. \end{itemize} La struttura di \acr{ext2} è stata ispirata a quella del filesystem di BSD: un @@ -3732,11 +3733,12 @@ riferimento al suo file descriptor mentre con \func{lutimes} nel caso in cui \param{filename} sia un collegamento simbolico saranno modificati i suoi tempi invece di quelli del file a cui esso punta. -Nonostante il kernel, come accennato, supporti risoluzioni dei tempi dei file -fino al nanosecondo, le funzioni fin qui esaminate non consentono di impostare -valori con questa precisione. Per questo sono state introdotte due nuove -funzioni, \funcd{futimens} e \func{utimensat}, in grado di eseguire questo -compito; i rispettivi prototipi sono: +Nonostante il kernel nelle versioni più recenti supporti, come accennato, +risoluzioni dei tempi dei file fino al nanosecondo, le funzioni fin qui +esaminate non consentono di impostare valori con questa precisione. Per questo +sono state introdotte due nuove funzioni di sistema, \funcd{futimens} e +\funcd{utimensat}, in grado di eseguire questo compito; i rispettivi prototipi +sono: \begin{funcproto}{ \fhead{sys/time.h} @@ -3746,18 +3748,41 @@ compito; i rispettivi prototipi sono: timespec times[2], int flags)} \fdesc{Cambia i tempi di un file.} } + {Le funzioni ritornano $0$ in caso di successo e $-1$ per un errore, nel qual caso \var{errno} assumerà uno dei valori: \begin{errlist} - \item[\errcode{EBADF}] da fare + \item[\errcode{EACCES}] si è richiesta l'impostazione del tempo corrente ma + non si ha il permesso di scrittura sul file, o non si è proprietari del + file o non si hanno i privilegi di amministratore; oppure il file è + immutabile (vedi sez.~\ref{sec:file_perm_overview}). + \item[\errcode{EBADF}] \param{fd} non è un file descriptor valido (solo + \func{futimens}), oppure \param{dirfd} non è \const{AT\_FDCWD} o un file + descriptor valido (solo \func{utimensat}). + \item[\errcode{EFAULT}] \param{times} non è un puntatore valido (per + entrambe), oppure \param{dirfd} è \const{AT\_FDCWD} ma \param{pathname} è + \var{NULL} o non è un puntatore valido (solo \func{utimensat}). + \item[\errcode{EINVAL}] si sono usati dei valori non corretti per i tempi + di \param{times} (per entrambe), oppure è si usato un valore non valido + per \param{flags}, oppure \param{pathname} è \var{NULL}, \param{dirfd} non + è \const{AT\_FDCWD} e \param{flags} contiene \const{AT\_SYMLINK\_NOFOLLOW} + (solo \func{utimensat}). + \item[\errcode{EPERM}] si è richiesto un cambiamento nei tempi non al tempo + corrente, ma non si è proprietari del file o non si hanno i privilegi di + amministratore; oppure il file è \itindex{file~attributes} immutabile o + \textit{append-only} (vedi sez.~\ref{sec:file_perm_overview}). + \item[\errcode{ESRCH}] non c'è il permesso di attraversamento per una delle + componenti di \param{pathname} (solo \func{utimensat}) \end{errlist} - ed inoltre nel loro significato generico.} + ed inoltre per entrambe \errval{EROFS} e per \func{utimensat} + \errval{ELOOP}, \errval{ENAMETOOLONG}, \errval{ENOENT}, \errval{ENOTDIR} nel + loro significato generico.} \end{funcproto} Entrambe le funzioni utilizzano per indicare i valori dei tempi un -vettore \param{times} di due strutture \struct{timespec} che permette di -specificare un valore di tempo con una precisione fino al nanosecondo, la cui -definizione è riportata in fig.~\ref{fig:sys_timespec_struct}. +vettore \param{times} di due strutture \struct{timespec}, la cui definizione è +riportata in fig.~\ref{fig:sys_timespec_struct}, che permette di specificare +un valore dei tempi con una precisione fino al nanosecondo. \begin{figure}[!htb] \footnotesize \centering @@ -3782,23 +3807,39 @@ quello di ultima modifica. Quando si usa uno di questi valori speciali per \var{tv\_nsec} il corrispondente valore di \var{tv\_sec} viene ignorato. Queste due funzioni sono una estensione definita nella revisione POSIX.1-2008 -dello standard POSIX; sono state introdotte a partire dal kernel 2.6.22, e -supportate dalla \acr{glibc} a partire dalla versione 2.6.\footnote{in - precedenza, a partire dal kernel 2.6.16, era stata introdotta la funzione - \funcm{futimesat} seguendo una bozza della revisione dello standard poi - modificata, questa funzione, sostituita da \func{utimensat}, è stata - dichiarata obsoleta, non è supportata da nessuno standard e non deve essere - più utilizzata: pertanto non la tratteremo.} La prima è sostanzialmente una -estensione di \func{futimes} che consente di specificare i tempi con -precisione maggiore, la seconda supporta invece, rispetto ad \func{utimes}, -una sintassi più complessa che, come vedremo in sez.~\ref{sec:file_openat} -consente una indicazione sicura dei \itindsub{pathname}{relativo} -\textit{pathname relativi} specificando la directory da usare come riferimento -in \param{dirfd} e la possibilità di usare per \param{flags} il valore -\const{AT\_SYMLINK\_NOFOLLOW} per indicare alla funzione di non dereferenziare -i collegamenti simbolici; si rimanda pertanto la spiegazione del significato -degli argomenti aggiuntivi alla trattazione generica delle varie funzioni che -usano la stessa sintassi, effettuata in sez.~\ref{sec:file_openat}. +dello standard POSIX, in Linux sono state introdotte a partire dal kernel +2.6.22,\footnote{si tenga presente però che per kernel precedenti il 2.6.26 le + due funzioni sono difettose nel rispetto di alcuni requisiti minori dello + standard e nel controllo della correttezza dei tempi, per i dettagli dei + quali si rimanda alla pagina di manuale.} e supportate dalla \acr{glibc} a +partire dalla versione 2.6.\footnote{in precedenza, a partire dal kernel + 2.6.16, era stata introdotta una \textit{system call} \funcm{futimesat} + seguendo una bozza della revisione dello standard poi modificata; questa + funzione, sostituita da \func{utimensat}, è stata dichiarata obsoleta, non è + supportata da nessuno standard e non deve essere più utilizzata: pertanto + non ne parleremo.} La prima è sostanzialmente una estensione di +\func{futimes} che consente di specificare i tempi con precisione maggiore, la +seconda supporta invece, rispetto ad \func{utimes}, una sintassi più complessa +che consente una indicazione sicura del file su cui operare specificando la +directory su cui si trova tramite il file descriptor \param{dirfd} ed il suo +nome come \itindsub{pathname}{relativo} \textit{pathname relativo} +in \param{pathname}.\footnote{su Linux solo \func{utimensat} è una + \textit{system call} e \func{futimens} è una funzione di libreria, infatti + se \param{pathname} è \var{NULL} \param{dirfd} viene considerato un file + descriptor ordinario e il cambiamento del tempo applicato al file + sottostante, qualunque esso sia, per cui \code{futimens(fd, times}) è del + tutto equivalente a \code{utimensat(fd, NULL, times, 0)}.} + +Torneremo su questa sintassi e sulla sua motivazione in +sez.~\ref{sec:file_openat}, quando tratteremo tutte le altre funzioni (le +cosiddette funzioni \textit{at}) che la utilizzano; essa prevede comunque +anche la presenza dell'argomento \param{flags} con cui attivare flag di +controllo che modificano il comportamento della funzione, nel caso specifico +l'unico valore consentito è \const{AT\_SYMLINK\_NOFOLLOW} che indica alla +funzione di non dereferenziare i collegamenti simbolici, cosa che le permette +di riprodurre le funzionalità di \func{lutimes}. + + \section{Il controllo di accesso ai file} @@ -3807,25 +3848,28 @@ usano la stessa sintassi, effettuata in sez.~\ref{sec:file_openat}. Una delle caratteristiche fondamentali di tutti i sistemi unix-like è quella del controllo di accesso ai file, che viene implementato per qualunque filesystem standard.\footnote{per standard si intende che implementa le - caratteristiche previste dallo standard POSIX; in Linux sono disponibili - anche una serie di altri filesystem, come quelli di Windows e del Mac, che - non supportano queste caratteristiche.} In questa sezione ne esamineremo i -concetti essenziali e le funzioni usate per gestirne i vari aspetti. + caratteristiche previste dallo standard POSIX; in Linux sono utilizzabili + anche filesystem di altri sistemi operativi, che non supportano queste + caratteristiche.} In questa sezione ne esamineremo i concetti essenziali e +le funzioni usate per gestirne i vari aspetti. \subsection{I permessi per l'accesso ai file} \label{sec:file_perm_overview} -Ad ogni file Linux associa sempre l'utente che ne è proprietario (il -cosiddetto \textit{owner}) ed un gruppo di appartenenza, secondo il meccanismo -degli identificatori di utente e gruppo (\ids{UID} e \ids{GID}). Questi valori -sono accessibili da programma tramite la funzione \func{stat}, e sono -mantenuti nei campi \var{st\_uid} e \var{st\_gid} della struttura -\struct{stat} (si veda sez.~\ref{sec:file_stat}).\footnote{questo è vero solo - per filesystem di tipo Unix, ad esempio non è vero per il filesystem vfat di - Windows, che non fornisce nessun supporto per l'accesso multiutente, e per - il quale i permessi vengono assegnati in maniera fissa con un opzione in - fase di montaggio.} +Ad ogni file Linux associa sempre, oltre ad un insieme di permessi, l'utente +che ne è proprietario (il cosiddetto \textit{owner}) ed un gruppo di +appartenenza, indicati dagli identificatori di utente e gruppo (\ids{UID} e +\ids{GID}) di cui abbiamo già parlato in +sez.~\ref{sec:proc_access_id}.\footnote{questo è vero solo per filesystem di + tipo Unix, ad esempio non è vero per il filesystem VFAT di Windows, che non + fornisce nessun supporto per l'accesso multiutente, e per il quale queste + proprietà vengono assegnate in maniera fissa con opportune opzioni di + montaggio.} Anche questi sono mantenuti \index{itinode} sull'\textit{inode} +insieme alle altre proprietà e sono accessibili da programma tramite la +funzione \func{stat} (trattata in sez.~\ref{sec:file_stat}), che restituisce +l'utente proprietario nel campo \var{st\_uid} ed il gruppo proprietario nel +campo \var{st\_gid} della omonima struttura \struct{stat}. Il controllo di accesso ai file segue un modello abbastanza semplice che prevede tre permessi fondamentali strutturati su tre livelli di accesso. @@ -3833,10 +3877,11 @@ Esistono varie estensioni a questo modello,\footnote{come le \itindex{Access~Control~List~(ACL)} \textit{Access Control List} che sono state aggiunte ai filesystem standard con opportune estensioni (vedi sez.~\ref{sec:file_ACL}) per arrivare a meccanismi di controllo ancora più - sofisticati come il \textit{mandatory access control} di SE-Linux.} ma nella -maggior parte dei casi il meccanismo standard è più che sufficiente a -soddisfare tutte le necessità più comuni. I tre permessi di base associati ad -ogni file sono: + sofisticati come il \itindex{Mandatory~Access~Control~(MAC)} + \textit{mandatory access control} di SE-Linux e delle altre estesioni come + \textit{Smack} o.} ma nella maggior parte dei casi il meccanismo standard è +più che sufficiente a soddisfare tutte le necessità più comuni. I tre +permessi di base associati ad ogni file sono: \begin{itemize*} \item il permesso di lettura (indicato con la lettera \texttt{r}, dall'inglese \textit{read}). @@ -3870,23 +3915,23 @@ I restanti tre bit (noti come \itindex{suid~bit} \textit{suid bit}, \itindex{sgid~bit} \textit{sgid bit}, e \itindex{sticky~bit} \textit{sticky bit}) sono usati per indicare alcune caratteristiche più complesse del meccanismo del controllo di accesso su cui torneremo in seguito (in -sez.~\ref{sec:file_special_perm}); lo schema di allocazione dei bit è -riportato in fig.~\ref{fig:file_perm_bit}. - -Anche i permessi, come tutte le altre informazioni pertinenti al file, sono -memorizzati \itindex{inode} nell'\textit{inode}; in particolare essi sono -contenuti in alcuni bit del campo \var{st\_mode} della struttura \struct{stat} +sez.~\ref{sec:file_special_perm}), lo schema di allocazione dei bit è +riportato in fig.~\ref{fig:file_perm_bit}. Come tutte le altre proprietà di +una file anche i permessi sono memorizzati \itindex{inode} +nell'\textit{inode}, e come accennato in sez.~\ref{sec:file_types} essi sono +contenuti in una parte del campo \var{st\_mode} della struttura \struct{stat} (si veda di nuovo fig.~\ref{fig:file_stat_struct}). In genere ci si riferisce ai tre livelli dei privilegi usando le lettere \texttt{u} (per \textit{user}), \texttt{g} (per \textit{group}) e \texttt{o} (per \textit{other}), inoltre se si vuole indicare tutti i raggruppamenti insieme si usa la lettera \texttt{a} (per \textit{all}). Si tenga ben presente -questa distinzione dato che in certi casi, mutuando la terminologia in uso nel -VMS, si parla dei permessi base come di permessi per \textit{owner}, -\textit{group} ed \textit{all}, le cui iniziali possono dar luogo a -confusione. Le costanti che permettono di accedere al valore numerico di -questi bit nel campo \var{st\_mode} sono riportate in +questa distinzione dato che in certi casi, mutuando la terminologia in uso a +suo tempo nel VMS, si parla dei permessi base come di permessi per +\textit{owner}, \textit{group} ed \textit{all}, le cui iniziali possono dar +luogo a confusione. Le costanti che permettono di accedere al valore numerico +di questi bit nel campo \var{st\_mode}, già viste in +tab.~\ref{tab:file_mode_flags}, sono riportate per chiarezza in tab.~\ref{tab:file_bit_perm}. \begin{table}[htb] @@ -3924,18 +3969,18 @@ La prima regola è che per poter accedere ad un file attraverso il suo \textit{pathname} occorre il permesso di esecuzione in ciascuna delle directory che compongono il \textit{pathname}; lo stesso vale per aprire un file nella directory corrente (per la quale appunto serve il diritto di -esecuzione). - -Per una directory infatti il permesso di esecuzione significa che essa può -essere attraversata nella risoluzione del \textit{pathname}, ed è distinto dal -permesso di lettura che invece implica che si può leggere il contenuto della -directory. +esecuzione). Per una directory infatti il permesso di esecuzione significa che +essa può essere attraversata nella risoluzione del \textit{pathname}, e per +questo viene anche chiamato permesso di attraversamento. Esso è sempre +distinto dal permesso di lettura che invece implica che si può leggere il +contenuto della directory. Questo significa che se si ha il permesso di esecuzione senza permesso di -lettura si potrà lo stesso aprire un file in una directory (se si hanno i -permessi opportuni per il medesimo) ma non si potrà vederlo con \cmd{ls} -(mentre per crearlo occorrerà anche il permesso di scrittura per la -directory). +lettura si potrà lo stesso aprire un file all'interno di una una directory (se +si hanno i permessi adeguati per il medesimo) ma non si potrà vederlo con +\cmd{ls} mancando il permesso di leggere il contenuto della directory. Per +crearlo o rinominarlo o cancellarlo invece occorrerà avere anche il permesso +di scrittura per la directory. Avere il permesso di lettura per un file consente di aprirlo con le opzioni (si veda quanto riportato in tab.~\ref{tab:file_open_flags}) di sola lettura o @@ -3947,14 +3992,15 @@ Non si può creare un file fintanto che non si disponga del permesso di esecuzione e di quello di scrittura per la directory di destinazione; gli stessi permessi occorrono per cancellare un file da una directory (si ricordi che questo non implica necessariamente la rimozione del contenuto del file dal -disco), non è necessario nessun tipo di permesso per il file stesso (infatti -esso non viene toccato, viene solo modificato il contenuto della directory, -rimuovendo la voce che ad esso fa riferimento). +disco). Per la cancellazione non è necessario nessun tipo di permesso per il +file stesso dato che, come illustrato in sez.~\ref{sec:link_symlink_rename} +esso non viene toccato, nella cancellazione viene solo modificato il contenuto +della directory, rimuovendo la voce che ad esso fa riferimento. Per poter eseguire un file (che sia un programma compilato od uno script di -shell, od un altro tipo di file eseguibile riconosciuto dal kernel), occorre -avere il permesso di esecuzione, inoltre solo i file regolari possono essere -eseguiti. +shell, od un altro tipo di file eseguibile riconosciuto dal kernel), occorre, +oltre al permesso di lettura per accedere al contenuto, avere anche il +permesso di esecuzione. Inoltre solo i file regolari possono essere eseguiti. I permessi per un collegamento simbolico sono ignorati, contano quelli del file a cui fa riferimento; per questo in genere il comando \cmd{ls} riporta @@ -3993,18 +4039,18 @@ di accesso sono i seguenti: proprietario del file (nel qual caso si dice che il processo è proprietario del file) allora: \begin{itemize*} - \item se il relativo\footnote{per relativo si intende il bit di user-read se - il processo vuole accedere in lettura, quello di user-write per - l'accesso in scrittura, ecc.} bit dei permessi d'accesso dell'utente è - impostato, l'accesso è consentito - \item altrimenti l'accesso è negato + \item se il relativo\footnote{per relativo si intende il bit di + \textit{user-read} se il processo vuole accedere in lettura, quello di + \textit{user-write} per l'accesso in scrittura, ecc.} bit dei permessi + d'accesso dell'utente è impostato, l'accesso è consentito; + \item altrimenti l'accesso è negato. \end{itemize*} \item Se il \ids{GID} effettivo del processo o uno dei \ids{GID} supplementari dei processi corrispondono al \ids{GID} del file allora: \begin{itemize*} \item se il bit dei permessi d'accesso del gruppo è impostato, l'accesso è - consentito, - \item altrimenti l'accesso è negato + consentito; + \item altrimenti l'accesso è negato. \end{itemize*} \item Se il bit dei permessi d'accesso per tutti gli altri è impostato, l'accesso è consentito, altrimenti l'accesso è negato. @@ -4017,6 +4063,38 @@ permessi per il gruppo non vengono neanche controllati. Lo stesso vale se il processo appartiene ad un gruppo appropriato, in questo caso i permessi per tutti gli altri non vengono controllati. +\itindbeg{file~attributes} +A questi che sono i permessi ordinari si aggiungono, per i filesystem che +supportano questa estensione, due permessi speciali mantenuti nei cosiddetti +\textit{file attributes}, che si possono leggere ed impostare con i comandi +\cmd{lsattr} e \cmd{chattr}.\footnote{per l'utilizzo di questo comando e le + spiegazioni riguardo gli altri \textit{file attributes} si rimanda alla + sezione 1.4.4 di \cite{AGL}.} + +Il primo è il cosiddetto attributo di immutabilità (\textit{immutable}, +identificato dalla lettera \texttt{i}) che impedisce ogni modifica al file, +\textit{inode} compreso. Questo significa non solo che non se ne può cambiare +il contenuto, ma neanche nessuno dei metadati, ed in particolare non si può +cancellare, rinominare, modificare nei permessi o nei tempi, o creare +\textit{hard link} verso di esso. + +Il secondo è il cosiddetto attributo di \textit{append-only}, (identificato +dalla lettera \texttt{a}) che consente soltanto la scrittura del file in coda +al file. Il file cioè può essere soltanto esteso, ma i suoi metadati, a parte +i tempi che può però possono essere impostati al valore corrente, non possono +essere modificati, quindi di nuovo non si potrà cancellare, rinominare, o +modificare nei permessi. + +Entrambi questi attributi attivano queste proprietà a livello di filesytem, +per cui a differenza dei permessi ordinari esse varranno per qualunque utente +compreso l'amministratore. L'amministratore è l'unico che può attivare o +disattivare questi attributi,\footnote{più precisamente un processo con la + \itindex{capabilities} capacità \const{CAP\_LINUX\_IMMUTABLE}.} e potendo +rimuoverli è comunque capace di tornare in grado di eseguire qualunque +operazione. +\itindbeg{file~attributes} + + \subsection{I bit dei permessi speciali} \label{sec:file_special_perm} @@ -6669,8 +6747,9 @@ opportuno dettagliare maggiormente. 2.4).\\ \const{CAP\_LINUX\_IMMUTABLE}& La capacità di impostare sui file gli attributi \textit{immutable} e - \itindex{append~mode} \textit{append only} (se - supportati).\\ + \itindex{append~mode} \textit{append-only} (vedi + sez.~\ref{sec:file_perm_overview}) se + supportati.\\ \const{CAP\_MKNOD} & La capacità di creare \index{file!di~dispositivo} file di dispositivo con \func{mknod} (vedi diff --git a/img/fileperm.dia b/img/fileperm.dia index e6a24a5..ddb68ad 100644 Binary files a/img/fileperm.dia and b/img/fileperm.dia differ