From 8247284097011dd78d9207d05efab85da02b7833 Mon Sep 17 00:00:00 2001 From: Simone Piccardi Date: Tue, 11 Oct 2005 22:23:01 +0000 Subject: [PATCH] Qualche correzione sparsa, indicizzazioni, ed aggiunto qualcosa sulle capabilities. --- process.tex | 18 +++--- prochand.tex | 152 ++++++++++++++++++++++++++++++--------------------- signal.tex | 22 ++++---- tcpsock.tex | 4 +- 4 files changed, 112 insertions(+), 84 deletions(-) diff --git a/process.tex b/process.tex index a0024f5..29ca369 100644 --- a/process.tex +++ b/process.tex @@ -899,15 +899,15 @@ L'uso dei flag permette di selezionare con maggior finezza le pagine da bloccare, ad esempio limitandosi a tutte le pagine allocate a partire da un certo momento. -In ogni caso un processo real-time che deve entrare in una sezione critica -deve provvedere a riservare memoria sufficiente prima dell'ingresso, per -scongiurare l'occorrenza di un eventuale \textit{page - fault}\itindex{page~fault} causato dal meccanismo di \textit{copy on - write}\itindex{copy~on~write}. Infatti se nella sezione critica si va ad -utilizzare memoria che non è ancora stata riportata in RAM si potrebbe avere -un \itindex{page~fault}\textit{page fault} durante l'esecuzione della stessa, -con conseguente rallentamento (probabilmente inaccettabile) dei tempi di -esecuzione. +In ogni caso un processo real-time che deve entrare in una +\index{sezione~critica} sezione critica deve provvedere a riservare memoria +sufficiente prima dell'ingresso, per scongiurare l'occorrenza di un eventuale +\textit{page fault}\itindex{page~fault} causato dal meccanismo di \textit{copy + on write}\itindex{copy~on~write}. Infatti se nella \index{sezione~critica} +sezione critica si va ad utilizzare memoria che non è ancora stata riportata +in RAM si potrebbe avere un \itindex{page~fault}\textit{page fault} durante +l'esecuzione della stessa, con conseguente rallentamento (probabilmente +inaccettabile) dei tempi di esecuzione. In genere si ovvia a questa problematica chiamando una funzione che ha allocato una quantità sufficientemente ampia di variabili automatiche, in modo diff --git a/prochand.tex b/prochand.tex index b2b2b0b..443bc47 100644 --- a/prochand.tex +++ b/prochand.tex @@ -1873,56 +1873,51 @@ scrivere codice portabile. 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}|} @@ -2021,8 +2016,12 @@ in tab.~\ref{tab:proc_capabilities}. 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, @@ -2061,12 +2060,28 @@ in tab.~\ref{tab:proc_capabilities}. \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 @@ -2089,22 +2104,35 @@ sez.~\ref{sec:proc_setuid}; il loro significato \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 diff --git a/signal.tex b/signal.tex index aa47a4d..dcef54c 100644 --- a/signal.tex +++ b/signal.tex @@ -1569,10 +1569,10 @@ segnale arriva immediatamente dopo l'esecuzione del controllo (\texttt{\small 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. @@ -1899,9 +1899,9 @@ che essi siano eseguite senza interruzioni. 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)} @@ -1945,10 +1945,10 @@ quell'indirizzo. \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ò diff --git a/tcpsock.tex b/tcpsock.tex index 14c664b..a174506 100644 --- a/tcpsock.tex +++ b/tcpsock.tex @@ -2156,11 +2156,11 @@ fig.~\ref{fig:TCP_echo_server_code_second}; l'unica modifica effettuata prima dell'entrata nel ciclo principale è stata quella di aver introdotto, subito dopo la chiamata (\texttt{\small 17--20}) alla funzione \func{listen}, una eventuale pausa con una condizione (\texttt{\small 21}) sulla variabile -\var{waiting}, che viene inizializzata, con l'opzione \code{-w Nsec}, al +\var{waiting}, che viene inizializzata, con l'opzione \texttt{-w Nsec}, al numero di secondi da aspettare (il valore preimpostato è nullo). Si è potuto lasciare inalterata tutta la sezione di creazione del socket -perché nel server l'unica chiamata ad una system call critica, che può essere +perché nel server l'unica chiamata ad una system call lenta, che può essere interrotta dall'arrivo di \const{SIGCHLD}, è quella ad \func{accept}, che è l'unica funzione che può mettere il processo padre in stato di sleep nel periodo in cui un figlio può terminare; si noti infatti come le altre -- 2.30.2