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[18]{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
\end{basedescript}
-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.
-
-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
-
-
+Oltre a questi tre insiemi, che sono relativi al singolo processo, il kernel
+mantiene un insieme generale valido per tutto il sistema, chiamato
+\index{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 da esso una
+\textit{capability} 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 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}.
-vengano
-impostati come valori per le \textit{capabilities} (per tutti e tre gli
-insiemi) del nuovo programma quelle
occorrenza sarà perduta.
Questi esempi ci mostrano che per una gestione effettiva dei segnali occorrono
-funzioni più sofisticate di quelle illustrate finora, che hanno origine dalla
-interfaccia semplice, ma poco sofisticata, dei primi sistemi Unix, in modo da
-consentire la gestione di tutti i possibili aspetti con cui un processo deve
-reagire alla ricezione di un segnale.
+delle funzioni più sofisticate di quelle finora illustrate, queste hanno la
+loro origine nella semplice interfaccia dei primi sistemi Unix, ma con esse
+non è possibile gestire in maniera adeguata di tutti i possibili aspetti con
+cui un processo deve reagire alla ricezione di un segnale.
Le operazioni più semplici, come l'assegnazione o il controllo di una
variabile (per essere sicuri si può usare il tipo \type{sig\_atomic\_t}) di
-norma sono atomiche, quando occorrono operazioni più complesse si può invece
-usare la funzione \funcd{sigprocmask} che permette di bloccare uno o più
-segnali; il suo prototipo è:
+norma sono atomiche; quando si devono eseguire operazioni più complesse si può
+invece usare la funzione \funcd{sigprocmask} che permette di bloccare uno o
+più segnali; il suo prototipo è:
\begin{prototype}{signal.h}
{int sigprocmask(int how, const sigset\_t *set, sigset\_t *oldset)}
\end{table}
In questo modo diventa possibile proteggere delle sezioni di codice bloccando
-l'insieme di segnali voluto per poi riabilitarli alla fine della sezione
-critica. La funzione permette di risolvere problemi come quelli mostrati in
-fig.~\ref{fig:sig_event_wrong}, proteggendo la sezione fra il controllo del
-flag e la sua cancellazione.
+l'insieme di segnali voluto per poi riabilitarli alla fine della
+\index{sezione~critica} sezione critica. La funzione permette di risolvere
+problemi come quelli mostrati in fig.~\ref{fig:sig_event_wrong}, proteggendo
+la sezione fra il controllo del flag e la sua cancellazione.
La funzione può essere usata anche all'interno di un gestore, ad esempio
per riabilitare la consegna del segnale che l'ha invocato, in questo caso però