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 di siamo predisposte delle protezioni per in essere in grado di
-difendersi dagli effetti di una eventuale compromissione del sistema (come
-montare un filesystem in sola lettura per impedirne modifiche), una volta che
-questa sia stata effettuata e si siano ottenuti i privilegi di amministratore,
-queste potranno essere comunque rimosse (nel caso dell'esempio si potrà sempre
-rimontare il sistema in lettura-scrittura).
+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.
-Dato che i privilegi sono sempre gli stessi, non esiste modo per evitare che
-un processo con diritti di amministratore non possa eseguire certe operazioni.
+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.
-
-Queste capacità possano essere abilitate e disabilitate in maniera
-indipendente per ciascun processo, permettendo una granularità molto più fine
-nella distribuzione dei privilegi. Il meccanismo completo delle
-\textit{capabilities} prevederebbe anche la possibilità di associare le stesse
-\textit{capabilities} anche ai singoli file
-eseguibili,\footnote{l'implementazione di Linux si rifà ad una bozza per
- quello che dovrebbe divenire lo standard POSIX.1e, che prevede questa
- funzionalità.} in modo da poter stabilire quali capacità possono essere
-utilizzate quando viene messo in esecuzione uno specifico programma;
-attualmente\footnote{vale a dire almeno fino al kernel 2.6.13, e non è
- disponibile al momento neanche nessuna realizzazione sperimentale.} questa
-funzionalità non è implementata.
-
-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} (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}), è 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}.
-
-
-\begin{table}[!hbt]
+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.13, e
+ finora non è disponibile al momento neanche presente nessuna realizzazione
+ sperimentale delle specifiche POSIX.1e, anche se esistono dei patch di
+ sicurezza del kernel, come LIDS (vedi
+ \href{http://www.lids.org}{\texttt{http://www.lids.org/})} che realizzano
+ qualcosa di simile.}
+
+
+\begin{table}[!h!bt]
\centering
\footnotesize
\begin{tabular}{|l|p{12cm}|}
chiamante ha nel suo insieme di capacità
permesse) da qualunque processo.\\
\const{CAP\_SETUID} & la capacità di manipolare gli user ID del
- processo (e trasmettere un valore arbitrario
- tramite i socket unix domain).\\
+ 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 unix domain (vedi
+ sez.~\ref{sec:unix_socket_xxx}).\\
\const{CAP\_SYS\_ADMIN} & la capacità di eseguire una serie di compiti
amministrativi (come impostare le quote,
attivare e disattivare la swap, montare,
\label{tab:proc_capabilities}
\end{table}
-\footnotetext{questa capacità è presente soltato a partire dai kernel della
- serie 2.4.x.}
+\footnotetext[21]{questa capacità è presente soltato a partire dai kernel
+ della serie 2.4.x.}
\footnotetext{questa capacità è presente soltato 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} (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}), è 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}.
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
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è quelle che vengono effettivamente usate dal
- kernel per eseguire il controllo di accesso per le operazioni compiute dal
- processo.
+ ``\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 che un processo \textsl{può}
- impostare come \textsl{effettive} se ha la capacità \const{CAP\_SETPCAP}. Se
- un processo cancella una capacità da questo insieme non potrà più
- riassumerla (almeno che non esegua un programma che è \acr{suid} di root).
+ ``\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{ereditate}, 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).
+ ``\textsl{ereditate}'', 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).
\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 \file{/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 può al più rimuovere uno dei bit
+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 viene messo in esecuzione (con \func{exec}) un processo 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} Linux usa due funzioni,
+\funcd{capget} e \funcd{capset}, che permettono rispettivamente di leggerne ed
+impostarne i valori, i cui rispettivi prototipi sono:
+\begin{functions}
+ \headdecl{sys/capability.h}
-Oltre a questi tre insiemi relativi al singolo processo il kernel mantiene un
-valore generale per tutto il sistema, chiamato
-\index{capabilities~bounding~set} \textit{capabilities bounding set}. Questo
-è un parametro di sistema, accessibile attraverso il contenuto del file
-\file{/proc/sys/kernel/cap-bound}, che consente di impostare un limite
-generale alle capacità che possono essere accordate ai vari processi.
+ \funcdecl{int capget(cap\_user\_header\_t hdrp, cap\_user\_data\_t datap)}
+ Legge le \textit{capabilities}.
-Il meccanismo prevede infatti che nell'esecuzione di una \func{exec} venga
-utilizzato il valore mantenuto nell'insieme \textit{inherited} per
-inizializzare tutti gli insiemi
+ \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 costituiscono una interfaccia di basso livello, ed usano
+due strutture specifiche di Linux, la cui definizione è riportata in
+fig.~\ref{fig:cap_kernel_struct}. Queste ultime, come le due funzioni
+precedenti, 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,
-vengano
-impostati come valori per le \textit{capabilities} (per tutti e tre gli
-insiemi) del nuovo programma quelle
+\begin{figure}[!htb]
+ \footnotesize
+ \centering
+ \begin{minipage}[c]{15cm}
+ \includestruct{listati/tms.h}
+ \end{minipage}
+ \normalsize
+ \caption{Le strutture specifiche di Linux per l'interfaccia di gestione di
+ basso livello delle \textit{capabilities}.}
+ \label{fig:cap_kernel_struct}
+\end{figure}
+sono definite in una apposita struttura del kernel,
+Per la gestione delle \textit{capabilities} lo standard POSIX.1e prevede l'uso
+di uno specifico tipo di dato \type{cap\_t}, che