Spostamento della sezione sulle capabilities, inizio aggiornamento
[gapil.git] / filedir.tex
index b15c5f098b3216c6b5539cb3aea5447d3b19a12f..eca8d1d3be2bbdadad35813fb41b710432826314 100644 (file)
@@ -2730,6 +2730,737 @@ 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
+  di Linux si rifà ad una bozza per quello che dovrebbe divenire lo standard
+  POSIX.1e, che prevede questa funzionalità.} prevederebbe anche la
+possibilità di associare le stesse \textit{capabilities} anche ai singoli file
+eseguibili,\footnote{una descrizione sommaria di questa funzionalità è
+  riportata nella pagina di manuale che descrive l'implementazione delle
+  \textit{capabilities} con Linux (accessibile con \texttt{man capabilities}),
+  ma non essendo implementata non ne tratteremo qui.} in modo da poter
+stabilire quali capacità possono essere utilizzate quando viene messo in
+esecuzione uno specifico programma; attualmente però questa funzionalità non è
+implementata.\footnote{per attualmente si intende fino al kernel 2.6.23;
+  benché l'infrastruttura per crearla sia presente (vedi anche
+  sez.~\ref{sec:file_xattr}) finora non è disponibile nessuna realizzazione
+  delle specifiche POSIX.1e, esistono però dei patch di sicurezza del kernel,
+  come LIDS (vedi \href{http://www.lids.org}{\textsf{http://www.lids.org/})}
+  che realizzano qualcosa di simile.}
+
+% 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 del 2.6.26, vedi
+% http://lwn.net/Articles/280279/  
+
+\begin{table}[!h!btp]
+  \centering
+  \footnotesize
+  \begin{tabular}{|l|p{12cm}|}
+    \hline
+    \textbf{Capacità}&\textbf{Descrizione}\\
+    \hline
+    \hline
+%
+% POSIX-draft defined capabilities.
+%
+    \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, (vedi sez.~\ref{sec:file_access_control})
+                              caratteristici del modello classico del
+                              controllo di accesso chiamato
+                              \itindex{Discrectionary~Access~Control~(DAC)} 
+                              \textit{Discrectionary Access Control} (da cui
+                              il nome DAC).\\  
+    \const{CAP\_DAC\_READ\_SEARCH}& La capacità di evitare il controllo dei
+                              permessi di lettura, scrittura ed esecuzione per
+                              le directory (vedi
+                              sez.~\ref{sec:file_access_control}).\\
+    \const{CAP\_FOWNER}     & La capacità di evitare il controllo 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 di un file per tutte
+                              le operazioni privilegiate non coperte dalle
+                              precedenti \const{CAP\_DAC\_OVERRIDE} e
+                              \const{CAP\_DAC\_READ\_SEARCH}. 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 (con il comando 
+                              \cmd{chattr}) e delle 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}).\\
+    \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\_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 (con \func{setuid}, \func{setreuid},
+                              \func{setresuid}, \func{setfsuid}) e di
+                              trasmettere un valore arbitrario
+                              dell'\textsl{uid} nel passaggio delle
+                              credenziali coi socket \textit{unix domain} (vedi
+                              sez.~\ref{sec:unix_socket}).\\ 
+%
+% Linux specific capabilities
+%
+\hline
+    \const{CAP\_SETPCAP}    & La capacità di impostare o rimuovere una capacità
+                              (limitatamente a quelle che il processo
+                              chiamante ha nel suo insieme di capacità
+                              permesse) da qualunque processo.\\
+% TODO cambiata nel 2.4.24 rc1 ? 
+    \const{CAP\_LINUX\_IMMUTABLE}& La capacità di impostare gli attributi
+                              \textit{immutable} e \itindex{append~mode}
+                              \textit{append only} per i file su un
+                              filesystem che supporta questi 
+                              attributi estesi.\\ 
+    \const{CAP\_NET\_BIND\_SERVICE}& La capacità di porre in ascolto server
+                              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\_ADMIN} & La capacità di eseguire alcune operazioni
+                              privilegiate sulla rete (impostare le opzioni
+                              privilegiate dei socket, abilitare il
+                              \itindex{multicast} \textit{multicasting},
+                              impostare interfacce di rete e 
+                              tabella di instradamento).\\
+    \const{CAP\_NET\_RAW}   & La capacità di usare socket \texttt{RAW} e
+                              \texttt{PACKET} (quelli che permettono di creare
+                              pacchetti nei protocolli di basso livello).\\
+    \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\_SYS\_MODULE}& La capacità di caricare e rimuovere moduli del
+                              kernel. \\ 
+    \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\_CHROOT}& La capacità di eseguire la funzione
+                              \func{chroot} (vedi
+                              sez.~\ref{sec:file_chroot}).\\
+    \const{CAP\_SYS\_PTRACE}& Consente di tracciare qualunque processo con
+                              \func{ptrace} (vedi 
+                              sez.~\ref{sec:xxx_ptrace}).\\
+    \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\_ADMIN} & La capacità di eseguire una serie di compiti
+                              amministrativi (come impostare le quote,
+                              attivare e disattivare la swap, montare,
+                              rimontare e smontare filesystem, ecc.). \\
+    \const{CAP\_SYS\_BOOT}  & La capacità di fare eseguire un riavvio del
+                              sistema.\\
+% TODO trattare reboot e kexec 
+    \const{CAP\_SYS\_NICE}  & La capacità di modificare le priorità dei
+                              processi (vedi sez.~\ref{sec:proc_priority}). \\ 
+    \const{CAP\_SYS\_RESOURCE}& La capacità di superare le limitazioni sulle
+                              risorse, aumentare le quote disco, usare lo
+                              spazio disco riservato all'amministratore.\\ 
+    \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}.\\
+    \const{CAP\_MKNOD}      & La capacità di creare file di dispositivo con la
+                              funzione \func{mknod} (vedi
+                              sez.~\ref{sec:file_mknod}).\footnotemark\\ 
+    \const{CAP\_LEASE}      & La capacità di creare dei \textit{file lease}
+                              \index{file!lease} su di un file (vedi
+                              sez.~\ref{sec:file_asyncronous_lease})
+                              indipendentemente dalla proprietà dello
+                              stesso.\footnotemark\\
+    \const{CAP\_SETFCAP}    & La capacità di impostare le
+                              \textit{capabilities} di un file (non
+                              supportata).\\ 
+    \const{CAP\_AUDIT\_WRITE}&consente la scrittura di dati nel giornale di
+                              auditing del kernel.\\ 
+    \const{CAP\_AUDIT\_CONTROL}& consente di abilitare e disabilitare il
+                              controllo dell'auditing.\footnotemark\\ 
+% TODO verificare questa roba dell'auditing
+    \hline
+  \end{tabular}
+  \caption{Le costanti che identificano le \textit{capabilities} presenti nel
+    kernel.}
+\label{tab:proc_capabilities}
+\end{table}
+
+\footnotetext[21]{questa capacità è presente soltanto a partire dai kernel
+  della serie 2.4.x.}
+
+\footnotetext[22]{questa capacità è presente soltanto a partire dai kernel della
+  serie 2.4.x.}
+
+\footnotetext{queste ultime due capacità sono presenti  soltanto a partire dai
+  kernel della serie 2.6.11.}
+
+Per gestire questo nuovo 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; se ne è riportato
+l'elenco,\footnote{si tenga presente che l'elenco delle \textit{capabilities}
+  presentato questa tabella, ripreso dalla relativa pagina di manuale
+  (accessibile con \texttt{man capabilities}) e dalle definizioni in
+  \texttt{sys/capabilities.h}, è quello aggiornato al kernel 2.6.6.} con una
+breve descrizione, ed il nome delle costanti che identificano i singoli bit,
+in tab.~\ref{tab:proc_capabilities}; la tabella è divisa in due parti, la
+prima riporta le \textit{capabilities} previste nella bozza dello standard
+POSIX1.e, la seconda quelle specifiche di Linux.
+
+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.
+
+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/<pid>/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}
 
@@ -4025,9 +4756,9 @@ programmi e librerie) di cui il server potrebbe avere bisogno.
 % LocalWords:  removexattr lremovexattr fremovexattr attributename  lacl acl
 % LocalWords:  OBJ setfacl len any prefix separator options NUMERIC IDS SMART
 % LocalWords:  INDENT major number IDE Documentation makedev fopendir proc copy
+% LocalWords:  euidaccess eaccess delete def tag qualifier permset
 
 %%% Local Variables: 
 %%% mode: latex
 %%% TeX-master: "gapil"
 %%% End: 
-% LocalWords:  euidaccess eaccess delete def tag qualifier permset