-con il valore di \var{errno} in caso di errore (\texttt{\small 12--13}).
-
-
-\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,
- poi 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à, chiamata \textit{file capabilities}, è
-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 per ottenere limitazioni delle capacità
-dell'amministratore a livello di sistema operativo, come \index{SELinux}
-SELinux.
-
-Con questo supporto e con le ulteriori modifiche introdotte con il kernel
-2.6.25 il meccanismo delle \textit{capabilities} è stato totalmente
-rivoluzionato, rendendolo più aderente alle intenzioni originali dello
-standard POSIX, rimuovendo il significato che fino ad allora aveva avuto la
-capacità \const{CAP\_SETPCAP} e cambiando le modalità di funzionamento del
-cosiddetto \itindex{capabilities~bounding~set} \textit{capabilities bounding
- set}. Ulteriori modifiche sono state apportate con il kernel 2.6.26 per
-consentire la rimozione non ripristinabile dei privilegi di
-amministratore. Questo fa sì che il significato ed il comportamento del kernel
-finisca per dipendere dalla versione dello stesso e dal fatto che le nuove
-\textit{file capabilities} siano abilitate o meno. Per capire meglio la
-situazione e cosa è cambiato conviene allora spiegare con maggiori dettagli
-come funziona il meccanismo delle \textit{capabilities}.
-
-Il primo passo per frazionare i privilegi garantiti all'amministratore,
-supportato fin dalla introduzione iniziale del kernel 2.2, è stato quello in
-cui a ciascun processo sono stati associati tre distinti insiemi di
-\textit{capabilities}, denominati rispettivamente \textit{permitted},
-\textit{inheritable} ed \textit{effective}. 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 era, fino al kernel 2.6.25 definito come
- intero a 32 bit per un massimo di 32 \textit{capabilities} distinte,
- attualmente è stato aggiornato ad un vettore in grado di mantenerne fino a
- 64.} 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, che è rimasto sostanzialmente
-lo stesso anche dopo le modifiche seguite alla introduzione delle
-\textit{file capabilities} è il seguente:
-\begin{basedescript}{\desclabelwidth{2.1cm}\desclabelstyle{\nextlinelabel}}
-\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} o come
- \textsl{ereditabili}. Se un processo cancella una capacità da questo insieme
- non potrà più riassumerla.\footnote{questo nei casi ordinari, sono
- previste però una serie di eccezioni, dipendenti anche dal tipo di
- supporto, che vedremo meglio in seguito dato il notevole intreccio nella
- casistica.}
-\item[\textit{inheritable}] l'insieme delle \textit{capabilities}
- ``\textsl{ereditabili}'', cioè di quelle che verranno trasmesse come insieme
- delle \textsl{permesse} ad un nuovo programma eseguito attraverso una
- chiamata ad \func{exec}.
-\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.
-\label{sec:capabilities_set}
-\end{basedescript}
-
-Con l'introduzione delle \textit{file capabilities} sono stati introdotti
-altri tre insiemi associabili a ciascun file.\footnote{la realizzazione viene
- eseguita con l'uso di uno specifico attributo esteso,
- \texttt{security.capability}, la cui modifica è riservata, (come illustrato
- in sez.~\ref{sec:file_xattr}) ai processi dotato della capacità
- \const{CAP\_SYS\_ADMIN}.} Le \textit{file capabilities} hanno effetto
-soltanto quando il file che le porta viene eseguito come programma con una
-\func{exec}, e forniscono un meccanismo che consente l'esecuzione dello stesso
-con maggiori privilegi; in sostanza sono una sorta di estensione del
-\acr{suid} bit limitato ai privilegi di amministratore. Anche questi tre
-insiemi sono identificati con gli stessi nomi di quello dei processi, ma il
-loro significato è diverso:
-\begin{basedescript}{\desclabelwidth{2.1cm}\desclabelstyle{\nextlinelabel}}
-\item[\textit{permitted}] (chiamato originariamente \textit{forced}) l'insieme
- delle capacità che con l'esecuzione del programma verranno aggiunte alle
- capacità \textsl{permesse} del processo.
-\item[\textit{inheritable}] (chiamato originariamente \textit{allowed})
- l'insieme delle capacità che con l'esecuzione del programma possono essere
- ereditate dal processo originario (che cioè non vengono tolte
- dall'\textit{inheritable set} del processo originale all'esecuzione di
- \func{exec}).
-\item[\textit{effective}] in questo caso non si tratta di un insieme ma di un
- unico valore logico; se attivo all'esecuzione del programma tutte le
- capacità che risulterebbero \textsl{permesse} verranno pure attivate,
- inserendole automaticamente nelle \textsl{effettive}, se disattivato nessuna
- capacità verrà attivata (cioè l'\textit{effective set} resterà vuoto).
-\end{basedescript}
-
-\itindbeg{capabilities~bounding~set}
-
-Infine come accennato, esiste un ulteriore insieme, chiamato
-\textit{capabilities bounding set}, il cui scopo è quello di costituire un
-limite alle capacità che possono essere attivate per un programma. Il suo
-funzionamento però è stato notevolmente modificato con l'introduzione delle
-\textit{file capabilities} e si deve pertanto prendere in considerazione una
-casistica assai complessa.
-
-Per i kernel fino al 2.6.25, o se non si attiva il supporto per le
-\textit{file capabilities}, il \textit{capabilities bounding set} è un
-parametro generale di sistema, il cui valore viene riportato nel file
-\sysctlfile{kernel/cap-bound}. Il suo valore iniziale è definito in
-sede di compilazione del kernel, e da sempre ha previsto come default la
-presenza di tutte le \textit{capabilities} eccetto \const{CAP\_SETPCAP}. In
-questa situazione solo il primo processo eseguito nel sistema (quello con
-\textsl{pid} 1, di norma \texttt{/sbin/init}) ha la possibilità di
-modificarlo; ogni processo eseguito successivamente, se dotato dei privilegi
-di amministratore, è in grado soltanto di rimuovere una delle
-\textit{capabilities} già presenti dell'insieme.\footnote{per essere precisi
- occorreva la capacità \const{CAP\_SYS\_MODULE}.}
-
-In questo caso l'effetto complessivo del \textit{capabilities bounding set} è
-che solo le capacità in esso presenti possono essere trasmesse ad un altro
-programma attraverso una \func{exec}. Questo in sostanza significa che se un
-qualunque programma elimina da esso una capacità, considerato che
-\texttt{init} (almeno nelle versioni ordinarie) non supporta la reimpostazione
-del \textit{bounding set}, questa non sarà più disponibile per nessun processo
-a meno di un riavvio, eliminando così in forma definitiva quella capacità per
-tutti, compreso l'amministratore.\footnote{la qual cosa, visto il default
- usato per il \textit{capabilities bounding set}, significa anche che
- \const{CAP\_SETPCAP} non è stata praticamente mai usata nella sua forma
- originale.}
-
-Con il kernel 2.6.25 e le \textit{file capabilities} il \textit{bounding set}
-è diventato una proprietà di ciascun processo, che viene propagata invariata
-sia attraverso una \func{fork} che una \func{exec}. In questo caso il file
-\sysctlfile{kernel/cap-bound} non esiste e \texttt{init} non ha nessun
-ruolo speciale, inoltre in questo caso all'avvio il valore iniziale prevede la
-presenza di tutte le capacità (compresa \const{CAP\_SETPCAP}).
-
-Con questo nuovo meccanismo il \textit{bounding set} continua a ricoprire un
-ruolo analogo al precedente nel passaggio attraverso una \func{exec}, come
-limite alle capacità che possono essere aggiunte al processo in quanto
-presenti nel \textit{permitted set} del programma messo in esecuzione, in
-sostanza il nuovo programma eseguito potrà ricevere una capacità presente nel
-suo \textit{permitted set} (quello del file) solo se questa è anche nel
-\textit{bounding set} (del processo). In questo modo si possono rimuovere
-definitivamente certe capacità da un processo, anche qualora questo dovesse
-eseguire un programma privilegiato che prevede di riassegnarle.
-
-Si tenga presente però che in questo caso il \textit{bounding set} blocca
-esclusivamente le capacità indicate nel \textit{permitted set} del programma
-che verrebbero attivate in caso di esecuzione, e non quelle eventualmente già
-presenti nell'\textit{inheritable set} del processo (ad esempio perché
-presenti prima di averle rimosse dal \textit{bounding set}). In questo caso
-eseguendo un programma che abbia anche lui dette capacità nel suo
-\textit{inheritable set} queste verrebbero assegnate.
-
-In questa seconda versione inoltre il \textit{bounding set} costituisce anche
-un limite per le capacità che possono essere aggiunte all'\textit{inheritable
- set} del processo stesso con \func{capset}, sempre nel senso che queste
-devono essere presenti nel \textit{bounding set} oltre che nel
-\textit{permitted set} del processo. Questo limite vale anche per processi con
-i privilegi di amministratore,\footnote{si tratta sempre di avere la
- \textit{capability} \const{CAP\_SETPCAP}.} per i quali invece non vale la
-condizione che le \textit{capabilities} da aggiungere nell'\textit{inheritable
- set} debbano essere presenti nel proprio \textit{permitted set}.\footnote{lo
- scopo anche in questo caso è ottenere una rimozione definitiva della
- possibilità di passare una capacità rimossa dal \textit{bounding set}.}
-
-Come si può notare per fare ricorso alle \textit{capabilities} occorre
-comunque farsi carico di una notevole complessità di gestione, aggravata dalla
-presenza di una radicale modifica del loro funzionamento con l'introduzione
-delle \textit{file capabilities}. Considerato che il meccanismo originale era
-incompleto e decisamente problematico nel caso di programmi che non ne
-sapessero tener conto,\footnote{c'è stato un grosso problema di sicurezza con
- \texttt{sendmail}, riuscendo a rimuovere \const{CAP\_SETGID}
- dall'\textit{inheritable set} di un processo si ottenne di far fallire
- \func{setuid} in maniera inaspettata per il programma (che aspettandosi
- sempre il successo della funzione non ne controllava lo stato di uscita) con
- la conseguenza di effettuare come amministratore operazioni che altrimenti
- sarebbero state eseguite, senza poter apportare danni, da utente normale.}
-ci soffermeremo solo sulla implementazione completa presente a partire dal
-kernel 2.6.25, tralasciando ulteriori dettagli riguardo la versione
-precedente.
-
-Riassumendo le regole finora illustrate tutte le \textit{capabilities} vengono
-ereditate senza modifiche attraverso una \func{fork} mentre, indicati con
-\texttt{orig\_*} i valori degli insiemi del processo chiamante, con
-\texttt{file\_*} quelli del file eseguito e con \texttt{bound\_set} il
-\textit{capabilities bounding set}, dopo l'invocazione di \func{exec} il
-processo otterrà dei nuovi insiemi di capacità \texttt{new\_*} secondo la
-formula (espressa in pseudo-codice C) di fig.~\ref{fig:cap_across_exec}; si
-noti come in particolare il \textit{capabilities bounding set} non viene
-comunque modificato e resta lo stesso sia attraverso una \func{fork} che
-attraverso una \func{exec}.
-
-\begin{figure}[!htbp]
- \footnotesize \centering
- \begin{minipage}[c]{12cm}
- \includecodesnip{listati/cap-results.c}
- \end{minipage}
- \caption{Espressione della modifica delle \textit{capabilities} attraverso
- una \func{exec}.}
- \label{fig:cap_across_exec}
-\end{figure}
-
-\itindend{capabilities~bounding~set}
-
-A queste regole se ne aggiungono delle altre che servono a riprodurre il
-comportamento tradizionale di un sistema unix-like in tutta una serie di
-circostanze. La prima di queste è relativa a quello che avviene quando si
-esegue un file senza \textit{capabilities}; se infatti si considerasse questo
-equivalente al non averne assegnata alcuna, non essendo presenti capacità né
-nel \textit{permitted set} né nell'\textit{inheritable set} del file,
-nell'esecuzione di un qualunque programma l'amministratore perderebbe tutti i
-privilegi originali dal processo.
-
-Per questo motivo se un programma senza \textit{capabilities} assegnate viene
-eseguito da un processo con \ids{UID} reale 0, esso verrà trattato come
-se tanto il \textit{permitted set} che l'\textit{inheritable set} fossero con
-tutte le \textit{capabilities} abilitate, con l'\textit{effective set} attivo,
-col risultato di fornire comunque al processo tutte le capacità presenti nel
-proprio \textit{bounding set}. Lo stesso avviene quando l'eseguibile ha attivo
-il \acr{suid} bit ed appartiene all'amministratore, in entrambi i casi si
-riesce così a riottenere il comportamento classico di un sistema unix-like.
-
-Una seconda circostanza è quella relativa a cosa succede alle
-\textit{capabilities} di un processo nelle possibili transizioni da \ids{UID}
-nullo a \ids{UID} non nullo o viceversa (corrispondenti rispettivamente a
-cedere o riottenere i i privilegi di amministratore) che si possono effettuare
-con le varie funzioni viste in sez.~\ref{sec:proc_setuid}. In questo caso la
-casistica è di nuovo alquanto complessa, considerata anche la presenza dei
-diversi gruppi di identificatori illustrati in tab.~\ref{tab:proc_uid_gid}, si
-avrà allora che:
-\begin{enumerate*}
-\item se si passa da \ids{UID} effettivo nullo a non nullo
- l'\textit{effective set} del processo viene totalmente azzerato, se
- viceversa si passa da \ids{UID} effettivo non nullo a nullo il
- \textit{permitted set} viene copiato nell'\textit{effective set};
-\item se si passa da \textit{file system} \ids{UID} nullo a non nullo verranno
- cancellate dall'\textit{effective set} del processo tutte le capacità
- attinenti i file, e cioè \const{CAP\_LINUX\_IMMUTABLE}, \const{CAP\_MKNOD},
- \const{CAP\_DAC\_OVERRIDE}, \const{CAP\_DAC\_READ\_SEARCH},
- \const{CAP\_MAC\_OVERRIDE}, \const{CAP\_CHOWN}, \const{CAP\_FSETID} e
- \const{CAP\_FOWNER} (le prime due a partire dal kernel 2.2.30), nella
- transizione inversa verranno invece inserite nell'\textit{effective set}
- quelle capacità della precedente lista che sono presenti nel suo
- \textit{permitted set}.
-\item se come risultato di una transizione riguardante gli identificativi dei
- gruppi \textit{real}, \textit{saved} ed \textit{effective} in cui si passa
- da una situazione in cui uno di questi era nullo ad una in cui sono tutti
- non nulli,\footnote{in sostanza questo è il caso di quando si chiama
- \func{setuid} per rimuovere definitivamente i privilegi di amministratore
- da un processo.} verranno azzerati completamente sia il \textit{permitted
- set} che l'\textit{effective set}.
-\end{enumerate*}
-\label{sec:capability-uid-transition}
-
-La combinazione di tutte queste regole consente di riprodurre il comportamento
-ordinario di un sistema di tipo Unix tradizionale, ma può risultare
-problematica qualora si voglia passare ad una configurazione di sistema
-totalmente basata sull'applicazione delle \textit{capabilities}; in tal caso
-infatti basta ad esempio eseguire un programma con \acr{suid} bit di proprietà
-dell'amministratore per far riottenere ad un processo tutte le capacità
-presenti nel suo \textit{bounding set}, anche se si era avuta la cura di
-cancellarle dal \textit{permitted set}.
-
-\itindbeg{securebits}
-
-Per questo motivo a partire dal kernel 2.6.26, se le \textit{file
- capabilities} sono abilitate, ad ogni processo viene stata associata una
-ulteriore maschera binaria, chiamata \textit{securebits flags}, su cui sono
-mantenuti una serie di flag (vedi tab.~\ref{tab:securebits_values}) il cui
-valore consente di modificare queste regole speciali che si applicano ai
-processi con \ids{UID} nullo. La maschera viene sempre mantenuta
-attraverso una \func{fork}, mentre attraverso una \func{exec} viene sempre
-cancellato il flag \const{SECURE\_KEEP\_CAPS}.
-
-\begin{table}[htb]
- \centering
- \footnotesize
- \begin{tabular}{|l|p{10cm}|}
- \hline
- \textbf{Flag} & \textbf{Descrizione} \\
- \hline
- \hline
- \const{SECURE\_KEEP\_CAPS}& Il processo non subisce la cancellazione delle
- sue \textit{capabilities} quando tutti i suoi
- \ids{UID} passano ad un valore non
- nullo (regola di compatibilità per il cambio
- di \ids{UID} n.~3 del precedente
- elenco), sostituisce il precedente uso
- dell'operazione \const{PR\_SET\_KEEPCAPS} di
- \func{prctl}.\\
- \const{SECURE\_NO\_SETUID\_FIXUP}&Il processo non subisce le modifiche
- delle sue \textit{capabilities} nel passaggio
- da nullo a non nullo degli \ids{UID}
- dei gruppi \textit{effective} e
- \textit{file system} (regole di compatibilità
- per il cambio di \ids{UID} nn.~1 e 2 del
- precedente elenco).\\
- \const{SECURE\_NOROOT} & Il processo non assume nessuna capacità
- aggiuntiva quando esegue un programma, anche
- se ha \ids{UID} nullo o il programma ha
- il \acr{suid} bit attivo ed appartiene
- all'amministratore (regola di compatibilità
- per l'esecuzione di programmi senza
- \textit{capabilities}).\\
- \hline
- \end{tabular}
- \caption{Costanti identificative dei flag che compongono la maschera dei
- \textit{securebits}.}
- \label{tab:securebits_values}
-\end{table}
-
-A ciascuno dei flag di tab.~\ref{tab:securebits_values} è inoltre abbinato un
-corrispondente flag di blocco, identificato da una costante omonima con
-l'estensione \texttt{\_LOCKED}, la cui attivazione è irreversibile ed ha
-l'effetto di rendere permanente l'impostazione corrente del corrispondente
-flag ordinario; in sostanza con \const{SECURE\_KEEP\_CAPS\_LOCKED} si rende
-non più modificabile \const{SECURE\_KEEP\_CAPS}, ed analogamente avviene con
-\const{SECURE\_NO\_SETUID\_FIXUP\_LOCKED} per
-\const{SECURE\_NO\_SETUID\_FIXUP} e con \const{SECURE\_NOROOT\_LOCKED} per
-\const{SECURE\_NOROOT}.
-
-Per l'impostazione di questi flag sono stata predisposte due specifiche
-operazioni di \func{prctl} (vedi sez.~\ref{sec:process_prctl}),
-\const{PR\_GET\_SECUREBITS}, che consente di ottenerne il valore, e
-\const{PR\_SET\_SECUREBITS}, che consente di modificarne il valore; per
-quest'ultima sono comunque necessari i privilegi di amministratore ed in
-particolare la capacità \const{CAP\_SETPCAP}. Prima dell'introduzione dei
-\textit{securebits} era comunque possibile ottenere lo stesso effetto di
-\const{SECURE\_KEEP\_CAPS} attraverso l'uso di un'altra operazione di
-\func{prctl}, \const{PR\_SET\_KEEPCAPS}.
-
-\itindend{securebits}
-
-Oltre alla gestione dei \textit{securebits} la nuova versione delle
-\textit{file capabilities} prevede l'uso di \func{prctl} anche per la gestione
-del \textit{capabilities bounding set}, attraverso altre due operazioni
-dedicate, \const{PR\_CAPBSET\_READ} per controllarne il valore e
-\const{PR\_CAPBSET\_DROP} per modificarlo; quest'ultima di nuovo è una
-operazione privilegiata che richiede la capacità \const{CAP\_SETPCAP} e che,
-come indica chiaramente il nome, permette solo la rimozione di una
-\textit{capability} dall'insieme; per i dettagli sull'uso di tutte queste
-operazioni si rimanda alla rilettura di sez.~\ref{sec:process_prctl}.
-
-% 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{include/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!btp]
- \centering
- \footnotesize
- \begin{tabular}{|l|p{10.5cm}|}
- \hline
- \textbf{Capacità}&\textbf{Descrizione}\\
- \hline
- \hline
-%
-% POSIX-draft defined capabilities.
-%
- \const{CAP\_AUDIT\_CONTROL}& La capacità di abilitare e disabilitare il
- controllo dell'auditing (dal kernel 2.6.11).\\
- \const{CAP\_AUDIT\_WRITE}&La capacità di scrivere dati nel giornale di
- auditing del kernel (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\_KILL} & La capacità di mandare segnali a qualunque
- processo (vedi sez.~\ref{sec:sig_kill_raise}).\\
- \const{CAP\_SETFCAP} & La capacità di impostare le
- \textit{capabilities} di un file (dal kernel
- 2.6.24).\\
- \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}
- \itindex{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 modifiche privilegiate alle
- \textit{capabilities}.\\
- \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 (vedi sez.~\ref{sec:sys_reboot}).\\
- \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 \textit{Mandatory
- Access Control} di Smack (dal kernel 2.6.25).\\
- \const{CAP\_MAC\_OVERRIDE}& La capacità evitare il \textit{Mandatory
- Access Control} 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 varie priorità dei
- processi (vedi sez.~\ref{sec:proc_priority}).\\
- \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:process_ptrace}).\\
- \const{CAP\_SYS\_RAWIO} & La capacità di operare sulle porte
- di I/O con \func{ioperm} e \func{iopl} (vedi
- sez.~\ref{sec:process_io_port}).\\
- \const{CAP\_SYS\_RESOURCE}& La capacità di superare le varie 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}.\\
- \const{CAP\_SYSLOG} & La capacità di gestire il buffer dei messaggi
- del kernel, (vedi sez.~\ref{sec:sess_daemon}),
- introdotta dal kernel 2.6.38 come capacità
- separata da \const{CAP\_SYS\_ADMIN}.\\
- \const{CAP\_WAKE\_ALARM}& La capacità di usare i timer di tipo
- \const{CLOCK\_BOOTTIME\_ALARM} e
- \const{CLOCK\_REALTIME\_ALARM}, vedi
- sez.~\ref{sec:sig_timer_adv} (dal kernel 3.0).\\
- \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).}
-
-
-Prima di dettagliare il significato della capacità più generiche, conviene
-però dedicare un discorso a parte a \const{CAP\_SETPCAP}, il cui significato è
-stato completamente cambiato con l'introduzione delle \textit{file
- capabilities} nel kernel 2.6.24. In precedenza questa capacità era quella
-che permetteva al processo che la possedeva di impostare o rimuovere le
-\textit{capabilities} che fossero presenti nel \textit{permitted set} del
-chiamante di un qualunque altro processo. In realtà questo non è mai stato
-l'uso inteso nelle bozze dallo standard POSIX, ed inoltre, come si è già
-accennato, dato che questa capacità è assente nel \textit{capabilities
- bounding set} usato di default, essa non è neanche mai stata realmente
-disponibile.
-
-Con l'introduzione \textit{file capabilities} e il cambiamento del significato
-del \textit{capabilities bounding set} la possibilità di modificare le
-capacità di altri processi è stata completamente rimossa, e
-\const{CAP\_SETPCAP} ha acquisito quello che avrebbe dovuto essere il suo
-significato originario, e cioè la capacità del processo di poter inserire nel
-suo \textit{inheritable set} qualunque capacità presente nel \textit{bounding
- set}. Oltre a questo la disponibilità di \const{CAP\_SETPCAP} consente ad un
-processo di eliminare una capacità dal proprio \textit{bounding set} (con la
-conseguente impossibilità successiva di eseguire programmi con quella
-capacità), o di impostare i \textit{securebits} delle \textit{capabilities}.
-
-La prima fra le capacità ``\textsl{ampie}'' che occorre dettagliare
-maggiormente è \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'\ids{UID} effettivo del
- processo (o meglio l'\ids{UID} di filesystem, 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 dei file (vedi sez.~\ref{sec:file_ioctl}) 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 su
-qualunque oggetto dell'IPC di SysV (vedi sez.~\ref{sec:ipc_sysv}), operare
-sugli attributi estesi dei file di classe \texttt{security} o \texttt{trusted}
-(vedi sez.~\ref{sec:file_xattr}), specificare un \ids{UID} arbitrario
-nella trasmissione delle credenziali dei socket (vedi
-sez.~\ref{sec:socket_credential_xxx}), assegnare classi privilegiate
-(\const{IOPRIO\_CLASS\_RT} e prima del kernel 2.6.25 anche
-\const{IOPRIO\_CLASS\_IDLE}) 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 \sysctlfile{fs/file-max}.}
-effettuare operazioni privilegiate sulle chiavi mantenute dal kernel (vedi
-sez.~\ref{sec:keyctl_management}), usare la funzione \func{lookup\_dcookie},
-usare \const{CLONE\_NEWNS} con \func{unshare} e \func{clone}, (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 di un processo (vedi sez.~\ref{sec:sys_resource_limit}) e quelle sul
-numero di processi, ed i limiti 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 un certo periodo di tempo era anche
-indicato che per poterle utilizzare fosse necessario che la macro
-\macro{\_POSIX\_SOURCE} risultasse non definita (ed era richiesto di inserire
-una istruzione \texttt{\#undef \_POSIX\_SOURCE} prima di includere
-\headfile{sys/capability.h}) requisito che non risulta più
-presente.\footnote{e non è chiaro neanche quanto sia mai stato davvero
- necessario.}
-
-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{viene però
- garantito che le vecchie funzioni continuino a funzionare.} Pertanto se si
-vogliono scrivere programmi portabili che possano essere eseguiti senza
-modifiche o adeguamenti su qualunque versione del kernel è opportuno
-utilizzare le interfacce di alto livello che vedremo più avanti.
-
-\begin{figure}[!htb]
- \footnotesize
- \centering
- \begin{minipage}[c]{\textwidth}
- \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 PID del processo del quale si vogliono leggere
-o modificare le \textit{capabilities}. Con \func{capset} questo, se si usano
-le \textit{file capabilities}, può essere solo 0 o PID del processo chiamante,
-che sono equivalenti. Il campo \var{version} deve essere impostato al valore
-della versione delle stesse usata dal kernel (quello indicato da una delle
-costanti \texttt{\_LINUX\_CAPABILITY\_VERSION\_n} 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 versione due è comunque deprecata e non deve essere
-usata (il kernel stamperà un avviso). I valori delle \textit{capabilities}
-devono essere passati come maschere binarie;\footnote{e si tenga presente che
- i valori di tab.~\ref{tab:proc_capabilities} non possono essere combinati
- direttamente, indicando il numero progressivo del bit associato alla
- relativa capacità.} con l'introduzione delle \textit{capabilities} a 64 bit
-inoltre il puntatore \param{datap} non può essere più considerato come
-relativo ad una singola struttura, ma ad un vettore di due
-strutture.\footnote{è questo cambio di significato che ha portato a deprecare
- la versione 2, che con \func{capget} poteva portare ad un buffer overflow
- per vecchie applicazioni che continuavano a considerare \param{datap} come
- puntatore ad una singola struttura.}
-
-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 un
-\index{tipo!opaco} 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
- \val{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 \val{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 motivo 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
- \val{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}.
-
-\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}
-
-Una variante di \func{cap\_clear} è \funcd{cap\_clear\_flag} che cancella da
-un \textit{capability state} tutte le \textit{capabilities} di un certo
-insieme fra quelli di pag.~\pageref{sec:capabilities_set}, il suo prototipo
-è:
-\begin{functions}
- \headdecl{sys/capability.h}
-
- \funcdecl{int cap\_clear\_flag(cap\_t cap\_p, cap\_flag\_t flag)}
-
- Cancella dal \textit{capability state} \param{cap\_p} tutte le
- \textit{capabilities} dell'insieme \param{flag}.
-
- \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 richiede che si indichi quale degli insiemi si intente cancellare
-con l'argomento \param{flag}. Questo deve essere specificato 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 \headfile{sys/capability.h}.} uno dei valori
-illustrati in tab.~\ref{tab:cap_set_identifier}.
-
-Si possono inoltre confrontare in maniera diretta due diversi
-\textit{capability state} con la funzione \funcd{cap\_compare}; il suo
-prototipo è:
-\begin{functions}
- \headdecl{sys/capability.h}
- \funcdecl{int cap\_compare(cap\_t cap\_a, cap\_t cap\_b)}
-
- Confronta due \textit{capability state}.
-
- \bodydesc{La funzione ritorna 0 se i \textit{capability state} sono identici
- ed un valore positivo se differiscono, non sono previsti errori.}
-\end{functions}
-
-La funzione esegue un confronto fra i due \textit{capability state} passati
-come argomenti e ritorna in un valore intero il risultato, questo è nullo se
-sono identici o positivo se vi sono delle differenze. Il valore di ritorno
-della funzione consente inoltre di per ottenere ulteriori informazioni su
-quali sono gli insiemi di \textit{capabilities} che risultano differenti. Per
-questo si può infatti usare la apposita macro \macro{CAP\_DIFFERS}:
-\begin{functions}
- \funcdecl{int CAP\_DIFFERS(value, flag)} Controlla lo stato di eventuali
- differenze delle \textit{capabilities} nell'insieme \texttt{flag}.
-\end{functions}
-
-La macro che richiede si passi nell'argomento \texttt{value} il risultato
-della funzione \func{cap\_compare} e in \texttt{flag} l'indicazione (coi
-valori di tab.~\ref{tab:cap_set_identifier}) dell'insieme che si intende
-controllare; restituirà un valore diverso da zero se le differenze rilevate da
-\func{cap\_compare} sono presenti nell'insieme indicato.
-
-Per la gestione dei singoli valori delle \textit{capabilities} presenti in un
-\textit{capability state} l'interfaccia prevede due funzioni specifiche,
-\funcd{cap\_get\_flag} e \funcd{cap\_set\_flag}, che permettono
-rispettivamente di leggere o impostare il valore di una capacità all'interno
-in uno dei tre insiemi già citati; 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 si intende operare, sempre con i valori di
-tab.~\ref{tab:cap_set_identifier}.
-
-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} può indicare una sola capacità.\footnote{in
- \headfile{sys/capability.h} 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} lo restituisce nella variabile puntata
-dall'argomento \param{value\_p}. Questa deve essere di tipo
-\type{cap\_flag\_value\_t} ed assumerà uno dei valori di
-tab.~\ref{tab:cap_value_type}. La funzione consente pertanto di leggere solo
-lo 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 ed
-allo stesso valore. 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) per le capacità elencate in \param{caps} viene
-indicato dall'argomento \param{value} sempre con i valori di
-tab.~\ref{tab:cap_value_type}.
-
-Per semplificare la gestione delle \textit{capabilities} l'interfaccia prevede
-che sia possibile utilizzare anche una rappresentazione testuale del contenuto
-di un \textit{capability state} e fornisce le opportune funzioni di
-gestione;\footnote{entrambe erano previste dalla bozza dello standard
- POSIX.1e.} la prima di queste, che consente di ottenere la rappresentazione
-testuale, è \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{capability 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}.
-
-La rappresentazione testuale, che viene usata anche di programmi di gestione a
-riga di comando, prevede che lo stato venga rappresentato con una stringa di
-testo composta da una serie di proposizioni separate da spazi, ciascuna delle
-quali specifica una operazione da eseguire per creare lo stato finale. Nella
-rappresentazione si fa sempre conto di partire da uno stato in cui tutti gli
-insiemi sono vuoti e si provvede a impostarne i contenuti.
-
-Ciascuna proposizione è nella forma di un elenco di capacità, espresso con i
-nomi di tab.~\ref{tab:proc_capabilities} separati da virgole, seguito da un
-operatore, e dall'indicazione degli insiemi a cui l'operazione si applica. I
-nomi delle capacità possono essere scritti sia maiuscoli che minuscoli, viene
-inoltre riconosciuto il nome speciale \texttt{all} che è equivalente a
-scrivere la lista completa. Gli insiemi sono identificati dalle tre lettere
-iniziali: ``\texttt{p}'' per il \textit{permitted}, ``\texttt{i}'' per
-l'\textit{inheritable} ed ``\texttt{e}'' per l'\textit{effective} che devono
-essere sempre minuscole e se ne può indicare più di uno.
-
-Gli operatori possibili sono solo tre: ``\texttt{+}'' che aggiunge le capacità
-elencate agli insiemi indicati, ``\texttt{-}'' che le toglie e ``\texttt{=}''
-che le assegna esattamente. I primi due richiedono che sia sempre indicato sia
-un elenco di capacità che gli insiemi a cui esse devono applicarsi, e
-rispettivamente attiveranno o disattiveranno le capacità elencate nell'insieme
-o negli insiemi specificati, ignorando tutto il resto. I due operatori possono
-anche essere combinati nella stessa proposizione, per aggiungere e togliere le
-capacità dell'elenco da insiemi diversi.
-
-L'assegnazione si applica invece su tutti gli insiemi allo stesso tempo,
-pertanto l'uso di ``\texttt{=}'' è equivalente alla cancellazione preventiva
-di tutte le capacità ed alla impostazione di quelle elencate negli insiemi
-specificati, questo significa che in genere lo si usa una sola volta
-all'inizio della stringa. In tal caso l'elenco delle capacità può non essere
-indicato e viene assunto che si stia facendo riferimento a tutte quante senza
-doverlo scrivere esplicitamente.
-
-Come esempi avremo allora che un processo non privilegiato di un utente, che
-non ha nessuna capacità attiva, avrà una rappresentazione nella forma
-``\texttt{=}'' che corrisponde al fatto che nessuna capacità viene assegnata a
-nessun insieme (vale la cancellazione preventiva), mentre un processo con
-privilegi di amministratore avrà una rappresentazione nella forma
-``\texttt{=ep}'' in cui tutte le capacità vengono assegnate agli insiemi
-\textit{permitted} ed \textit{effective} (e l'\textit{inheritable} è ignorato
-in quanto per le regole viste a pag.~\ref{sec:capability-uid-transition} le
-capacità verranno comunque attivate attraverso una \func{exec}). Infine, come
-esempio meno banale dei precedenti, otterremo per \texttt{init} una
-rappresentazione nella forma ``\texttt{=ep cap\_setpcap-e}'' dato che come
-accennato tradizionalmente \const{CAP\_SETPCAP} è sempre stata rimossa da
-detto processo.
-
-Viceversa per passare ottenere un \textit{capability state} dalla sua
-rappresentazione testuale si può usare \funcd{cap\_from\_text}, il cui
-prototipo è:
-\begin{functions}
- \headdecl{sys/capability.h}
-
- \funcdecl{cap\_t cap\_from\_text(const char *string)}
-
- Crea un \textit{capability state} dalla sua rappresentazione testuale.
-
- \bodydesc{La funzione ritorna un puntatore valido 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 restituisce il puntatore ad un \textit{capability state}
-inizializzato con i valori indicati nella stringa \param{string} che ne
-contiene la rappresentazione testuale. La memoria per il \textit{capability
- state} viene allocata automaticamente dalla funzione e dovrà essere liberata
-con \func{cap\_free}.
-
-Alle due funzioni citate se ne aggiungono altre due che consentono di
-convertire i valori delle costanti di tab.~\ref{tab:proc_capabilities} nelle
-stringhe usate nelle rispettive rappresentazioni e viceversa. Le due funzioni,
-\funcd{cap\_to\_name} e \funcd{cap\_from\_name}, sono estensioni specifiche di
-Linux ed i rispettivi prototipi sono:
-\begin{functions}
- \headdecl{sys/capability.h}
-
- \funcdecl{char * cap\_to\_name(cap\_value\_t cap)}
- \funcdecl{int cap\_from\_name(const char *name, cap\_value\_t *cap\_p)}
- Convertono le \textit{capabilities} dalle costanti alla rappresentazione
- testuale e viceversa.
-
- \bodydesc{La funzione \func{cap\_to\_name} ritorna un valore diverso da
- \val{NULL} in caso di successo e \val{NULL} in caso di errore, mentre
- \func{cap\_to\_name} ritorna rispettivamente 0 e $-1$; per entrambe in
- caso di errore \var{errno} può assumere i valori \errval{EINVAL} o
- \errval{ENOMEM}. }
-\end{functions}
-
-La prima funzione restituisce la stringa (allocata automaticamente e che dovrà
-essere liberata con \func{cap\_free}) che corrisponde al valore della
-capacità \param{cap}, mentre la seconda restituisce nella variabile puntata
-da \param{cap\_p} il valore della capacità rappresentata dalla
-stringa \param{name}.
-
-Fin quei abbiamo trattato solo le funzioni di servizio relative alla
-manipolazione dei \textit{capability state} come strutture di dati;
-l'interfaccia di gestione prevede però anche le funzioni per trattare le
-\textit{capabilities} presenti nei processi. La prima di queste funzioni è
-\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{capability 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 \headfile{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{capability
- 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}[!htbp]
- \footnotesize \centering
- \begin{minipage}[c]{\codesamplewidth}
- \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/
-
-