-
-\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!bt]
- \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.\\
- \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).\\
- \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{questa capacità è presente soltanto a partire dai kernel della
- serie 2.4.x.}
-
-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 ...