X-Git-Url: https://gapil.gnulinux.it/gitweb/?p=gapil.git;a=blobdiff_plain;f=filedir.tex;h=b1f8e7615086434a0acb31c9ba9073c20c879594;hp=69af64b78326fc3f3c12b57bece96847b4e7eb34;hb=b81723c64c1d63b89cd3cec12f2fcccc4a756967;hpb=ee41e8b34dd560d230966160fb3eb748defc3e46 diff --git a/filedir.tex b/filedir.tex index 69af64b..b1f8e76 100644 --- a/filedir.tex +++ b/filedir.tex @@ -1,6 +1,6 @@ %% filedir.tex %% -%% Copyright (C) 2000-2009 Simone Piccardi. Permission is granted to +%% Copyright (C) 2000-2010 Simone Piccardi. Permission is granted to %% copy, distribute and/or modify this document under the terms of the GNU Free %% Documentation License, Version 1.1 or any later version published by the %% Free Software Foundation; with the Invariant Sections being "Un preambolo", @@ -613,12 +613,14 @@ file nella directory. \subsection{La creazione di file speciali} \label{sec:file_mknod} +\index{file!di~dispositivo|(} + Finora abbiamo parlato esclusivamente di file, directory e link simbolici; in sez.~\ref{sec:file_file_types} abbiamo visto però che il sistema prevede pure -degli altri tipi di file speciali, come i \index{file!di~dispositivo} file di -dispositivo, le fifo ed i socket (questi ultimi sono un caso a parte, essendo -associati anche alla comunicazione via rete, per cui ci saranno trattati in -dettaglio a partire da cap.~\ref{cha:socket_intro}). +degli altri tipi di file speciali, come i file di dispositivo, le fifo ed i +socket (questi ultimi sono un caso a parte, essendo associati anche alla +comunicazione via rete, per cui ci saranno trattati in dettaglio a partire da +cap.~\ref{cha:socket_intro}). La manipolazione delle caratteristiche di questi diversi tipi di file e la loro cancellazione può essere effettuata con le stesse funzioni che operano @@ -672,15 +674,15 @@ o \const{S\_IFBLK} o \const{S\_IFCHR}), il valore di \param{dev} dovr usato per indicare a quale dispositivo si fa riferimento, altrimenti il suo valore verrà ignorato. Solo l'amministratore può creare un file di dispositivo usando questa funzione (il processo deve avere la -\textit{capability} \const{CAP\_MKNOD}), ma in Linux\footnote{questo è un - comportamento specifico di Linux, la funzione non è prevista dallo standard - POSIX.1 originale, mentre è presente in SVr4 e 4.4BSD, ma esistono - differenze nei comportamenti e nei codici di errore, tanto che questa è - stata introdotta in POSIX.1-2001 con una nota che la definisce portabile - solo quando viene usata per creare delle fifo, ma comunque deprecata essendo - utilizzabile a tale scopo la specifica \func{mkfifo}.} l'uso per la -creazione di un file ordinario, di una fifo o di un socket è consentito anche -agli utenti normali. +\itindex{capabilities} \textit{capability} \const{CAP\_MKNOD}), ma in +Linux\footnote{questo è un comportamento specifico di Linux, la funzione non è + prevista dallo standard POSIX.1 originale, mentre è presente in SVr4 e + 4.4BSD, ma esistono differenze nei comportamenti e nei codici di errore, + tanto che questa è stata introdotta in POSIX.1-2001 con una nota che la + definisce portabile solo quando viene usata per creare delle fifo, ma + comunque deprecata essendo utilizzabile a tale scopo la specifica + \func{mkfifo}.} l'uso per la creazione di un file ordinario, di una fifo o +di un socket è consentito anche agli utenti normali. I nuovi \itindex{inode} \textit{inode} creati con \func{mknod} apparterranno al proprietario e al gruppo del processo che li ha creati, a meno che non si @@ -747,6 +749,8 @@ relativo identificativo con la macro \macro{makedev}: \textit{major number} e \itindex{minor~number} \textit{minor number}. \end{functions} +\index{file!di~dispositivo|)} + Infine con lo standard POSIX.1-2001 è stata introdotta una funzione specifica per creare una fifo (tratteremo le fifo in in sez.~\ref{sec:ipc_named_pipe}); la funzione è \funcd{mkfifo} ed il suo prototipo è: @@ -1541,9 +1545,10 @@ su un file, su un link simbolico e su un file descriptor. La struttura \struct{stat} usata da queste funzioni è definita nell'header \file{sys/stat.h} e in generale dipende dall'implementazione; la versione usata da Linux è mostrata in fig.~\ref{fig:file_stat_struct}, così come -riportata dalla pagina di manuale di \func{stat} (in realtà la definizione +riportata dalla pagina di manuale di \func{stat}; in realtà la definizione effettivamente usata nel kernel dipende dall'architettura e ha altri campi -riservati per estensioni come tempi più precisi, o per il padding dei campi). +riservati per estensioni come tempi dei file più precisi (vedi +sez.~\ref{sec:file_file_times}), o per il padding dei campi. \begin{figure}[!htb] \footnotesize @@ -1561,8 +1566,6 @@ Si noti come i vari membri della struttura siano specificati come tipi primitivi del sistema (di quelli definiti in tab.~\ref{tab:intro_primitive_types}, e dichiarati in \file{sys/types.h}). -% TODO: aggiornare con i cambiamenti ai tempi fatti con il 2.6 - \subsection{I tipi di file} \label{sec:file_types} @@ -1677,9 +1680,10 @@ dimensione inferiore sarebbe inefficiente. Si tenga conto che la lunghezza del file riportata in \var{st\_size} non è detto che corrisponda all'occupazione dello spazio su disco per via della -possibile esistenza dei cosiddetti \textit{holes} (letteralmente -\textsl{buchi}) che si formano tutte le volte che si va a scrivere su un file -dopo aver eseguito una \func{lseek} (vedi sez.~\ref{sec:file_lseek}) oltre la +possibile esistenza dei cosiddetti \index{file!\textit{hole}} \textit{holes} +(letteralmente \textsl{buchi}) che si formano tutte le volte che si va a +scrivere su un \itindex{sparse~file} file dopo aver eseguito una \func{lseek} +(tratteremo in dettaglio l'argomento in sez.~\ref{sec:file_lseek}) oltre la sua fine. In questo caso si avranno risultati differenti a seconda del modo in cui si @@ -1729,9 +1733,9 @@ dimensione si possono usare le due funzioni \funcd{truncate} e Se il file è più lungo della lunghezza specificata i dati in eccesso saranno perduti; il comportamento in caso di lunghezza inferiore non è specificato e dipende dall'implementazione: il file può essere lasciato invariato o esteso -fino alla lunghezza scelta; in quest'ultimo caso lo spazio viene riempito con -zeri (e in genere si ha la creazione di un \textit{hole} nel file). - +fino alla lunghezza scelta; nel caso di Linux viene esteso con la creazione di +un \index{file!\textit{hole}} \textsl{buco} nel \itindex{sparse~file} file e +ad una lettura si otterranno degli zeri. \subsection{I tempi dei file} \label{sec:file_file_times} @@ -1742,7 +1746,9 @@ possono essere letti tramite la funzione \func{stat}, che li restituisce attraverso tre campi della struttura \struct{stat} di fig.~\ref{fig:file_stat_struct}. Il significato di detti tempi e dei relativi campi è riportato nello schema in tab.~\ref{tab:file_file_times}, dove è anche -riportato un esempio delle funzioni che effettuano cambiamenti su di essi. +riportato un esempio delle funzioni che effettuano cambiamenti su di essi. Il +valore è espresso nel cosiddetto \itindex{calendar~time} \textit{calendar + time}, su cui torneremo in dettaglio in sez.~\ref{sec:sys_time}. \begin{table}[htb] \centering @@ -1766,8 +1772,8 @@ riportato un esempio delle funzioni che effettuano cambiamenti su di essi. \end{table} Il primo punto da tenere presente è la differenza fra il cosiddetto tempo di -modifica (il \textit{modification time} \var{st\_mtime}) e il tempo di -cambiamento di stato (il \textit{change time} \var{st\_ctime}). Il primo +modifica (il \textit{modification time}, \var{st\_mtime}) e il tempo di +cambiamento di stato (il \textit{change time}, \var{st\_ctime}). Il primo infatti fa riferimento ad una modifica del contenuto di un file, mentre il secondo ad una modifica \itindex{inode} dell'\textit{inode}; siccome esistono molte operazioni (come la funzione \func{link} e molte altre che vedremo in @@ -1775,12 +1781,50 @@ seguito) che modificano solo le informazioni contenute \itindex{inode} nell'\textit{inode} senza toccare il contenuto del file, diventa necessario l'utilizzo di un altro tempo. -Il sistema non tiene conto dell'ultimo accesso \itindex{inode} -all'\textit{inode}, pertanto funzioni come \func{access} o \func{stat} non -hanno alcuna influenza sui tre tempi. Il tempo di ultimo accesso (ai dati) -viene di solito usato per cancellare i file che non servono più dopo un certo -lasso di tempo (ad esempio il programma \cmd{leafnode} cancella i vecchi -articoli sulla base di questo tempo). +Il tempo di ultima modifica viene usato ad esempio da programmi come +\cmd{make} per decidere quali file necessitano di essere ricompilati o +(talvolta insieme anche al tempo di cambiamento di stato) per decidere quali +file devono essere archiviati per il backup. Il tempo di ultimo accesso viene +di solito usato per identificare i file che non vengono più utilizzati per un +certo lasso di tempo. Ad esempio un programma come \texttt{leafnode} lo usa +per cancellare gli articoli letti più vecchi, mentre \texttt{mutt} lo usa per +marcare i messaggi di posta che risultano letti. Il sistema non tiene conto +dell'ultimo accesso \itindex{inode} all'\textit{inode}, pertanto funzioni come +\func{access} o \func{stat} non hanno alcuna influenza sui tre tempi. Il +comando \cmd{ls} (quando usato con le opzioni \cmd{-l} o \cmd{-t}) mostra i +tempi dei file secondo lo schema riportato nell'ultima colonna di +tab.~\ref{tab:file_file_times}. + +L'aggiornamento del tempo di ultimo accesso è stato a lungo considerato un +difetto progettuale di Unix, questo infatti comporta la necessità di +effettuare un accesso in scrittura sul disco anche in tutti i casi in cui +questa informazione non interessa e sarebbe possibile avere un semplice +accesso in lettura sui dati bufferizzati. Questo comporta un ovvio costo sia +in termini di prestazioni, che di consumo di risorse come la batteria per i +portatili, o cicli di riscrittura per i dischi su memorie riscrivibili. + +Per questo motivo, onde evitare di mantenere una informazione che nella +maggior parte dei casi non interessa, è sempre stato possibile disabilitare +l'aggiornamento del tempo di ultimo accesso con l'opzione di montaggio +\texttt{noatime}. Dato però che questo può creare problemi a qualche +programma, in Linux è stata introdotta la opzione \texttt{relatime} che esegue +l'aggiornamento soltanto se il tempo di ultimo accesso è precedente al tempo di +ultima modifica o cambiamento, così da rendere evidente che vi è stato un +accesso dopo la scrittura, ed evitando al contempo ulteriori operazioni su +disco negli accessi successivi. In questo modo l'informazione relativa al +fatto che un file sia stato letto resta disponibile, e ad esempio i programmi +citati in precedenza continuano a funzionare. Questa opzione, a partire dal +kernel 2.6.30, è diventata il comportamento di default e non deve più essere +specificata esplicitamente.\footnote{si può comunque riottenere il vecchio + comportamento usando la opzione di montaggio \texttt{strictatime}.} + +L'effetto delle varie funzioni di manipolazione dei file sui relativi tempi è +illustrato in tab.~\ref{tab:file_times_effects}, facendo riferimento al +comportamento classico per quanto riguarda \var{st\_atime}. Si sono riportati +gli effetti sia per il file a cui si fa riferimento, sia per la directory che +lo contiene; questi ultimi possono essere capiti se si tiene conto di quanto +già detto, e cioè che anche le directory sono file (che contengono una lista +di nomi) che il sistema tratta in maniera del tutto analoga a tutti gli altri. \begin{table}[htb] \centering @@ -1862,21 +1906,6 @@ articoli sulla base di questo tempo). \label{tab:file_times_effects} \end{table} - -Il tempo di ultima modifica invece viene usato da \cmd{make} per decidere -quali file necessitano di essere ricompilati o (talvolta insieme anche al -tempo di cambiamento di stato) per decidere quali file devono essere -archiviati per il backup. Il comando \cmd{ls} (quando usato con le opzioni -\cmd{-l} o \cmd{-t}) mostra i tempi dei file secondo lo schema riportato -nell'ultima colonna di tab.~\ref{tab:file_file_times}. - -L'effetto delle varie funzioni di manipolazione dei file sui tempi è -illustrato in tab.~\ref{tab:file_times_effects}. Si sono riportati gli effetti -sia per il file a cui si fa riferimento, sia per la directory che lo contiene; -questi ultimi possono essere capiti se si tiene conto di quanto già detto, e -cioè che anche le directory sono file (che contengono una lista di nomi) che -il sistema tratta in maniera del tutto analoga a tutti gli altri. - Per questo motivo tutte le volte che compiremo un'operazione su un file che comporta una modifica del nome contenuto nella directory, andremo anche a scrivere sulla directory che lo contiene cambiandone il tempo di modifica. Un @@ -1890,22 +1919,23 @@ esiste. Per questo motivo quando si copia un file, a meno di preservare esplicitamente i tempi (ad esempio con l'opzione \cmd{-p} di \cmd{cp}) esso avrà sempre il tempo corrente come data di ultima modifica. -I tempi di ultimo accesso e modifica possono essere cambiati usando la -funzione \funcd{utime}, il cui prototipo è: +I tempi di ultimo accesso e modifica possono essere modificati esplicitamente +usando la funzione \funcd{utime}, il cui prototipo è: \begin{prototype}{utime.h} -{int utime(const char *filename, struct utimbuf *times)} + {int utime(const char *filename, struct utimbuf *times)} -Cambia i tempi di ultimo accesso e modifica \itindex{inode} -dell'\textit{inode} specificato da \param{filename} secondo i campi -\var{actime} e \var{modtime} di \param{times}. Se questa è \val{NULL} allora -viene usato il tempo corrente. + Cambia i tempi di ultimo accesso e modifica \itindex{inode} + dell'\textit{inode} specificato da \param{filename} secondo i valori dei + campi \var{actime} e \var{modtime} di \param{times}. Se questa è \val{NULL} + allora viene usato il tempo corrente. -\bodydesc{La funzione restituisce 0 in caso di successo e -1 in caso di - errore, nel qual caso \var{errno} assumerà uno dei valori: - \begin{errlist} - \item[\errcode{EACCES}] non si ha il permesso di scrittura sul file. - \item[\errcode{ENOENT}] \param{filename} non esiste. - \end{errlist}} + \bodydesc{La funzione restituisce 0 in caso di successo e -1 in caso di + errore, nel qual caso \var{errno} assumerà uno dei valori: + \begin{errlist} + \item[\errcode{EACCES}] non si ha il permesso di scrittura sul file. + \item[\errcode{EPERM}] non si è proprietari del file. + \end{errlist} + ed inoltre \errval{EROFS} e \errval{ENOENT}.} \end{prototype} La funzione prende come argomento \param{times} una struttura @@ -1935,11 +1965,163 @@ cambiamento di stato del file, che viene comunque cambiato dal kernel tutte le volte che si modifica \itindex{inode} l'\textit{inode} (quindi anche alla chiamata di \func{utime}). Questo serve anche come misura di sicurezza per evitare che si possa modificare un file nascondendo completamente le proprie -tracce. In realtà la cosa resta possibile, se si è in grado di accedere al -file di dispositivo, scrivendo direttamente sul disco senza passare attraverso -il filesystem, ma ovviamente in questo modo la cosa è molto più complicata da -realizzare. +tracce. In realtà la cosa resta possibile, se si è in grado di accedere al +\index{file!di~dispositivo} file di dispositivo, scrivendo direttamente sul +disco senza passare attraverso il filesystem, ma ovviamente in questo modo la +cosa è molto più complicata da realizzare. + +A partire dal kernel 2.6 la risoluzione dei tempi dei file, che nei campi di +tab.~\ref{tab:file_file_times} è espressa in secondi, è stata portata ai +nanosecondi per la gran parte dei filesystem. La ulteriore informazione può +essere acceduta attraverso altri campi appositamente aggiunti alla struttura +\struct{stat}. Se si sono definite le macro \macro{\_BSD\_SOURCE} o +\macro{\_SVID\_SOURCE} questi sono \var{st\_atim.tv\_nsec}, +\var{st\_mtim.tv\_nsec} e \var{st\_ctim.tv\_nsec} se queste non sono definite, +\var{st\_atimensec}, \var{st\_mtimensec} e \var{st\_mtimensec}. Qualora il +supporto per questa maggior precisione sia assente questi campi aggiuntivi +saranno nulli. + +Per la gestione di questi nuovi valori è stata definita una seconda funzione +di modifica, \funcd{utimes}, che consente di specificare tempi con maggior +precisione; il suo prototipo è: +\begin{prototype} + {sys/time.h} + {int utimes(const char *filename, struct timeval times[2])} + + Cambia i tempi di ultimo accesso e modifica \itindex{inode} + dell'\textit{inode} specificato da \param{filename} secondo i valori + specificati da \param{times}. Se questo è \val{NULL} allora viene usato il + tempo corrente. + + \bodydesc{La funzione restituisce 0 in caso di successo e -1 in caso di + errore, nel qual caso \var{errno} assumerà uno dei valori: + \begin{errlist} + \item[\errcode{EACCES}] non si ha il permesso di scrittura sul file. + \item[\errcode{EPERM}] non si è proprietari del file. + \end{errlist} + ed inoltre \errval{EROFS} e \errval{ENOENT}.} +\end{prototype} + +La funzione è del tutto analoga alla precedente \func{utime} ma usa come +argomento \param{times}, un vettore di due strutture \struct{timeval}, la cui +definizione è riportata in fig.~\ref{fig:sys_timeval_struct}, che consentono +di indicare i tempi con una precisione del microsecondo. Il primo elemento +di \param{times} indica il valore per il tempo di ultimo accesso, il secondo +quello per il tempo di ultima modifica. + +\begin{figure}[!htb] + \footnotesize \centering + \begin{minipage}[c]{15cm} + \includestruct{listati/timeval.h} + \end{minipage} + \normalsize + \caption{La struttura \structd{timeval} usata per indicare valori di tempo + con la precisione del microsecondo.} + \label{fig:sys_timeval_struct} +\end{figure} + +Oltre ad \func{utimes} su Linux sono presenti altre due funzioni,\footnote{le + due funzioni non sono definite in nessuno standard, ma sono presenti, oltre + che su Linux, anche su BSD.} \funcd{futimes} e \funcd{lutimes}, che +consentono rispettivamente di effettuare la modifica utilizzando un file +già aperto o di eseguirla direttamente su un link simbolico. I relativi +prototipi sono: +\begin{functions} + \headdecl{sys/time.h} + + \funcdecl{int futimes(int fd, const struct timeval tv[2])} Cambia i tempi + di un file già aperto specificato tramite il file descriptor \param{fd}. + + \funcdecl{int lutimes(const char *filename, const struct timeval tv[2])} + Cambia i tempi di \param{filename} anche se questo è un link simbolico. + + + \bodydesc{Le funzioni restituiscono zero in caso di successo e $-1$ per un + errore, nel qual caso \var{errno} assumerà gli stessi valori di + \func{utimes}, con in più per \func{futimes}: + \begin{errlist} + \item[\errcode{EBADF}] \param{fd} non è un file descriptor. + \item[\errcode{ENOSYS}] il filesystem \texttt{/proc} non è accessibile. + \end{errlist}} +\end{functions} + +Le due funzioni anno lo stesso comportamento di \texttt{utimes} e richiedono +gli stessi privilegi per poter operare, la differenza è che con \func{futimes} +si può indicare il file su cui operare facendo riferimento al relativo file +descriptor (tratteremo in dettaglio l'argomento in +sez.~\ref{cha:file_unix_interface}) mentre con \func{lutimes} nel caso in +cui \param{filename} sia un link 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: +\begin{functions} + \headdecl{sys/time.h} + + \funcdecl{futimens(int fd, const struct timespec times[2])} Cambia i tempi + di un file già aperto, specificato dal file descriptor \param{fd}. + + \funcdecl{int utimensat(int dirfd, const char *pathname, const struct + timespec times[2], int flags)} Cambia i tempi del file \param{pathname}. + + + \bodydesc{Le funzioni restituiscono zero in caso di successo e $-1$ per un + errore, nel qual caso \var{errno} assumerà gli stessi valori di + \func{utimes}, con in più per \func{futimes}: + \begin{errlist} + \item[\errcode{EBADF}] \param{fd} non è un file descriptor. + \item[\errcode{ENOSYS}] il filesystem \texttt{/proc} non è accessibile. + \end{errlist}} +\end{functions} + +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}. + +\begin{figure}[!htb] + \footnotesize \centering + \begin{minipage}[c]{15cm} + \includestruct{listati/timespec.h} + \end{minipage} + \normalsize + \caption{La struttura \structd{timespec} usata per indicare valori di tempo + con la precisione del nanosecondo.} + \label{fig:sys_timespec_struct} +\end{figure} +Come per le precedenti funzioni il primo elemento di \param{times} indica il +tempo di ultimo accesso ed il secondo quello di ultima modifica, e se si usa +il valore \const{NULL} verrà impostato il tempo corrente sia per l'ultimo +accesso che per l'ultima modifica. Nei singoli elementi di \param{times} si +possono inoltre utilizzare due valori speciali per il campo \var{tv\_nsec}: +con \const{UTIME\_NOW} si richiede l'uso del tempo corrente, mentre con +\const{UTIME\_OMIT} si richiede di non impostare il tempo. Si può così +aggiornare in maniera specifica soltanto uno fra il tempo di ultimo accesso e +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 in una recente revisione +dello standard POSIX (la POSIX.1-2008); sono state introdotte a partire dal +kernel 2.6.22, e supportate dalle \acr{glibc} a partire dalla versione +2.6.\footnote{in precedenza, a partire dal kernel 2.6.16, era stata introdotta + la funzione \func{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},\footnote{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}.} consente una indicazione sicura dei +\textit{pathname relativi} specificando la directory da usare come riferimento +in \param{dirfd} e la possibilità di usare \param{flags} per indicare alla +funzione di dereferenziare o meno i link simbolici. \section{Il controllo di accesso ai file} @@ -2346,7 +2528,15 @@ eseguendo un programma coi privilegi di un altro utente (ad esempio attraverso l'uso del \itindex{suid~bit} \textit{suid bit}) che vuole controllare se l'utente originale ha i permessi per accedere ad un certo file. -% TODO documentare euidaccess (e eaccess) +Del tutto analoghe a \func{access} sono le due funzioni \funcd{euidaccess} e +\funcd{eaccess} che ripetono lo stesso controllo usando però gli +identificatori del gruppo effettivo, verificando quindi le effettive capacità +di accesso ad un file. Le funzioni hanno entrambe lo stesso +prototipo\footnote{in realtà \func{eaccess} è solo un sinonimo di + \func{euidaccess} fornita per compatibilità con l'uso di questo nome in + altri sistemi.} che è del tutto identico a quello di \func{access}. Prendono +anche gli stessi valori e restituiscono gli stessi risultati e gli stessi +codici di errore. Per cambiare i permessi di un file il sistema mette ad disposizione due funzioni \funcd{chmod} e \funcd{fchmod}, che operano rispettivamente su un @@ -2457,7 +2647,7 @@ Per alcuni filesystem\footnote{i filesystem pi a scongiurare l'abuso dei \itindex{suid~bit} bit \acr{suid} e \acr{sgid}; essa consiste nel cancellare automaticamente questi bit dai permessi di un file qualora un processo che non appartenga all'amministratore\footnote{per la - precisione un processo che non dispone della capability + precisione un processo che non dispone della \itindex{capabilities} capacità \const{CAP\_FSETID}.} effettui una scrittura. In questo modo anche se un utente malizioso scopre un file \acr{suid} su cui può scrivere, un'eventuale modifica comporterà la perdita di questo privilegio. @@ -2539,16 +2729,28 @@ automaticamente propagato, restando coerente a quello della directory di partenza, in tutte le sotto-directory. La semantica SVr4 offre la possibilità di scegliere, ma per ottenere lo stesso -risultato di coerenza che si ha con BSD necessita che per le nuove directory -venga anche propagato anche il bit \acr{sgid}. Questo è il comportamento -predefinito del comando \cmd{mkdir}, ed è in questo modo ad esempio che Debian -assicura che le sotto-directory create nella home di un utente restino sempre -con il \acr{gid} del gruppo primario dello stesso. - -Come per i permessi, il sistema fornisce anche delle funzioni che permettano -di cambiare utente e gruppo cui il file appartiene; le funzioni in questione -sono tre: \funcd{chown}, \funcd{fchown} e \funcd{lchown}, ed i loro prototipi -sono: +risultato di coerenza che si ha con BSD necessita che quando si creano nuove +directory venga anche propagato anche il bit \acr{sgid}. Questo è il +comportamento predefinito del comando \cmd{mkdir}, ed è in questo modo ad +esempio che le varie distribuzioni assicurano che le sotto-directory create +nella home di un utente restino sempre con il \acr{gid} del gruppo primario +dello stesso. + +La presenza del bit \acr{sgid} è inoltre molto comoda quando si hanno +directory contenenti file condivisi all'intero di un gruppo in cui possono +scrivere tutti i membri dello stesso, dato che assicura che i file che gli +utenti vi creano appartengano sempre allo stesso gruppo. Questo non risolve +però completamente i problemi di accesso da parte di altri utenti dello stesso +gruppo, in quanto i permessi assegnati al gruppo potrebbero non essere +sufficienti; in tal caso si deve aver cura di usare un valore di +\itindex{umask} \textit{umask} che ne lasci di sufficienti.\footnote{in tal + caso si può assegnare agli utenti del gruppo una \textit{umask} di $002$, + anche se la soluzione migliore in questo caso è usare una ACL di default + (vedi sez.~\ref{sec:file_ACL}).} + +Come avviene nel caso dei permessi il sistema fornisce anche delle funzioni, +\funcd{chown}, \funcd{fchown} e \funcd{lchown}, che permettono di cambiare sia +l'utente che il gruppo a cui un file appartiene; i rispettivi prototipi sono: \begin{functions} \headdecl{sys/types.h} \headdecl{sys/stat.h} @@ -2560,8 +2762,8 @@ sono: Le funzioni cambiano utente e gruppo di appartenenza di un file ai valori specificati dalle variabili \param{owner} e \param{group}. - \bodydesc{Le funzioni restituiscono zero in caso di successo e -1 per - un errore, in caso di errore \var{errno} può assumere i valori: + \bodydesc{Le funzioni restituiscono 0 in caso di successo e -1 per un + errore, nel qual caso caso \var{errno} assumerà i valori: \begin{errlist} \item[\errcode{EPERM}] l'user-ID effettivo non corrisponde a quello del proprietario del file o non è zero, o utente e gruppo non sono validi @@ -2572,13 +2774,14 @@ sono: \errval{EACCES}, \errval{ELOOP}; \func{fchown} anche \errval{EBADF}.} \end{functions} -In Linux soltanto l'amministratore (in sostanza un processo con la -\itindex{capabilities} capability \const{CAP\_CHOWN}) può cambiare il -proprietario di un file, seguendo la semantica di BSD che non consente agli -utenti di assegnare i loro file ad altri (per evitare eventuali aggiramenti -delle quote). L'amministratore può cambiare il gruppo di un file, il -proprietario può cambiare il gruppo dei file che gli appartengono solo se il -nuovo gruppo è il suo gruppo primario o uno dei gruppi di cui fa parte. +Con Linux solo l'amministratore\footnote{o in generale un processo con la + \itindex{capabilities} capacità \const{CAP\_CHOWN}, vedi + sez.~\ref{sec:proc_capabilities}.} può cambiare il proprietario di un file; +in questo viene seguita la semantica usata da BSD che non consente agli utenti +di assegnare i loro file ad altri utenti evitando eventuali aggiramenti delle +quote. L'amministratore può cambiare sempre il gruppo di un file, il +proprietario può cambiare il gruppo solo dei file che gli appartengono e solo +se il nuovo gruppo è il suo gruppo primario o uno dei gruppi di cui fa parte. La funzione \func{chown} segue i link simbolici, per operare direttamente su un link simbolico si deve usare la funzione \func{lchown}.\footnote{fino alla @@ -2595,24 +2798,18 @@ privilegi di root entrambi i bit \itindex{suid~bit} \acr{suid} e \itindex{sgid~bit} \acr{sgid} vengono cancellati. Questo non avviene per il bit \acr{sgid} nel caso in cui esso sia usato (in assenza del corrispondente permesso di esecuzione) per indicare che per il file è attivo il -\itindex{mandatory~locking} \textit{mandatory locking}. +\itindex{mandatory~locking} \textit{mandatory locking} (vedi +sez.~\ref{sec:file_mand_locking}). \subsection{Un quadro d'insieme sui permessi} \label{sec:file_riepilogo} -Avendo affrontato in maniera separata il comportamento delle varie funzioni ed -il significato dei singoli bit dei permessi sui file, vale la pena fare un -riepilogo in cui si riassumono le caratteristiche di ciascuno di essi, in modo -da poter fornire un quadro d'insieme. - -In tab.~\ref{tab:file_fileperm_bits} si sono riassunti gli effetti dei vari -bit dei permessi per un file; per quanto riguarda l'applicazione dei permessi -per proprietario, gruppo ed altri si ricordi quanto illustrato in -sez.~\ref{sec:file_perm_overview}. Per compattezza, nella tabelle si sono -specificati i bit di \itindex{suid~bit} \textit{suid}, \itindex{sgid~bit} -\textit{sgid} e \textit{sticky} \itindex{sticky~bit} con la notazione -illustrata anche in fig.~\ref{fig:file_perm_bit}. +Avendo affrontato in maniera separata il comportamento delle varie funzioni +che operano sui permessi dei file ed avendo trattato in sezioni diverse il +significato dei singoli bit dei permessi, vale la pena di fare un riepilogo in +cui si riassumano le caratteristiche di ciascuno di essi, in modo da poter +fornire un quadro d'insieme. \begin{table}[!htb] \centering @@ -2623,7 +2820,7 @@ illustrata anche in fig.~\ref{fig:file_perm_bit}. \multicolumn{3}{|c|}{user}& \multicolumn{3}{|c|}{group}& \multicolumn{3}{|c|}{other}& - \multirow{2}{*}{\textbf{Operazioni possibili}} \\ + \multirow{2}{*}{\textbf{Significato per i file}} \\ \cline{1-12} \acr{s}&\acr{s}&\acr{t}&r&w&x&r&w&x&r&w&x& \\ \hline @@ -2643,28 +2840,12 @@ illustrata anche in fig.~\ref{fig:file_perm_bit}. -&-&-&-&-&-&-&-&-&-&1&-&Permesso di scrittura per tutti gli altri.\\ -&-&-&-&-&-&-&-&-&-&-&1&Permesso di esecuzione per tutti gli altri.\\ \hline - \end{tabular} - \caption{Tabella riassuntiva del significato dei bit dei permessi per un - file.} - \label{tab:file_fileperm_bits} -\end{table} - -In tab.~\ref{tab:file_dirperm_bits} si sono invece riassunti gli effetti dei -vari bit dei permessi per una directory; anche in questo caso si sono -specificati i bit di \itindex{suid~bit} \textit{suid}, \itindex{sgid~bit} -\textit{sgid} e \textit{sticky} \itindex{sticky~bit} con la notazione compatta -illustrata in fig.~\ref{fig:file_perm_bit}. - -\begin{table}[!htb] - \centering - \footnotesize - \begin{tabular}[c]{|c|c|c|c|c|c|c|c|c|c|c|c|l|} \hline \multicolumn{3}{|c|}{special}& \multicolumn{3}{|c|}{user}& \multicolumn{3}{|c|}{group}& \multicolumn{3}{|c|}{other}& - \multirow{2}{*}{\textbf{Operazioni possibili}} \\ + \multirow{2}{*}{\textbf{Significato per le directory}} \\ \cline{1-12} \acr{s}&\acr{s}&\acr{t}&r&w&x&r&w&x&r&w&x& \\ \hline @@ -2688,20 +2869,37 @@ illustrata in fig.~\ref{fig:file_perm_bit}. -&-&-&-&-&-&-&-&-&-&-&1&Permesso di attraversamento per tutti gli altri.\\ \hline \end{tabular} - \caption{Tabella riassuntiva del significato dei bit dei permessi per una - directory.} - \label{tab:file_dirperm_bits} + \caption{Tabella riassuntiva del significato dei bit dei permessi per un + file e directory.} + \label{tab:file_fileperm_bits} \end{table} -Nelle tabelle si è indicato con il carattere ``-'' il fatto che il valore del +Nella parte superiore di tab.~\ref{tab:file_fileperm_bits} si è riassunto il +significato dei vari bit dei permessi per un file ordinario; per quanto +riguarda l'applicazione dei permessi per proprietario, gruppo ed altri si +ricordi quanto illustrato in sez.~\ref{sec:file_perm_overview}. Per +compattezza, nella tabella si sono specificati i bit di \itindex{suid~bit} +\textit{suid}, \itindex{sgid~bit} \textit{sgid} e \textit{sticky} +\itindex{sticky~bit} con la notazione illustrata anche in +fig.~\ref{fig:file_perm_bit}. Nella parte inferiore si sono invece riassunti +i significati dei vari bit dei permessi per una directory; anche in questo +caso si è riapplicato ai bit di \itindex{suid~bit} \textit{suid}, +\itindex{sgid~bit} \textit{sgid} e \textit{sticky} \itindex{sticky~bit} la +notazione illustrata in fig.~\ref{fig:file_perm_bit}. + +Si ricordi infine che i permessi non hanno alcun significato per i link +simbolici, mentre per i \index{file!di~dispositivo} file di dispositivo hanno +senso soltanto i permessi di lettura e scrittura, che si riflettono sulla +possibilità di compiere dette operazioni sul dispositivo stesso. + +Nella tabella si è indicato con il carattere ``-'' il fatto che il valore del bit in questione non è influente rispetto a quanto indicato nella riga della -tabella; la descrizione dell'operazione fa riferimento soltanto alla +tabella; la descrizione del significato fa riferimento soltanto alla combinazione di bit per i quali è stato riportato esplicitamente un valore. Si rammenti infine che il valore dei bit dei permessi non ha alcun effetto qualora il processo possieda i privilegi di amministratore. - \section{Caratteristiche e funzionalità avanzate} \label{sec:file_dir_advances} @@ -2712,6 +2910,764 @@ scopi di sicurezza, che sono state introdotte nelle versioni pi Linux. +\subsection{La gestione delle \textit{capabilities}} +\label{sec:proc_capabilities} + +\itindbeg{capabilities} + +Come accennato in sez.~\ref{sec:proc_access_id} l'architettura classica della +gestione dei privilegi in un sistema unix-like ha il sostanziale problema di +fornire all'amministratore dei poteri troppo ampi, questo comporta che anche +quando si siano predisposte delle misure di protezione per in essere in grado +di difendersi dagli effetti di una eventuale compromissione del +sistema,\footnote{come montare un filesystem in sola lettura per impedirne + modifiche, o marcare un file come immutabile.} una volta che questa sia +stata effettuata e si siano ottenuti i privilegi di amministratore, queste +potranno essere comunque rimosse.\footnote{nei casi elencati nella precedente + nota si potrà sempre rimontare il sistema in lettura-scrittura, o togliere + la marcatura di immutabilità.} + +Il problema consiste nel fatto che nell'architettura tradizionale di un +sistema unix-like i controlli di accesso sono basati su un solo livello di +separazione: per i processi normali essi sono posti in atto, mentre per i +processi con i privilegi di amministratore essi non vengono neppure eseguiti; +per questo motivo non era previsto alcun modo per evitare che un processo con +diritti di amministratore non potesse eseguire certe operazioni, o per cedere +definitivamente alcuni privilegi da un certo momento in poi. + +Per ovviare a tutto ciò, a partire dai kernel della serie 2.2, è stato +introdotto un meccanismo, detto \textit{capabilities}, che consentisse di +suddividere i vari privilegi tradizionalmente associati all'amministratore in +un insieme di \textsl{capacità} distinte. L'idea era che queste capacità +potessero essere abilitate e disabilitate in maniera indipendente per ciascun +processo con privilegi di amministratore, permettendo così una granularità +molto più fine nella distribuzione degli stessi che evitasse la originaria +situazione di \textsl{tutto o nulla}. + +Il meccanismo completo delle \textit{capabilities}\footnote{l'implementazione + si rifà ad una bozza di quello che doveva diventare lo standard POSIX.1e, + ormai abbandonato.} prevede inoltre la possibilità di associare le stesse ai +singoli file eseguibili, in modo da poter stabilire quali capacità possono +essere utilizzate quando viene messo in esecuzione uno specifico programma; ma +il supporto per questa funzionalità è stato introdotto soltanto a partire dal +kernel 2.6.24; fino ad allora doveva essere il programma stesso ad eseguire +una riduzione esplicita delle sue capacità, cosa che ha reso l'uso di questa +funzionalità poco diffuso, vista la presenza di meccanismi alternativi come +\index{SELinux} SELinux. + +Per gestire questo meccanismo ciascun processo porta con sé tre distinti +insiemi di \textit{capabilities}, che vengono denominati rispettivamente +\textit{effective}, \textit{permitted} ed \textit{inherited}. Questi insiemi +vengono mantenuti in forma di tre diverse maschere binarie,\footnote{il kernel + li mantiene, come i vari identificatori di sez.~\ref{sec:proc_setuid}, + all'interno della \struct{task\_struct} di ciascun processo (vedi + fig.~\ref{fig:proc_task_struct}), nei tre campi \texttt{cap\_effective}, + \texttt{cap\_inheritable}, \texttt{cap\_permitted} del tipo + \texttt{kernel\_cap\_t}; questo è attualmente definito come intero a 32 bit, + il che comporta un massimo di 32 \textit{capabilities} distinte.} in cui +ciascun bit corrisponde ad una capacità diversa. + +L'utilizzo di tre distinti insiemi serve a fornire una interfaccia flessibile +per l'uso delle \textit{capabilities}, con scopi analoghi a quelli per cui +sono mantenuti i diversi insiemi di identificatori di +sez.~\ref{sec:proc_setuid}; il loro significato è il seguente: +\begin{basedescript}{\desclabelwidth{2.0cm}\desclabelstyle{\nextlinelabel}} +\item[\textit{effective}] l'insieme delle \textit{capabilities} + ``\textsl{effettive}'', cioè di quelle che vengono effettivamente usate dal + kernel quando deve eseguire il controllo di accesso per le varie operazioni + compiute dal processo. +\item[\textit{permitted}] l'insieme delle \textit{capabilities} + ``\textsl{permesse}'', cioè l'insieme di quelle capacità che un processo + \textsl{può} impostare come \textsl{effettive}. Se un processo cancella una + capacità da questo insieme non potrà più riassumerla (almeno che non esegua + un programma che è \acr{suid} di root). +\item[\textit{inherited}] l'insieme delle \textit{capabilities} + ``\textsl{ereditabili}'', cioè quelle che vengono trasmesse ad un nuovo + programma eseguito attraverso una chiamata ad \func{exec} (con l'eccezione + del caso che questo sia \acr{suid} di root). +\label{sec:capabilities_set} +\end{basedescript} + +Oltre a questi tre insiemi, che sono relativi al singolo processo, il kernel +mantiene un insieme generale valido per tutto il sistema, chiamato +\itindex{capabilities~bounding~set} \textit{capabilities bounding set}. Ogni +volta che un programma viene posto in esecuzione con \func{exec} il contenuto +degli insiemi \textit{effective} e \textit{permitted} vengono mascherati con +un \textsl{AND} binario del contenuto corrente del \textit{capabilities + bounding set}, così che il nuovo processo potrà disporre soltanto delle +capacità in esso elencate. + +Il \textit{capabilities bounding set} è un parametro di sistema, accessibile +attraverso il contenuto del file \procfile{/proc/sys/kernel/cap-bound}, che per +questa sua caratteristica consente di impostare un limite generale alle +capacità che possono essere accordate ai vari processi. Questo valore può +essere impostato ad un valore arbitrario esclusivamente dal primo processo +eseguito nel sistema (di norma cioè da \texttt{/sbin/init}), ogni processo +eseguito successivamente (cioè con \textsl{pid} diverso da 1) anche se +eseguito con privilegi di amministratore potrà soltanto rimuovere uno dei bit +già presenti dell'insieme: questo significa che una volta rimossa una +\textit{capability} dal \textit{capabilities bounding set} essa non sarà più +disponibile, neanche per l'amministratore, a meno di un riavvio. + +Quando un programma viene messo in esecuzione\footnote{cioè quando viene + eseguita la \func{execve} con cui lo si lancia; in corrispondenza di una + \func{fork} le \textit{capabilities} non vengono modificate.} esso eredita +(nel senso che assume negli insiemi \textit{effective} e \textit{permitted}) +le \textit{capabilities} mantenute nell'insieme \textit{inherited}, a meno che +non sia eseguito un programma \acr{suid} di root o la \func{exec} sia stata +eseguita da un programma con \textsl{uid} reale zero; in tal caso il programma +ottiene tutte le \textit{capabilities} presenti nel \textit{capabilities + bounding set}. In questo modo si può far si che ad un processo eseguito in +un secondo tempo possano essere trasmesse solo un insieme limitato di +capacità, impedendogli di recuperare quelle assenti nell'insieme +\textit{inherited}. Si tenga presente invece che attraverso una \func{fork} +vengono mantenute le stesse capacità del processo padre. + + +% TODO verificare per process capability bounding set, vedi: +% http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=3b7391de67da515c91f48aa371de77cb6cc5c07e + +% TODO capire cosa cambia con i patch vari, vedi +% http://lwn.net/Articles/280279/ +% http://lwn.net/Articles/256519/ +% http://lwn.net/Articles/211883/ + + +Un elenco delle delle \textit{capabilities} disponibili su Linux, con una +breve descrizione ed il nome delle costanti che le identificano, è riportato +in tab.~\ref{tab:proc_capabilities};\footnote{l'elenco presentato questa + tabella, ripreso dalla pagina di manuale (accessibile con \texttt{man + capabilities}) e dalle definizioni in \texttt{linux/capabilities.h}, è + aggiornato al kernel 2.6.26.} la tabella è divisa in due parti, la prima +riporta le \textit{capabilities} previste anche nella bozza dello standard +POSIX1.e, la seconda quelle specifiche di Linux. Come si può notare dalla +tabella alcune \textit{capabilities} attengono a singole funzionalità e sono +molto specializzate, mentre altre hanno un campo di applicazione molto vasto, +che è opportuno dettagliare maggiormente. + +\begin{table}[!h!bt] + \centering + \footnotesize + \begin{tabular}{|l|p{12cm}|} + \hline + \textbf{Capacità}&\textbf{Descrizione}\\ + \hline + \hline +% +% POSIX-draft defined capabilities. +% + \const{CAP\_AUDIT\_WRITE}&La capacità di scrivere dati nel giornale di + auditing del kernel (dal kernel 2.6.11).\\ + \const{CAP\_AUDIT\_CONTROL}& La capacità di abilitare e disabilitare il + controllo dell'auditing (dal kernel 2.6.11).\\ + % TODO verificare questa roba dell'auditing + \const{CAP\_CHOWN} & La capacità di cambiare proprietario e gruppo + proprietario di un file (vedi + sez.~\ref{sec:file_ownership_management}).\\ + \const{CAP\_DAC\_OVERRIDE}& La capacità di evitare il controllo dei + permessi di lettura, scrittura ed esecuzione dei + file,\footnotemark (vedi + sez.~\ref{sec:file_access_control}).\\ + \const{CAP\_DAC\_READ\_SEARCH}& La capacità di evitare il controllo dei + permessi di lettura ed esecuzione per + le directory (vedi + sez.~\ref{sec:file_access_control}).\\ + \const{CAP\_FOWNER} & La capacità di evitare il controllo della + proprietà di un file per tutte + le operazioni privilegiate non coperte dalle + precedenti \const{CAP\_DAC\_OVERRIDE} e + \const{CAP\_DAC\_READ\_SEARCH}.\\ + \const{CAP\_FSETID} & La capacità di evitare la cancellazione + automatica dei bit \itindex{suid~bit} \acr{suid} + e \itindex{sgid~bit} \acr{sgid} quando un file + per i quali sono impostati viene modificato da + un processo senza questa capacità e la capacità + di impostare il bit \acr{sgid} su un file anche + quando questo è relativo ad un gruppo cui non si + appartiene (vedi + sez.~\ref{sec:file_perm_management}).\\ + \const{CAP\_SETFCAP} & La capacità di impostare le + \textit{capabilities} di un file (dal kernel + 2.6.24).\\ + \const{CAP\_KILL} & La capacità di mandare segnali a qualunque + processo (vedi sez.~\ref{sec:sig_kill_raise}).\\ + \const{CAP\_SETGID} & La capacità di manipolare i group ID dei + processi, sia il principale che i supplementari, + (vedi sez.~\ref{sec:proc_setgroups}) che quelli + trasmessi tramite i socket \textit{unix domain} + (vedi sez.~\ref{sec:unix_socket}).\\ + \const{CAP\_SETUID} & La capacità di manipolare gli user ID del + processo (vedi sez.~\ref{sec:proc_setuid}) e di + trasmettere un user ID arbitrario nel passaggio + delle credenziali coi socket \textit{unix + domain} (vedi sez.~\ref{sec:unix_socket}).\\ +% +% Linux specific capabilities +% +\hline + \const{CAP\_IPC\_LOCK} & La capacità di effettuare il \textit{memory + locking} \itindex{memory~locking} con le + funzioni \func{mlock}, \func{mlockall}, + \func{shmctl}, \func{mmap} (vedi + sez.~\ref{sec:proc_mem_lock} e + sez.~\ref{sec:file_memory_map}). \\ + \const{CAP\_IPC\_OWNER} & La capacità di evitare il controllo dei permessi + per le operazioni sugli oggetti di + intercomunicazione fra processi (vedi + sez.~\ref{sec:ipc_sysv}).\\ + \const{CAP\_LEASE} & La capacità di creare dei \textit{file lease} + \index{file!lease} (vedi + sez.~\ref{sec:file_asyncronous_lease}) + pur non essendo proprietari del file (dal kernel + 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).\\ + \const{CAP\_MKNOD} & La capacità di creare + \index{file!di~dispositivo} file di dispositivo + con \func{mknod} (vedi + sez.~\ref{sec:file_mknod}) (dal kernel 2.4).\\ + \const{CAP\_NET\_ADMIN} & La capacità di eseguire alcune operazioni + privilegiate sulla rete.\\ + \const{CAP\_NET\_BIND\_SERVICE}& La capacità di porsi in ascolto + su porte riservate (vedi + sez.~\ref{sec:TCP_func_bind}).\\ + \const{CAP\_NET\_BROADCAST}& La capacità di consentire l'uso di socket in + \itindex{broadcast} \textit{broadcast} e + \itindex{multicast} \textit{multicast}.\\ + \const{CAP\_NET\_RAW} & La capacità di usare socket \texttt{RAW} e + \texttt{PACKET} (vedi sez.~\ref{sec:sock_type}).\\ + \const{CAP\_SETPCAP} & La capacità di impostare o rimuovere una + capacità.\\ + % TODO cambiata nel 2.4.24 rc1 ? + \const{CAP\_SYS\_ADMIN} & La capacità di eseguire una serie di compiti + amministrativi. \\ + \const{CAP\_SYS\_BOOT} & La capacità di fare eseguire un riavvio del + sistema.\\ +% TODO trattare reboot e kexec + \const{CAP\_SYS\_CHROOT}& La capacità di eseguire la funzione + \func{chroot} (vedi + sez.~\ref{sec:file_chroot}).\\ + \const{CAP\_MAC\_ADMIN} & La capacità amministrare il MAC di Smack (dal + kernel 2.6.25).\\ + \const{CAP\_MAC\_OVERRIDE}& La capacità evitare il MAC di Smack (dal + kernel 2.6.25).\\ + \const{CAP\_SYS\_MODULE}& La capacità di caricare e rimuovere moduli del + kernel. \\ + \const{CAP\_SYS\_NICE} & La capacità di modificare le priorità dei + processi. \\ + \const{CAP\_SYS\_PACCT} & La capacità di usare le funzioni di + \textit{accounting} dei processi (vedi + sez.~\ref{sec:sys_bsd_accounting}).\\ + \const{CAP\_SYS\_PTRACE}& La capacità di tracciare qualunque processo con + \func{ptrace} (vedi + sez.~\ref{sec:xxx_ptrace}).\\ + \const{CAP\_SYS\_RAWIO} & La capacità di eseguire operazioni sulle porte + di I/O con \func{ioperm} e \func{iopl} (vedi + sez.~\ref{sec:file_io_port}).\\ + \const{CAP\_SYS\_RESOURCE}& La capacità di superare le limitazioni sulle + risorse.\\ + \const{CAP\_SYS\_TIME} & La capacità di modificare il tempo di sistema + (vedi sez.~\ref{sec:sys_time}).\\ + \const{CAP\_SYS\_TTY\_CONFIG}& La capacità di simulare un \textit{hangup} + della console, con la funzione + \func{vhangup}.\\ + \hline + \end{tabular} + \caption{Le costanti che identificano le \textit{capabilities} presenti nel + kernel.} +\label{tab:proc_capabilities} +\end{table} + +\footnotetext{vale a dire i permessi caratteristici del modello classico del + controllo di accesso chiamato \itindex{Discrectionary~Access~Control~(DAC)} + \textit{Discrectionary Access Control} (da cui il nome DAC).} + +La prima di queste capacità ``\textsl{ampie}'' è \const{CAP\_FOWNER}, che +rimuove le restrizioni poste ad un processo che non ha la proprietà di un file +in un vasto campo di operazioni;\footnote{vale a dire la richiesta che + l'user-ID effettivo del processo (o meglio il \textit{filesystem user-ID}, + vedi sez.~\ref{sec:proc_setuid}) coincida con quello del proprietario.} +queste comprendono i cambiamenti dei permessi e dei tempi del file (vedi +sez.~\ref{sec:file_perm_management} e sez.~\ref{sec:file_file_times}), le +impostazioni degli attributi estesi e delle ACL (vedi +sez.~\ref{sec:file_xattr} e \ref{sec:file_ACL}), poter ignorare lo +\itindex{sticky~bit} \textit{sticky bit} nella cancellazione dei file (vedi +sez.~\ref{sec:file_special_perm}), la possibilità di impostare il flag di +\const{O\_NOATIME} con \func{open} e \func{fcntl} (vedi +sez.~\ref{sec:file_open} e sez.~\ref{sec:file_fcntl}) senza restrizioni. + +Una seconda capacità che copre diverse operazioni, in questo caso riguardanti +la rete, è \const{CAP\_NET\_ADMIN}, che consente di impostare le opzioni +privilegiate dei socket (vedi sez.~\ref{sec:sock_generic_options}), abilitare +il \itindex{multicast} \textit{multicasting}, eseguire la configurazione delle +interfacce di rete (vedi sez.~\ref{sec:sock_ioctl_netdevice}) ed impostare la +tabella di instradamento. + +Una terza \textit{capability} con vasto campo di applicazione è +\const{CAP\_SYS\_ADMIN}, che copre una serie di operazioni amministrative, +come impostare le quote disco (vedi sez.\ref{sec:disk_quota}), attivare e +disattivare la swap, montare, rimontare e smontare filesystem (vedi +sez.~\ref{sec:sys_file_config}), effettuare operazioni di controllo sugli +oggetti dell'IPC di SysV (vedi sez.~\ref{sec:ipc_sysv}), operare sugli +attributi estesi di classe \texttt{security} o \texttt{trusted} (vedi +sez.~\ref{sec:file_xattr}), specificare un user-ID arbitrario nella +trasmissione delle credenziali dei socket (vedi sez.~\ref{sec:socket_xxx}), +assegnare classi privilegiate per lo scheduling dell'I/O (vedi +sez.~\ref{sec:io_priority}), superare il limite di sistema sul numero massimo +di file aperti,\footnote{quello indicato da \procfile{/proc/sys/fs/file-max}.} +effettuare operazioni privilegiate sulle chiavi mantenute dal kernel (vedi +sez.~\ref{sec:io_priority}), usare la funzione \func{lookup\_dcookie} (vedi +sez.~\ref{sec:xxx_profiling}), usare \const{CLONE\_NEWNS} con \func{unshare}, +(vedi sez.~\ref{sec:process_clone}). + +Originariamente \const{CAP\_SYS\_NICE} riguardava soltanto la capacità di +aumentare le priorità di esecuzione dei processi, come la diminuzione del +valore di \textit{nice} (vedi sez.~\ref{sec:proc_sched_stand}), l'uso delle +priorità \textit{real-time} (vedi sez.~\ref{sec:proc_real_time}), o +l'impostazione delle affinità di processore (vedi +sez.~\ref{sec:proc_sched_multiprocess}); ma con l'introduzione di priorità +anche riguardo le operazioni di accesso al disco, e, nel caso di sistemi NUMA, +alla memoria, essa viene a coprire anche la possibilità di assegnare priorità +arbitrarie nell'accesso a disco (vedi sez.~\ref{sec:io_priority}) e nelle +politiche di allocazione delle pagine di memoria ai nodi di un sistema NUMA. + +Infine la \textit{capability} \const{CAP\_SYS\_RESOURCE} attiene alla +possibilità di superare i limiti imposti sulle risorse di sistema, come usare +lo spazio disco riservato all'amministratore sui filesystem che lo supportano, +usare la funzione \func{ioctl} per controllare il \textit{journaling} sul +filesystem \acr{ext3}, non subire le quote disco, aumentare i limiti sulle +risorse (vedi sez.~\ref{sec:sys_resource_limit}) e sulle dimensioni dei +messaggi delle code del SysV IPC (vedi sez.~\ref{sec:ipc_sysv_mq}). + + +Per la gestione delle \textit{capabilities} il kernel mette a disposizione due +funzioni che permettono rispettivamente di leggere ed impostare i valori dei +tre insiemi illustrati in precedenza. Queste due funzioni sono \funcd{capget} +e \funcd{capset} e costituiscono l'interfaccia di gestione basso livello; i +loro rispettivi prototipi sono: +\begin{functions} + \headdecl{sys/capability.h} + + \funcdecl{int capget(cap\_user\_header\_t hdrp, cap\_user\_data\_t datap)} + Legge le \textit{capabilities}. + + \funcdecl{int capset(cap\_user\_header\_t hdrp, const cap\_user\_data\_t + datap)} + Imposta le \textit{capabilities}. + + + \bodydesc{Entrambe le funzioni ritornano 0 in caso di successo e -1 in caso + di errore, nel qual caso \var{errno} può assumere i valori: + \begin{errlist} + \item[\errcode{ESRCH}] si è fatto riferimento ad un processo inesistente. + \item[\errcode{EPERM}] si è tentato di aggiungere una capacità + nell'insieme delle \textit{capabilities} permesse, o di impostare una + capacità non presente nell'insieme di quelle permesse negli insieme + delle effettive o ereditate, o si è cercato di impostare una + \textit{capability} di un altro processo senza avare + \const{CAP\_SETPCAP}. + \end{errlist} + ed inoltre \errval{EFAULT} ed \errval{EINVAL}. +} + +\end{functions} + +Queste due funzioni prendono come argomenti due tipi di dati dedicati, +definiti come puntatori a due strutture specifiche di Linux, illustrate in +fig.~\ref{fig:cap_kernel_struct}. Per poterle utilizzare occorre anche +cancellare la macro \macro{\_POSIX\_SOURCE}.\footnote{per farlo occorre + utilizzare la direttiva di preprocessore \direct{undef}; si dovrà cioè + inserire una istruzione \texttt{\#undef \_POSIX\_SOURCE} prima di includere + \texttt{sys/capability.h}.} Si tenga presente che le strutture di +fig.~\ref{fig:cap_kernel_struct}, come i prototipi delle due funzioni +\func{capget} e \func{capset}, sono soggette ad essere modificate con il +cambiamento del kernel (in particolare i tipi di dati delle strutture) ed +anche se finora l'interfaccia è risultata stabile, non c'è nessuna +assicurazione che questa venga mantenuta.\footnote{anzi, visto lo scarso + utilizzo di questa funzionalità ci sono state varie discussioni fra gli + sviluppatori del kernel relative all'eliminarla o al modificarla + radicalmente.} Pertanto se si vogliono scrivere programmi portabili che +possano essere eseguiti su qualunque versione del kernel è opportuno +utilizzare le interfacce di alto livello. + +\begin{figure}[!htb] + \footnotesize + \centering + \begin{minipage}[c]{15cm} + \includestruct{listati/cap_user_header_t.h} + \end{minipage} + \normalsize + \caption{Definizione delle strutture a cui fanno riferimento i puntatori + \structd{cap\_user\_header\_t} e \structd{cap\_user\_data\_t} usati per + l'interfaccia di gestione di basso livello delle \textit{capabilities}.} + \label{fig:cap_kernel_struct} +\end{figure} + +La struttura a cui deve puntare l'argomento \param{hdrp} serve ad indicare, +tramite il campo \var{pid}, il processo del quale si vogliono leggere o +modificare le \textit{capabilities}. Il campo \var{version} deve essere +impostato al valore della versione delle usata dal kernel (quello indicato +dalla costante \const{\_LINUX\_CAPABILITY\_VERSION} di +fig.~\ref{fig:cap_kernel_struct}) altrimenti le funzioni ritorneranno con un +errore di \errcode{EINVAL}, restituendo nel campo stesso il valore corretto +della versione in uso. La struttura a cui deve puntare l'argomento +\param{datap} invece conterrà i valori letti o da impostare per i tre insiemi +delle capacità del processo. + +Dato che le precedenti funzioni, oltre ad essere specifiche di Linux, non +garantiscono la stabilità nell'interfaccia, è sempre opportuno effettuare la +gestione delle \textit{capabilities} utilizzando le funzioni di libreria a +questo dedicate. Queste funzioni, che seguono quanto previsto nelle bozze +dello standard POSIX.1e, non fanno parte delle \acr{glibc} e sono fornite in +una libreria a parte,\footnote{la libreria è \texttt{libcap2}, nel caso di + Debian può essere installata con il pacchetto omonimo.} pertanto se un +programma le utilizza si dovrà indicare esplicitamente l'uso della suddetta +libreria attraverso l'opzione \texttt{-lcap} del compilatore. + +Le funzioni dell'interfaccia delle bozze di POSIX.1e prevedono l'uso di uno +tipo di dato opaco, \type{cap\_t}, come puntatore ai dati mantenuti nel +cosiddetto \textit{capability state},\footnote{si tratta in sostanza di un + puntatore ad una struttura interna utilizzata dalle librerie, i cui campi + non devono mai essere acceduti direttamente.} in sono memorizzati tutti i +dati delle \textit{capabilities}. In questo modo è possibile mascherare i +dettagli della gestione di basso livello, che potranno essere modificati senza +dover cambiare le funzioni dell'interfaccia, che faranno riferimento soltanto +ad oggetti di questo tipo. L'interfaccia pertanto non soltanto fornisce le +funzioni per modificare e leggere le \textit{capabilities}, ma anche quelle +per gestire i dati attraverso \type{cap\_t}. + +La prima funzione dell'interfaccia è quella che permette di inizializzare un +\textit{capability state}, allocando al contempo la memoria necessaria per i +relativi dati. La funzione è \funcd{cap\_init} ed il suo prototipo è: +\begin{functions} + \headdecl{sys/capability.h} + + \funcdecl{cap\_t cap\_init(void)} + Crea ed inizializza un \textit{capability state}. + + \bodydesc{La funzione ritorna un valore non nullo in caso di successo e + \macro{NULL} in caso di errore, nel qual caso \var{errno} assumerà il + valore \errval{ENOMEM}. + } +\end{functions} + +La funzione restituisce il puntatore \type{cap\_t} ad uno stato inizializzato +con tutte le \textit{capabilities} azzerate. In caso di errore (cioè quando +non c'è memoria sufficiente ad allocare i dati) viene restituito \macro{NULL} +ed \var{errno} viene impostata a \errval{ENOMEM}. La memoria necessaria a +mantenere i dati viene automaticamente allocata da \func{cap\_init}, ma dovrà +essere disallocata esplicitamente quando non è più necessaria utilizzando, per +questo l'interfaccia fornisce una apposita funzione, \funcd{cap\_free}, il cui +prototipo è: +\begin{functions} + \headdecl{sys/capability.h} + + \funcdecl{int cap\_free(void *obj\_d)} + Disalloca la memoria allocata per i dati delle \textit{capabilities}. + + \bodydesc{La funzione ritorna 0 in caso di successo e $-1$ in caso di + errore, nel qual caso \var{errno} assumerà il valore \errval{EINVAL}. + } +\end{functions} + +La funzione permette di liberare la memoria allocata dalle altre funzioni +della libreria sia per un \textit{capability state}, nel qual caso l'argomento +dovrà essere un dato di tipo \type{cap\_t}, che per una descrizione testuale +dello stesso,\footnote{cioè quanto ottenuto tramite la funzione + \func{cap\_to\_text}.} nel qual caso l'argomento dovrà essere un dato di +tipo \texttt{char *}. Per questo l'argomento \param{obj\_d} è dichiarato come +\texttt{void *} e deve sempre corrispondere ad un puntatore ottenuto tramite +le altre funzioni della libreria, altrimenti la funzione fallirà con un errore +di \errval{EINVAL}. + +Infine si può creare una copia di un \textit{capability state} ottenuto in +precedenza tramite la funzione \funcd{cap\_dup}, il cui prototipo è: +\begin{functions} + \headdecl{sys/capability.h} + + \funcdecl{cap\_t cap\_dup(cap\_t cap\_p)} + Duplica un \textit{capability state} restituendone una copia. + + \bodydesc{La funzione ritorna un valore non nullo in caso di successo e + \macro{NULL} in caso di errore, nel qual caso \var{errno} potrà assumere i + valori \errval{ENOMEM} o \errval{EINVAL}. + } +\end{functions} + +La funzione crea una copia del \textit{capability state} posto all'indirizzo +\param{cap\_p} che si è passato come argomento, restituendo il puntatore alla +copia, che conterrà gli stessi valori delle \textit{capabilities} presenti +nell'originale. La memoria necessaria viene allocata automaticamente dalla +funzione. Una volta effettuata la copia i due \textit{capability state} +potranno essere modificati in maniera completamente +indipendente.\footnote{alla fine delle operazioni si ricordi però di + disallocare anche la copia, oltre all'originale. } + +Una seconda classe di funzioni di servizio previste dall'interfaccia sono +quelle per la gestione dei dati contenuti all'interno di un \textit{capability + state}; la prima di queste è \funcd{cap\_clear}, il cui prototipo è: +\begin{functions} + \headdecl{sys/capability.h} + + \funcdecl{int cap\_clear(cap\_t cap\_p)} + Inizializza un \textit{capability state} cancellando tutte le + \textit{capabilities}. + + \bodydesc{La funzione ritorna 0 in caso di successo e $-1$ in caso di + errore, nel qual caso \var{errno} assumerà il valore \errval{EINVAL}. + } +\end{functions} + +La funzione si limita ad azzerare tutte le \textit{capabilities} presenti nel +\textit{capability state} all'indirizzo \param{cap\_p} passato come argomento, +restituendo uno stato \textsl{vuoto}, analogo a quello che si ottiene nella +creazione con \func{cap\_init}. + +Per la gestione dei valori delle \textit{capabilities} presenti in un +\textit{capability state} l'interfaccia prevede due funzioni, +\funcd{cap\_get\_flag} e \funcd{cap\_set\_flag}, che permettono +rispettivamente di leggere o impostare il valore di un flag delle +\textit{capabilities}; i rispettivi prototipi sono: +\begin{functions} + \headdecl{sys/capability.h} + + \funcdecl{int cap\_get\_flag(cap\_t cap\_p, cap\_value\_t cap, cap\_flag\_t + flag, cap\_flag\_value\_t *value\_p)} + Legge il valore di una \textit{capability}. + + \funcdecl{int cap\_set\_flag(cap\_t cap\_p, cap\_flag\_t flag, int ncap, + cap\_value\_t *caps, cap\_flag\_value\_t value)} + Imposta il valore di una \textit{capability}. + + \bodydesc{Le funzioni ritornano 0 in caso di successo e $-1$ in caso di + errore, nel qual caso \var{errno} assumerà il valore \errval{EINVAL}. +} +\end{functions} + +In entrambe le funzioni l'argomento \param{cap\_p} indica il puntatore al +\textit{capability state} su cui operare, mentre l'argomento \param{flag} +indica su quale dei tre insiemi illustrati a +pag.~\pageref{sec:capabilities_set} si intende operare. Questi devono essere +specificati con una variabile di tipo \type{cap\_flag\_t} che può assumere +esclusivamente\footnote{si tratta in effetti di un tipo enumerato, come si può + verificare dalla sua definizione che si trova in + \texttt{/usr/include/sys/capability.h}.} uno dei valori illustrati in +tab.~\ref{tab:cap_set_identifier}. + +\begin{table}[htb] + \centering + \footnotesize + \begin{tabular}[c]{|l|l|} + \hline + \textbf{Valore} & \textbf{Significato} \\ + \hline + \hline + \const{CAP\_EFFECTIVE} & Capacità dell'insieme \textsl{effettivo}.\\ + \const{CAP\_PERMITTED} & Capacità dell'insieme \textsl{permesso}.\\ + \const{CAP\_INHERITABLE}& Capacità dell'insieme \textsl{ereditabile}.\\ + \hline + \end{tabular} + \caption{Valori possibili per il tipo di dato \type{cap\_flag\_t} che + identifica gli insiemi delle \textit{capabilities}.} + \label{tab:cap_set_identifier} +\end{table} + +La capacità che si intende controllare o impostare invece deve essere +specificata attraverso una variabile di tipo \type{cap\_value\_t}, che può +prendere come valore uno qualunque di quelli riportati in +tab.~\ref{tab:proc_capabilities}, in questo caso però non è possibile +combinare diversi valori in una maschera binaria, una variabile di tipo +\type{cap\_value\_t} deve indicare una sola capacità.\footnote{nel file di + header citato nella nota precedente il tipo \type{cap\_value\_t} è definito + come \ctyp{int}, ma i valori validi sono soltanto quelli di + tab.~\ref{tab:proc_capabilities}.} + +Infine lo stato di una capacità è descritto ad una variabile di tipo +\type{cap\_flag\_value\_t}, che a sua volta può assumere soltanto +uno\footnote{anche questo è un tipo enumerato.} dei valori di +tab.~\ref{tab:cap_value_type}. + +\begin{table}[htb] + \centering + \footnotesize + \begin{tabular}[c]{|l|l|} + \hline + \textbf{Valore} & \textbf{Significato} \\ + \hline + \hline + \const{CAP\_CLEAR}& La capacità non è impostata.\\ + \const{CAP\_SET} & La capacità è impostata.\\ + \hline + \end{tabular} + \caption{Valori possibili per il tipo di dato \type{cap\_flag\_value\_t} che + indica lo stato di una capacità.} + \label{tab:cap_value_type} +\end{table} + +La funzione \func{cap\_get\_flag} legge lo stato della capacità indicata +dall'argomento \param{cap} all'interno dell'insieme indicato dall'argomento +\param{flag} e ne restituisce il valore nella variabile posta all'indirizzo +puntato dall'argomento \param{value\_p}; è possibile cioè leggere soltanto uno +stato di una capacità alla volta. + +La funzione \func{cap\_set\_flag} può invece impostare in una sola chiamata +più \textit{capabilities}, anche se solo all'interno dello stesso insieme. Per +questo motivo essa prende un vettore di valori di tipo \type{cap\_value\_t} +nell'argomento \param{caps}, la cui dimensione viene specificata dall'argomento +\param{ncap}. Il tipo di impostazione da eseguire (cancellazione o +impostazione) viene indicato dall'argomento \param{value}. + +Per la visualizzazione dello stato delle \textit{capabilities} l'interfaccia +prevede una funzione apposita, \funcd{cap\_to\_text}, il cui prototipo è: +\begin{functions} + \headdecl{sys/capability.h} + + \funcdecl{char * cap\_to\_text(cap\_t caps, ssize\_t * length\_p)} + + Genera una visualizzazione testuale delle \textit{capabilities}. + + \bodydesc{La funzione ritorna un puntatore alla stringa con la descrizione + delle \textit{capabilities} in caso di successo e \val{NULL} in caso di + errore, nel qual caso \var{errno} può assumere i valori \errval{EINVAL} o + \errval{ENOMEM}. + } +\end{functions} + +La funzione ritorna l'indirizzo di una stringa contente la descrizione +testuale del contenuto del \textit{capabilities state} \param{caps} passato +come argomento, e, qualora l'argomento \param{length\_p} sia diverso da +\val{NULL}, restituisce nella variabile intera da questo puntata la lunghezza +della stringa. La stringa restituita viene allocata automaticamente dalla +funzione e pertanto dovrà essere liberata con \func{cap\_free}. + +Fin quei abbiamo trattato solo le funzioni di servizio relative alla +manipolazione dei \textit{capabilities state}; l'interfaccia di gestione +prevede però anche le funzioni per la gestione delle \textit{capabilities} +stesse. La prima di queste è \funcd{cap\_get\_proc} che consente la lettura +delle \textit{capabilities} del processo corrente, il suo prototipo è: +\begin{functions} + \headdecl{sys/capability.h} + + \funcdecl{cap\_t cap\_get\_proc(void)} + Legge le \textit{capabilities} del processo corrente. + + \bodydesc{La funzione ritorna un valore diverso da \val{NULL} in caso di + successo e \val{NULL} in caso di errore, nel qual caso \var{errno} può + assumere i valori \errval{EINVAL}, \errval{EPERM} o \errval{ENOMEM}. } +\end{functions} + +La funzione legge il valore delle \textit{capabilities} associate al processo +da cui viene invocata, restituendo il risultato tramite il puntatore ad un +\textit{capabilities state} contenente tutti i dati che provvede ad allocare +autonomamente e che di nuovo occorrerà liberare con \func{cap\_free} quando +non sarà più utilizzato. + +Se invece si vogliono leggere le \textit{capabilities} di un processo +specifico occorre usare la funzione \funcd{capgetp}, il cui +prototipo\footnote{su alcune pagine di manuale la funzione è descritta con un + prototipo sbagliato, che prevede un valore di ritorno di tipo \type{cap\_t}, + ma il valore di ritorno è intero, come si può verificare anche dalla + dichiarazione della stessa in \texttt{sys/capability.h}.} è: +\begin{functions} + \headdecl{sys/capability.h} + + \funcdecl{int capgetp(pid\_t pid, cap\_t cap\_d)} + Legge le \textit{capabilities} del processo indicato da \param{pid}. + + \bodydesc{La funzione ritorna 0 in caso di successo e $-1$ in caso di + errore, nel qual caso \var{errno} può assumere i valori \errval{EINVAL}, + \errval{EPERM} o \errval{ENOMEM}. + } +\end{functions} +%TODO controllare e correggere i codici di errore!!! + +La funzione legge il valore delle \textit{capabilities} del processo indicato +con l'argomento \param{pid}, e restituisce il risultato nel +\textit{capabilities state} posto all'indirizzo indicato con l'argomento +\param{cap\_d}; a differenza della precedente in questo caso il +\textit{capability state} deve essere stato creato in precedenza. Qualora il +processo indicato non esista si avrà un errore di \errval{ESRCH}. Gli stessi +valori possono essere letti direttamente nel filesystem \textit{proc}, nei +file \texttt{/proc//status}; ad esempio per \texttt{init} si otterrà +qualcosa del tipo: +\begin{Verbatim} +... +CapInh: 0000000000000000 +CapPrm: 00000000fffffeff +CapEff: 00000000fffffeff +... +\end{Verbatim} + +Infine per impostare le \textit{capabilities} del processo corrente (non +esiste una funzione che permetta di cambiare le \textit{capabilities} di un +altro processo) si deve usare la funzione \funcd{cap\_set\_proc}, il cui +prototipo è: +\begin{functions} + \headdecl{sys/capability.h} + + \funcdecl{int cap\_set\_proc(cap\_t cap\_p)} + Imposta le \textit{capabilities} del processo corrente. + + \bodydesc{La funzione ritorna 0 in caso di successo e $-1$ in caso di + errore, nel qual caso \var{errno} può assumere i valori \errval{EINVAL}, + \errval{EPERM} o \errval{ENOMEM}. + } +\end{functions} + +La funzione modifica le \textit{capabilities} del processo corrente secondo +quanto specificato con l'argomento \param{cap\_p}, posto che questo sia +possibile nei termini spiegati in precedenza (non sarà ad esempio possibile +impostare capacità non presenti nell'insieme di quelle permesse). In caso di +successo i nuovi valori saranno effettivi al ritorno della funzione, in caso +di fallimento invece lo stato delle capacità resterà invariato. Si tenga +presente che \textsl{tutte} le capacità specificate tramite \param{cap\_p} +devono essere permesse; se anche una sola non lo è la funzione fallirà, e per +quanto appena detto, lo stato delle \textit{capabilities} non verrà modificato +(neanche per le parti eventualmente permesse). + +Come esempio di utilizzo di queste funzioni nei sorgenti allegati alla guida +si è distribuito il programma \texttt{getcap.c}, che consente di leggere le +\textit{capabilities} del processo corrente\footnote{vale a dire di sé stesso, + quando lo si lancia, il che può sembrare inutile, ma serve a mostrarci quali + sono le \textit{capabilities} standard che ottiene un processo lanciato + dalla riga di comando.} o tramite l'opzione \texttt{-p}, quelle di un +processo qualunque il cui pid viene passato come parametro dell'opzione. + +\begin{figure}[htb] + \footnotesize \centering + \begin{minipage}[c]{15cm} + \includecodesample{listati/getcap.c} + \end{minipage} + \normalsize + \caption{Corpo principale del programma \texttt{getcap.c}.} + \label{fig:proc_getcap} +\end{figure} + +La sezione principale del programma è riportata in fig.~\ref{fig:proc_getcap}, +e si basa su una condizione sulla variabile \var{pid} che se si è usato +l'opzione \texttt{-p} è impostata (nella sezione di gestione delle opzioni, +che si è tralasciata) al valore del \textsl{pid} del processo di cui si vuole +leggere le \textit{capabilities} e nulla altrimenti. Nel primo caso +(\texttt{\small 1--6}) si utilizza direttamente (\texttt{\small 2}) +\func{cap\_get\_proc} per ottenere lo stato delle capacità del processo, nel +secondo (\texttt{\small 7--14}) prima si inizializza (\texttt{\small 8}) uno +stato vuoto e poi (\texttt{\small 9}) si legge il valore delle capacità del +processo indicato. + +Il passo successivo è utilizzare (\texttt{\small 16}) \func{cap\_to\_text} per +tradurre in una stringa lo stato, e poi (\texttt{\small 17}) stamparlo; infine +(\texttt{\small 19--20}) si libera la memoria allocata dalle precedenti +funzioni con \func{cap\_free} per poi ritornare dal ciclo principale della +funzione. + +\itindend{capabilities} + +% TODO vedi http://lwn.net/Articles/198557/ e +% http://www.madore.org/~david/linux/newcaps/ +% TODO documentare prctl ... + \subsection{Gli attributi estesi} \label{sec:file_xattr} @@ -2784,7 +3740,7 @@ classi di attributi riportate in tab.~\ref{tab:extended_attribute_class}. \begin{table}[htb] \centering \footnotesize - \begin{tabular}{|c|p{10cm}|} + \begin{tabular}{|l|p{10cm}|} \hline \textbf{Nome} & \textbf{Descrizione} \\ \hline @@ -2794,7 +3750,8 @@ classi di attributi riportate in tab.~\ref{tab:extended_attribute_class}. \itindex{Linux~Security~Modules} \textit{Linux Security Modules}), per le realizzazione di meccanismi evoluti di controllo di accesso come \index{SELinux} - SELinux.\\ + SELinux o le \textit{capabilities} dei file di + sez.~\ref{sec:proc_capabilities}.\\ \const{system} & Gli \textit{extended security attributes}: sono usati dal kernel per memorizzare dati di sistema associati ai file come le \itindex{Access~Control~List} ACL (vedi @@ -2823,10 +3780,10 @@ impiega per realizzare delle estensioni (come le \itindex{Access~Control~List} ACL, \index{SELinux} SELinux, ecc.) al tradizionale meccanismo dei controlli di accesso di Unix, l'accesso ai loro valori viene regolato in maniera diversa a seconda sia della loro classe sia di quali, fra le estensioni che li -utilizzano, sono poste in uso. In particolare, per ciascuna delle classi +utilizzano, sono poste in uso. In particolare, per ciascuna delle classi riportate in tab.~\ref{tab:extended_attribute_class}, si hanno i seguenti casi: -\begin{basedescript}{\desclabelwidth{2.0cm}\desclabelstyle{\nextlinelabel}} +\begin{basedescript}{\desclabelwidth{1.7cm}\desclabelstyle{\nextlinelabel}} \item[\texttt{security}] L'accesso agli \textit{extended security attributes} dipende dalle politiche di sicurezza stabilite da loro stessi tramite l'utilizzo di un sistema di controllo basato sui @@ -2857,58 +3814,53 @@ casi: controllo che accedono ad informazioni non disponibili ai processi ordinari. \item[\texttt{user}] L'accesso agli \textit{extended user attributes} è - regolato dagli ordinari permessi dei file a cui essi fanno riferimento: - occorre avere il permesso di lettura per leggerli e quello di scrittura per - scriverli o modificarli. Dato l'uso di questi attributi, si è scelto cioè di - applicare per il loro accesso gli stessi criteri che si usano per l'accesso - al contenuto dei file (o delle directory) cui essi fanno riferimento. - - Questa scelta vale però soltanto per i file e le directory ordinarie, se - valesse in generale infatti si avrebbe un serio problema di sicurezza dato - che esistono diversi oggetti sul filesystem per i quali è normale avere - avere il permesso di scrittura consentito a tutti gli utenti, come i link - simbolici, o alcuni file di dispositivo come \texttt{/dev/null}. Se fosse - possibile usare su di essi gli \textit{extended user attributes} un utente - qualunque potrebbe inserirvi dati a piacere.\footnote{la cosa è stata notata - su XFS, dove questo comportamento permetteva, non essendovi limiti sullo - spazio occupabile dagli \textit{Extended Attributes}, di bloccare il - sistema riempiendo il disco.} - - La semantica del controllo di accesso che abbiamo indicato inoltre non - avrebbe alcun senso al di fuori di file e directory: i permessi di lettura e - scrittura per un file di dispositivo attengono alle capacità di accesso al - dispositivo sottostante,\footnote{motivo per cui si può formattare un disco - anche se \texttt{/dev} è su un filesystem in sola lettura.} mentre per i - link simbolici questi vengono semplicemente ignorati: in nessuno dei due - casi hanno a che fare con il contenuto del file, e nella discussione - relativa all'uso degli \textit{extended user attributes} nessuno è mai stato - capace di indicare una qualche forma sensata di utilizzo degli stessi per - link simbolici o file di dispositivo, e neanche per le fifo o i socket. - - Per questo motivo gli \textit{extended user attributes} sono stati - completamente disabilitati per tutto ciò che non sia un file regolare o una - directory.\footnote{si può verificare la semantica adottata consultando il - file \texttt{fs/xattr.c} dei sorgenti del kernel.} Inoltre per le - directory è stata introdotta una ulteriore restrizione, dovuta di nuovo alla - presenza ordinaria di permessi di scrittura completi su directory come - \texttt{/tmp}. Questo è un altro caso particolare, in cui il premesso di - scrittura viene usato, unito alla presenza dello \itindex{sticky~bit} - \textit{sticky bit}, per garantire il permesso di creazione di nuovi file. - Per questo motivo, per evitare eventuali abusi, se una directory ha lo - \itindex{sticky~bit} \textit{sticky bit} attivo sarà consentito scrivere i - suoi \textit{extended user attributes} soltanto se si è proprietari della - stessa, o si hanno i privilegi amministrativi della capability - \index{capabilities} \const{CAP\_FOWNER}. + regolato dai normali permessi dei file: occorre avere il permesso di lettura + per leggerli e quello di scrittura per scriverli o modificarli. Dato l'uso + di questi attributi si è scelto di applicare al loro accesso gli stessi + criteri che si usano per l'accesso al contenuto dei file (o delle directory) + cui essi fanno riferimento. Questa scelta vale però soltanto per i file e le + directory ordinarie, se valesse in generale infatti si avrebbe un serio + problema di sicurezza dato che esistono diversi oggetti sul filesystem per i + quali è normale avere avere il permesso di scrittura consentito a tutti gli + utenti, come i link simbolici, o alcuni \index{file!di~dispositivo} file di + dispositivo come \texttt{/dev/null}. Se fosse possibile usare su di essi gli + \textit{extended user attributes} un utente qualunque potrebbe inserirvi + dati a piacere.\footnote{la cosa è stata notata su XFS, dove questo + comportamento permetteva, non essendovi limiti sullo spazio occupabile + dagli \textit{Extended Attributes}, di bloccare il sistema riempiendo il + disco.} + + La semantica del controllo di accesso indicata inoltre non avrebbe alcun + senso al di fuori di file e directory: i permessi di lettura e scrittura per + un \index{file!di~dispositivo} file di dispositivo attengono alle capacità + di accesso al dispositivo sottostante,\footnote{motivo per cui si può + formattare un disco anche se \texttt{/dev} è su un filesystem in sola + lettura.} mentre per i link simbolici questi vengono semplicemente + ignorati: in nessuno dei due casi hanno a che fare con il contenuto del + file, e nella discussione relativa all'uso degli \textit{extended user + attributes} nessuno è mai stato capace di indicare una qualche forma + sensata di utilizzo degli stessi per link simbolici o + \index{file!di~dispositivo} file di dispositivo, e neanche per le fifo o i + socket. Per questo motivo essi sono stati completamente disabilitati per + tutto ciò che non sia un file regolare o una directory.\footnote{si può + verificare la semantica adottata consultando il file \texttt{fs/xattr.c} + dei sorgenti del kernel.} Inoltre per le directory è stata introdotta una + ulteriore restrizione, dovuta di nuovo alla presenza ordinaria di permessi + di scrittura completi su directory come \texttt{/tmp}. Per questo motivo, + per evitare eventuali abusi, se una directory ha lo \itindex{sticky~bit} + \textit{sticky bit} attivo sarà consentito scrivere i suoi \textit{extended + user attributes} soltanto se si è proprietari della stessa, o si hanno i + privilegi amministrativi della capability \index{capabilities} + \const{CAP\_FOWNER}. \end{basedescript} Le funzioni per la gestione degli attributi estesi, come altre funzioni di gestione avanzate specifiche di Linux, non fanno parte delle \acr{glibc}, e sono fornite da una apposita libreria, \texttt{libattr}, che deve essere installata a parte;\footnote{la versione corrente della libreria è - \texttt{libattr1}, e nel caso si usi Debian la si può installare con il - pacchetto omonimo ed il collegato \texttt{libattr1-dev}.} pertanto se un -programma le utilizza si dovrà indicare esplicitamente l'uso della suddetta -libreria invocando il compilatore con l'opzione \texttt{-lattr}. + \texttt{libattr1}.} pertanto se un programma le utilizza si dovrà indicare +esplicitamente l'uso della suddetta libreria invocando il compilatore con +l'opzione \texttt{-lattr}. Per poter leggere gli attributi estesi sono disponibili tre diverse funzioni, \funcd{getxattr}, \funcd{lgetxattr} e \funcd{fgetxattr}, che consentono @@ -2939,9 +3891,8 @@ simbolico e ad un file descriptor; i rispettivi prototipi sono: \item[\errcode{ENOTSUP}] gli attributi estesi non sono supportati dal filesystem o sono disabilitati. \end{errlist} - Oltre a questi potranno essere restituiti tutti gli errori di \func{stat}, - ed in particolare \errcode{EPERM} se non si hanno i permessi di accesso - all'attributo. } + e tutti gli errori di \func{stat}, come \errcode{EPERM} se non si hanno i + permessi di accesso all'attributo. } \end{functions} Le funzioni \func{getxattr} e \func{lgetxattr} prendono come primo argomento @@ -3106,16 +4057,14 @@ file descriptor, da specificare con il loro primo argomento. Anche in questo caso l'argomento \param{name} deve essere specificato con le modalità già illustrate in precedenza per le altre funzioni relative agli attributi estesi. - \itindend{Extended~Attributes} -% TODO trattare gli attributi estesi e le funzioni la documentazione di -% sistema è nei pacchetti libxattr1-dev e attr - \subsection{Le \textit{Access Control List}} \label{sec:file_ACL} +% la documentazione di sistema è nei pacchetti libacl1-dev e acl +% vedi anche http://www.suse.de/~agruen/acl/linux-acls/online/ \itindbeg{Access~Control~List} @@ -3783,8 +4732,9 @@ della ACL rappresentata dai dati contenuti nel buffer puntato da utilizzo. Una volta che si disponga della ACL desiderata, questa potrà essere impostata -su un file o una directory. Per far questo sono disponibili due funzioni; la -prima è \funcd{acl\_set\_file}, il cui prototipo è: +su un file o una directory. Per impostare una ACL sono disponibili due +funzioni; la prima è \funcd{acl\_set\_file}, che opera sia su file che su +directory, ed il cui prototipo è: \begin{functions} \headdecl{sys/types.h} \headdecl{sys/acl.h} @@ -3792,7 +4742,7 @@ prima \funcdecl{int acl\_set\_file(const char *path, acl\_type\_t type, acl\_t acl)} - Imposta una ACL su un file. + Imposta una ACL su un file o una directory. \bodydesc{La funzione restituisce $0$ in caso di successo e $-1$ in caso di errore, nel qual caso \var{errno} assumerà uno dei valori: @@ -3812,12 +4762,20 @@ prima } \end{functions} -La funzione ... - -%TODO: finire - -La seconda funzione che consente di impostare una ACL è -\funcd{acl\_set\_fd}, il cui prototipo è: +La funzione consente di assegnare la ACL contenuta in \param{acl} al file o +alla directory indicate dal pathname \param{path}, mentre con \param{type} si +indica il tipo di ACL utilizzando le constanti di tab.~\ref{tab:acl_type}, ma +si tenga presente che le ACL di default possono essere solo impostate +qualora \param{path} indichi una directory. Inoltre perché la funzione abbia +successo la ACL dovrà essere valida, e contenere tutti le voci necessarie, +unica eccezione è quella in cui si specifica una ACL vuota per cancellare la +ACL di default associata a \func{path}.\footnote{questo però è una estensione + della implementazione delle ACL di Linux, la bozza di standard POSIX.1e + prevedeva l'uso della apposita funzione \funcd{acl\_delete\_def\_file}, che + prende come unico argomento il pathname della directory di cui si vuole + cancellare l'ACL di default, per i dettagli si ricorra alla pagina di + manuale.} La seconda funzione che consente di impostare una ACL è +\funcd{acl\_set\_fd}, ed il suo prototipo è: \begin{functions} \headdecl{sys/types.h} \headdecl{sys/acl.h} @@ -3841,12 +4799,19 @@ La seconda funzione che consente di impostare una ACL } \end{functions} +La funzione è del tutto è analoga a \funcd{acl\_set\_file} ma opera +esclusivamente sui file identificati tramite un file descriptor. Non dovendo +avere a che fare con directory (e con la conseguente possibilità di avere una +ACL di default) la funzione non necessita che si specifichi il tipo di ACL, +che sarà sempre di accesso, e prende come unico argomento, a parte il file +descriptor, la ACL da impostare. + Le funzioni viste finora operano a livello di una intera ACL, eseguendo in una sola volta tutte le operazioni relative a tutte le voci in essa contenuta. In generale è possibile modificare un singolo valore all'interno di una singola -voce direttamente con le funzioni previste dallo standardo POSIX.1e. Queste -funzioni però sono alquanto macchinose da utilizzare per cui è probabilmente -più semplice operare direttamente sulla rappresentazione testuale. Questo è il +voce direttamente con le funzioni previste dallo standard POSIX.1e. Queste +funzioni però sono alquanto macchinose da utilizzare per cui è molto più +semplice operare direttamente sulla rappresentazione testuale. Questo è il motivo per non tratteremo nei dettagli dette funzioni, fornendone solo una descrizione sommaria; chi fosse interessato potrà ricorrere alle pagina di manuale. @@ -3857,22 +4822,22 @@ opportuni puntatori di tipo \type{acl\_entry\_t}, che possono essere ottenuti dalla funzione \funcd{acl\_get\_entry} (per una voce esistente) o dalla funzione \funcd{acl\_create\_entry} per una voce da aggiungere. Nel caso della prima funzione si potrà poi ripetere la lettura per ottenere i puntatori alle -singoli voci. - -Una volta ottenuti detti puntatori si porà operare sui contenuti delle singole -voci ... - - -%TODO: finire +singole voci successive alla prima. + +Una volta ottenuti detti puntatori si potrà operare sui contenuti delle singole +voci; con le funzioni \funcd{acl\_get\_tag\_type}, \funcd{acl\_get\_qualifier}, +\funcd{acl\_get\_permset} si potranno leggere rispettivamente tipo, +qualificatore e permessi mentre con le corrispondente funzioni +\funcd{acl\_set\_tag\_type}, \funcd{acl\_set\_qualifier}, +\funcd{acl\_set\_permset} si possono impostare i valori; in entrambi i casi +vengono utilizzati tipi di dato ad hoc.\footnote{descritti nelle singole + pagine di manuale.} Si possono poi copiare i valori di una voce da una ACL +ad un altra con \funcd{acl\_copy\_entry} o eliminare una voce da una ACL con +\funcd{acl\_delete\_entry}. \itindend{Access~Control~List} -% TODO trattare le ACL, la documentazione di sistema è nei pacchetti -% libacl1-dev e acl -% vedi anche http://www.suse.de/~agruen/acl/linux-acls/online/ - - \subsection{La funzione \func{chroot}} \label{sec:file_chroot} @@ -3930,7 +4895,7 @@ chiamate nel processo sar accedere alla parte di albero sovrastante. Si ha così quella che viene chiamata una \textit{chroot jail}, in quanto il processo non può più accedere a file al di fuori della sezione di albero in cui è stato -\textsl{imprigionato}. +\textsl{imprigionato}. Solo un processo con i privilegi di amministratore può usare questa funzione, e la nuova radice, per quanto detto in sez.~\ref{sec:proc_fork}, sarà ereditata @@ -3964,7 +4929,7 @@ programmi e librerie) di cui il server potrebbe avere bisogno. % LocalWords: sez like filesystem unlink MacOS Windows VMS inode kernel unistd -% LocalWords: un'etichetta int const char oldpath newpath errno EXDEV EPERM st +% LocalWords: int const char oldpath newpath errno EXDEV EPERM st Smack SysV % LocalWords: EEXIST EMLINK EACCES ENAMETOOLONG ENOTDIR EFAULT ENOMEM EROFS ls % LocalWords: ELOOP ENOSPC EIO pathname nlink stat vfat fsck EISDIR ENOENT cap % LocalWords: POSIX socket fifo sticky root system call count crash nell' init @@ -3997,9 +4962,23 @@ programmi e librerie) di cui il server potrebbe avere bisogno. % LocalWords: attributes mime ADMIN FOWNER libattr lattr getxattr lgetxattr of % LocalWords: fgetxattr attr ssize ENOATTR ENOTSUP NUL setxattr lsetxattr list % LocalWords: fsetxattr flags XATTR REPLACE listxattr llistxattr flistxattr by -% LocalWords: removexattr lremovexattr fremovexattr attributename lacl acl +% LocalWords: removexattr lremovexattr fremovexattr attributename lacl acl tv % LocalWords: OBJ setfacl len any prefix separator options NUMERIC IDS SMART -% LocalWords: INDENT major number IDE Documentation makedev fopendir proc +% LocalWords: INDENT major number IDE Documentation makedev fopendir proc copy +% LocalWords: euidaccess eaccess delete def tag qualifier permset calendar NOW +% LocalWords: mutt noatime relatime strictatime atim nsec mtim ctim atimensec +% LocalWords: mtimensec utimes timeval futimes lutimes ENOSYS futimens OMIT +% LocalWords: utimensat timespec sec futimesat LIDS DAC OVERRIDE SEARCH chattr +% LocalWords: Discrectionary KILL SETGID domain SETUID setuid setreuid SETPCAP +% LocalWords: setresuid setfsuid IMMUTABLE immutable append only BIND SERVICE +% LocalWords: BROADCAST broadcast multicast multicasting RAW PACKET IPC LOCK +% LocalWords: memory mlock mlockall shmctl mmap MODULE RAWIO ioperm iopl PACCT +% LocalWords: PTRACE ptrace accounting NICE RESOURCE TTY CONFIG hangup vhangup +% LocalWords: LEASE lease SETFCAP AUDIT permitted inherited inheritable AND +% LocalWords: bounding execve fork capget capset header hdrp datap ESRCH undef +% LocalWords: version libcap lcap clear ncap caps pag capgetp CapInh CapPrm +% LocalWords: fffffeff CapEff getcap dell'IPC scheduling dell'I lookup dcookie +% LocalWords: NEWNS unshare nice NUMA ioctl journaling %%% Local Variables: %%% mode: latex