Programma di esempio delle funzioni delle capabilities, e un po' di
[gapil.git] / prochand.tex
index 9272a20e0bdb429978f21b24de0d56ca4cbbb6fd..4af6ea92cd27ba140ef19b19b6d417b2d7ea4e32 100644 (file)
@@ -126,13 +126,13 @@ struttura, alla cui base c'
 processi.
 
 Il kernel mantiene una tabella dei processi attivi, la cosiddetta
-\textit{process table}; per ciascun processo viene mantenuta una voce,
-costituita da una struttura \struct{task\_struct}, nella tabella dei processi
-che contiene tutte le informazioni rilevanti per quel processo. Tutte le
-strutture usate a questo scopo sono dichiarate nell'header file
-\file{linux/sched.h}, ed uno schema semplificato, che riporta la struttura
-delle principali informazioni contenute nella \struct{task\_struct} (che in
-seguito incontreremo a più riprese), è mostrato in
+\itindex{process~table} \textit{process table}; per ciascun processo viene
+mantenuta una voce, costituita da una struttura \struct{task\_struct}, nella
+tabella dei processi che contiene tutte le informazioni rilevanti per quel
+processo. Tutte le strutture usate a questo scopo sono dichiarate nell'header
+file \file{linux/sched.h}, ed uno schema semplificato, che riporta la
+struttura delle principali informazioni contenute nella \struct{task\_struct}
+(che in seguito incontreremo a più riprese), è mostrato in
 fig.~\ref{fig:proc_task_struct}.
 
 \begin{figure}[htb]
@@ -146,16 +146,18 @@ fig.~\ref{fig:proc_task_struct}.
 Come accennato in sez.~\ref{sec:intro_unix_struct} è lo
 \textit{scheduler}\itindex{scheduler} che decide quale processo mettere in
 esecuzione; esso viene eseguito ad ogni system call ed ad ogni
-interrupt,\footnote{più in una serie di altre occasioni. NDT completare questa
-  parte.} (ma può essere anche attivato esplicitamente). Il timer di sistema
-provvede comunque a che esso sia invocato periodicamente, generando un
-interrupt periodico secondo la frequenza specificata dalla costante
-\const{HZ}, definita in \file{asm/param.h}, ed il cui valore è espresso in
-Hertz.\footnote{Il valore usuale di questa costante è 100, per tutte le
-  architetture eccetto l'alpha, per la quale è 1000. Occorre fare attenzione a
-  non confondere questo valore con quello dei clock tick (vedi
+interrupt,\footnote{più in una serie di altre occasioni.} 
+% TODO completare questa parte.
+(ma può essere anche attivato esplicitamente). Il timer di sistema provvede
+comunque a che esso sia invocato periodicamente, generando un interrupt
+periodico secondo la frequenza specificata dalla costante \const{HZ}, definita
+in \file{asm/param.h}, ed il cui valore è espresso in Hertz.\footnote{Fino al
+  kernel 2.4 l valore usuale di questa costante era 100, per tutte le
+  architetture eccetto l'alpha, per la quale era 1000. Occorre fare attenzione
+  a non confondere questo valore con quello dei clock tick (vedi
   sez.~\ref{sec:sys_unix_time}).}
-%Si ha cioè un interrupt dal timer ogni centesimo di secondo.
+% TODO verificare gli ultimi cambiamenti del 2.6
+% Si ha cioè un interrupt dal timer ogni centesimo di secondo.
 
 Ogni volta che viene eseguito, lo \textit{scheduler}\itindex{scheduler}
 effettua il calcolo delle priorità dei vari processi attivi (torneremo su
@@ -317,22 +319,22 @@ prototipo della funzione 
 Dopo il successo dell'esecuzione di una \func{fork} sia il processo padre che
 il processo figlio continuano ad essere eseguiti normalmente a partire
 dall'istruzione successiva alla \func{fork}; il processo figlio è però una
-copia del padre, e riceve una copia dei segmenti di testo, stack e dati (vedi
-sez.~\ref{sec:proc_mem_layout}), ed esegue esattamente lo stesso codice del
-padre. Si tenga presente però che la memoria è copiata, non condivisa,
-pertanto padre e figlio vedono variabili diverse.
-
-Per quanto riguarda la gestione della memoria, in generale il segmento di
-testo, che è identico per i due processi, è condiviso e tenuto in read-only
-per il padre e per i figli. Per gli altri segmenti Linux utilizza la tecnica
-del \textit{copy on write}\itindex{copy~on~write}; questa tecnica
-comporta che una pagina di memoria viene effettivamente copiata per il nuovo
-processo solo quando ci viene effettuata sopra una scrittura (e si ha quindi
-una reale differenza fra padre e figlio). In questo modo si rende molto più
-efficiente il meccanismo della creazione di un nuovo processo, non essendo più
-necessaria la copia di tutto lo spazio degli indirizzi virtuali del padre, ma
-solo delle pagine di memoria che sono state modificate, e solo al momento
-della modifica stessa.
+copia del padre, e riceve una copia dei segmenti di testo, \itindex{stack} 
+stack e dati (vedi sez.~\ref{sec:proc_mem_layout}), ed esegue esattamente lo
+stesso codice del padre. Si tenga presente però che la memoria è copiata, non
+condivisa, pertanto padre e figlio vedono variabili diverse.
+
+Per quanto riguarda la gestione della memoria, in generale
+il\index{segmento!testo} segmento di testo, che è identico per i due processi,
+è condiviso e tenuto in read-only per il padre e per i figli. Per gli altri
+segmenti Linux utilizza la tecnica del \textit{copy on
+  write}\itindex{copy~on~write}; questa tecnica comporta che una pagina di
+memoria viene effettivamente copiata per il nuovo processo solo quando ci
+viene effettuata sopra una scrittura (e si ha quindi una reale differenza fra
+padre e figlio). In questo modo si rende molto più efficiente il meccanismo
+della creazione di un nuovo processo, non essendo più necessaria la copia di
+tutto lo spazio degli indirizzi virtuali del padre, ma solo delle pagine di
+memoria che sono state modificate, e solo al momento della modifica stessa.
 
 La differenza che si ha nei due processi è che nel processo padre il valore di
 ritorno della funzione \func{fork} è il \acr{pid} del processo figlio, mentre
@@ -898,15 +900,17 @@ secondo lo specchietto riportato in tab.~\ref{tab:proc_waidpid_pid}.
     \textbf{Valore} & \textbf{Opzione} &\textbf{Significato}\\
     \hline
     \hline
-    $<-1$& -- & attende per un figlio il cui \textit{process group} (vedi
-    sez.~\ref{sec:sess_proc_group}) è uguale al
-    valore assoluto di \param{pid}. \\
-    $-1$ & \const{WAIT\_ANY} & attende per un figlio qualsiasi, usata in
-    questa maniera è equivalente a \func{wait}.\\ 
-    $0$  & \const{WAIT\_MYPGRP} & attende per un figlio il cui \textit{process
-    group} è uguale a quello del processo chiamante. \\
-    $>0$ & -- &attende per un figlio il cui \acr{pid} è uguale al
-    valore di \param{pid}.\\
+    $<-1$& --               & attende per un figlio il cui
+                              \itindex{process~group} \textit{process group}
+                              (vedi sez.~\ref{sec:sess_proc_group}) è uguale
+                              al valore assoluto di \param{pid}. \\ 
+    $-1$& \const{WAIT\_ANY} & attende per un figlio qualsiasi, usata in
+                              questa maniera è equivalente a \func{wait}.\\ 
+    $0$ &\const{WAIT\_MYPGRP}&attende per un figlio il cui
+                              \itindex{process~group} \textit{process group} è
+                              uguale a quello del processo chiamante. \\ 
+    $>0$& --                & attende per un figlio il cui \acr{pid} è uguale
+                              al valore di \param{pid}.\\
     \hline
   \end{tabular}
   \caption{Significato dei valori dell'argomento \param{pid} della funzione
@@ -974,9 +978,10 @@ generato dalla terminazione di un figlio, avremo la certezza che la chiamata a
                              valutata solo se \val{WIFSIGNALED} ha restituito
                              un valore non nullo.\\ 
     \macro{WCOREDUMP(s)}   & Vera se il processo terminato ha generato un
-                             file di \textit{core dump}. Può essere valutata
-                             solo se \val{WIFSIGNALED} ha restituito un valore
-                             non nullo.\footnotemark \\ 
+                             file di \itindex{core~dump}\textit{core
+                               dump}. Può essere valutata solo se
+                             \val{WIFSIGNALED} ha restituito un valore non
+                             nullo.\footnotemark \\
     \macro{WIFSTOPPED(s)}  & Vera se il processo che ha causato il ritorno di
                              \func{waitpid} è bloccato. L'uso è possibile solo
                              avendo specificato l'opzione \const{WUNTRACED}. \\
@@ -995,15 +1000,16 @@ generato dalla terminazione di un figlio, avremo la certezza che la chiamata a
     presente come estensione sia in Linux che in altri Unix.}
 
 Entrambe le funzioni di attesa restituiscono lo stato di terminazione del
-processo tramite il puntatore \param{status} (se non interessa memorizzare lo
-stato si può passare un puntatore nullo). Il valore restituito da entrambe le
-funzioni dipende dall'implementazione, e tradizionalmente alcuni bit (in
-genere 8) sono riservati per memorizzare lo stato di uscita, e altri per
-indicare il segnale che ha causato la terminazione (in caso di conclusione
-anomala), uno per indicare se è stato generato un core file, ecc.\footnote{le
-  definizioni esatte si possono trovare in \file{<bits/waitstatus.h>} ma
-  questo file non deve mai essere usato direttamente, esso viene incluso
-  attraverso \file{<sys/wait.h>}.}
+processo tramite il puntatore \param{status} (se non interessa memorizzare
+lo stato si può passare un puntatore nullo). Il valore restituito da
+entrambe le funzioni dipende dall'implementazione, e tradizionalmente alcuni
+bit (in genere 8) sono riservati per memorizzare lo stato di uscita, e altri
+per indicare il segnale che ha causato la terminazione (in caso di
+conclusione anomala), uno per indicare se è stato generato un
+\itindex{core~dump}\textit{core dump}, ecc.\footnote{le definizioni esatte
+  si possono trovare in \file{<bits/waitstatus.h>} ma questo file non deve
+  mai essere usato direttamente, esso viene incluso attraverso
+  \file{<sys/wait.h>}.}
 
 Lo standard POSIX.1 definisce una serie di macro di preprocessore da usare per
 analizzare lo stato di uscita. Esse sono definite sempre in
@@ -1056,9 +1062,9 @@ processi in Unix 
 fatto attraverso una delle funzioni della famiglia \func{exec}. Quando un
 processo chiama una di queste funzioni esso viene completamente sostituito dal
 nuovo programma; il \acr{pid} del processo non cambia, dato che non viene
-creato un nuovo processo, la funzione semplicemente rimpiazza lo stack, lo
-heap, i dati ed il testo del processo corrente con un nuovo programma letto da
-disco. 
+creato un nuovo processo, la funzione semplicemente rimpiazza lo
+\itindex{stack} stack, lo \itindex{heap} heap, i dati ed il testo del processo
+corrente con un nuovo programma letto da disco.
 
 Ci sono sei diverse versioni di \func{exec} (per questo la si è chiamata
 famiglia di funzioni) che possono essere usate per questo compito, in realtà
@@ -1073,9 +1079,9 @@ famiglia di funzioni) che possono essere usate per questo compito, in realt
   \begin{errlist}
   \item[\errcode{EACCES}] il file non è eseguibile, oppure il filesystem è
     montato in \cmd{noexec}, oppure non è un file regolare o un interprete.
-  \item[\errcode{EPERM}] il file ha i bit \acr{suid} o \acr{sgid}, l'utente
-    non è root, il processo viene tracciato, o il filesystem è montato con
-    l'opzione \cmd{nosuid}.
+  \item[\errcode{EPERM}] il file ha i bit \itindex{suid~bit} \acr{suid} o
+    \itindex{sgid~bit} \acr{sgid}, l'utente non è root, il processo viene
+    tracciato, o il filesystem è montato con l'opzione \cmd{nosuid}.
   \item[\errcode{ENOEXEC}] il file è in un formato non eseguibile o non
     riconosciuto come tale, o compilato per un'altra architettura.
   \item[\errcode{ENOENT}] il file o una delle librerie dinamiche o l'interprete
@@ -1211,8 +1217,8 @@ la lista completa 
   (\acr{ppid});
 \item l'\textsl{user-ID reale}, il \textit{group-ID reale} ed i
   \textsl{group-ID supplementari} (vedi sez.~\ref{sec:proc_access_id});
-\item il \textit{session id} (\acr{sid}) ed il \textit{process group-ID}
-  (\acr{pgid}), vedi sez.~\ref{sec:sess_proc_group};
+\item il \textit{session ID} (\acr{sid}) ed il \itindex{process~group}
+  \textit{process group ID} (\acr{pgid}), vedi sez.~\ref{sec:sess_proc_group};
 \item il terminale di controllo (vedi sez.~\ref{sec:sess_ctrl_term});
 \item il tempo restante ad un allarme (vedi sez.~\ref{sec:sig_alarm_abort});
 \item la directory radice e la directory di lavoro corrente (vedi
@@ -1252,10 +1258,11 @@ Abbiamo detto che l'\textsl{user-ID reale} ed il \textsl{group-ID reale}
 restano gli stessi all'esecuzione di \func{exec}; lo stesso vale per
 l'\textsl{user-ID effettivo} ed il \textsl{group-ID effettivo} (il significato
 di questi identificatori è trattato in sez.~\ref{sec:proc_access_id}), tranne
-quando il file che si va ad eseguire abbia o il \acr{suid} bit o lo \acr{sgid}
-bit impostato, in questo caso l'\textsl{user-ID effettivo} ed il
-\textsl{group-ID effettivo} vengono impostati rispettivamente all'utente o al
-gruppo cui il file appartiene (per i dettagli vedi sez.~\ref{sec:proc_perms}).
+quando il file che si va ad eseguire abbia o il \itindex{suid~bit}\acr{suid}
+bit o lo \itindex{sgid~bit} \acr{sgid} bit impostato, in questo caso
+l'\textsl{user-ID effettivo} ed il \textsl{group-ID effettivo} vengono
+impostati rispettivamente all'utente o al gruppo cui il file appartiene (per i
+dettagli vedi sez.~\ref{sec:proc_perms}).
 
 Se il file da eseguire è in formato \emph{a.out} e necessita di librerie
 condivise, viene lanciato il \textit{linker} dinamico \cmd{/lib/ld.so} prima
@@ -1305,8 +1312,10 @@ problematiche connesse ad una gestione accorta dei privilegi.
 
 Come accennato in sez.~\ref{sec:intro_multiuser} il modello base\footnote{in
   realtà già esistono estensioni di questo modello base, che lo rendono più
-  flessibile e controllabile, come le \textit{capabilities}, le ACL per i file
-  o il \textit{Mandatory Access Control} di SELinux; inoltre basandosi sul
+  flessibile e controllabile, come le \itindex{capabilities}
+  \textit{capabilities} illustrate in sez.~\ref{sec:proc_capabilities}, le ACL
+  per i file o il \textit{Mandatory Access Control}
+  \itindex{Mandatory~Access~Control~(MAC)} di SELinux; inoltre basandosi sul
   lavoro effettuato con SELinux, a partire dal kernel 2.5.x, è iniziato lo
   sviluppo di una infrastruttura di sicurezza, il \textit{Linux Security
     Modules}, o LSM, in grado di fornire diversi agganci a livello del kernel
@@ -1316,10 +1325,6 @@ separazione fra l'amministratore (\textsl{root}, detto spesso anche
 \textit{superuser}) che non è sottoposto a restrizioni, ed il resto degli
 utenti, per i quali invece vengono effettuati i vari controlli di accesso.
 
-%Benché il sistema sia piuttosto semplice (è basato su un solo livello di
-% separazione) il sistema permette una
-%notevole flessibilità, 
-
 Abbiamo già accennato come il sistema associ ad ogni utente e gruppo due
 identificatori univoci, lo user-ID ed il group-ID; questi servono al kernel per
 identificare uno specifico utente o un gruppo di utenti, per poi poter
@@ -1403,12 +1408,13 @@ sez.~\ref{sec:file_perm_overview}).
 
 Questi identificatori normalmente sono identici ai corrispondenti del gruppo
 \textit{real} tranne nel caso in cui, come accennato in
-sez.~\ref{sec:proc_exec}, il programma che si è posto in esecuzione abbia i bit
-\acr{suid} o \acr{sgid} impostati (il significato di questi bit è affrontato
-in dettaglio in sez.~\ref{sec:file_suid_sgid}). In questo caso essi saranno
-impostati all'utente e al gruppo proprietari del file. Questo consente, per
-programmi in cui ci sia necessità, di dare a qualunque utente normale
-privilegi o permessi di un altro (o dell'amministratore).
+sez.~\ref{sec:proc_exec}, il programma che si è posto in esecuzione abbia i
+bit \itindex{suid~bit} \acr{suid} o \itindex{sgid~bit} \acr{sgid} impostati
+(il significato di questi bit è affrontato in dettaglio in
+sez.~\ref{sec:file_suid_sgid}). In questo caso essi saranno impostati
+all'utente e al gruppo proprietari del file. Questo consente, per programmi in
+cui ci sia necessità, di dare a qualunque utente normale privilegi o permessi
+di un altro (o dell'amministratore).
 
 Come nel caso del \acr{pid} e del \acr{ppid}, anche tutti questi
 identificatori possono essere letti attraverso le rispettive funzioni:
@@ -1452,9 +1458,10 @@ L'\textsl{user-ID salvato} ed il \textsl{group-ID salvato} sono copie
 dell'\textsl{user-ID effettivo} e del \textsl{group-ID effettivo} del processo
 padre, e vengono impostati dalla funzione \func{exec} all'avvio del processo,
 come copie dell'\textsl{user-ID effettivo} e del \textsl{group-ID effettivo}
-dopo che questi sono stati impostati tenendo conto di eventuali \acr{suid} o
-\acr{sgid}.  Essi quindi consentono di tenere traccia di quale fossero utente
-e gruppo effettivi all'inizio dell'esecuzione di un nuovo programma.
+dopo che questi sono stati impostati tenendo conto di eventuali
+\itindex{suid~bit}\acr{suid} o \itindex{sgid~bit} \acr{sgid}.  Essi quindi
+consentono di tenere traccia di quale fossero utente e gruppo effettivi
+all'inizio dell'esecuzione di un nuovo programma.
 
 L'\textsl{user-ID di filesystem} e il \textsl{group-ID di filesystem} sono
 un'estensione introdotta in Linux per rendere più sicuro l'uso di NFS
@@ -1505,10 +1512,11 @@ all'\textsl{user-ID salvato}. Negli altri casi viene segnalato un errore (con
 \errcode{EPERM}).
 
 Come accennato l'uso principale di queste funzioni è quello di poter
-consentire ad un programma con i bit \acr{suid} o \acr{sgid} impostati (vedi
-sez.~\ref{sec:file_suid_sgid}) di riportare l'\textsl{user-ID effettivo} a
-quello dell'utente che ha lanciato il programma, effettuare il lavoro che non
-necessita di privilegi aggiuntivi, ed eventualmente tornare indietro.
+consentire ad un programma con i bit \itindex{suid~bit} \acr{suid} o
+\itindex{sgid~bit} \acr{sgid} impostati (vedi sez.~\ref{sec:file_suid_sgid})
+di riportare l'\textsl{user-ID effettivo} a quello dell'utente che ha lanciato
+il programma, effettuare il lavoro che non necessita di privilegi aggiuntivi,
+ed eventualmente tornare indietro.
 
 Come esempio per chiarire l'uso di queste funzioni prendiamo quello con cui
 viene gestito l'accesso al file \file{/var/log/utmp}.  In questo file viene
@@ -1856,8 +1864,595 @@ compila con il flag \cmd{-ansi}, 
 scrivere codice portabile.
 
 
-%\subsection{La gestione delle capabilities}
-%\label{sec:proc_capabilities}
+\subsection{La gestione delle \textit{capabilities}}
+\label{sec:proc_capabilities}
+
+\itindbeg{capabilities} 
+
+Come accennato in sez.~\ref{sec:proc_access_id} l'architettura classica della
+gestione dei privilegi in un sistema unix-like ha il sostanziale problema di
+fornire all'amministratore dei poteri troppo ampi, questo comporta che anche
+quando si siano predisposte delle misure di protezione per in essere in grado
+di difendersi dagli effetti di una eventuale compromissione del
+sistema,\footnote{come montare un filesystem in sola lettura per impedirne
+  modifiche, o marcare un file come immutabile.} una volta che questa sia
+stata effettuata e si siano ottenuti i privilegi di amministratore, queste
+potranno essere comunque rimosse.\footnote{nei casi elencati nella precedente
+  nota si potrà sempre rimontare il sistema in lettura-scrittura, o togliere
+  la marcatura di immutabilità.}
+
+Il problema consiste nel fatto che nell'architettura tradizionale di un
+sistema unix-like i controlli di accesso sono basati su un solo livello di
+separazione: per i processi normali essi sono posti in atto, mentre per i
+processi con i privilegi di amministratore essi non vengono neppure eseguiti;
+per questo motivo non era previsto alcun modo per evitare che un processo con
+diritti di amministratore non potesse eseguire certe operazioni, o per cedere
+definitivamente alcuni privilegi da un certo momento in poi.
+
+Per ovviare a tutto ciò, a partire dai kernel della serie 2.2, è stato
+introdotto un meccanismo, detto \textit{capabilities}, che consentisse di
+suddividere i vari privilegi tradizionalmente associati all'amministratore in
+un insieme di \textsl{capacità} distinte.  L'idea era che queste capacità
+potessero essere abilitate e disabilitate in maniera indipendente per ciascun
+processo con privilegi di amministratore, permettendo così una granularità
+molto più fine nella distribuzione degli stessi che evitasse la originaria
+situazione di \textsl{tutto o nulla}.
+
+Il meccanismo completo delle \textit{capabilities}\footnote{l'implementazione
+  di Linux si rifà ad una bozza per quello che dovrebbe divenire lo standard
+  POSIX.1e, che prevede questa funzionalità.} prevederebbe anche la
+possibilità di associare le stesse \textit{capabilities} anche ai singoli file
+eseguibili,\footnote{una descrizione sommaria di questa funzionalità è
+  riportata nella pagina di manuale che descrive l'implementazione delle
+  \textit{capabilities} con Linux (accessibile con \texttt{man capabilities}),
+  ma non essendo implementata non ne tratteremo qui.} in modo da poter
+stabilire quali capacità possono essere utilizzate quando viene messo in
+esecuzione uno specifico programma; attualmente però questa funzionalità non è
+implementata.\footnote{per attualmente si intende fino al kernel 2.6.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}|}
+    \hline
+    \textbf{Capacità}&\textbf{Descrizione}\\
+    \hline
+    \hline
+    \const{CAP\_CHOWN}      & la capacità di cambiare proprietario e gruppo
+                              proprietario di un file (vedi
+                              sez.~\ref{sec:file_chown}).\\
+    \const{CAP\_DAC\_OVERRIDE}& la capacità di evitare il controllo dei
+                              permessi di lettura, scrittura ed esecuzione dei
+                              file, (vedi sez.~\ref{sec:file_access_control})
+                              caratteristici del modello classico del
+                              controllo di accesso chiamato
+                              \itindex{Discrectionary~Access~Control~(DAC)} 
+                              \textit{Discrectionary Access Control} (da cui
+                              il nome DAC).\\  
+    \const{CAP\_DAC\_READ\_SEARCH}& la capacità di evitare il controllo dei
+                              permessi di lettura, scrittura ed esecuzione per
+                              le directory (vedi
+                              sez.~\ref{sec:file_access_control}).\\
+    \const{CAP\_FOWNER}     & la capacità di evitare il controllo che 
+                              l'user-ID effettivo del processo (o meglio il
+                              \textit{filesystem user-ID}, vedi
+                              sez.~\ref{sec:proc_setuid}) coincida con
+                              quello del proprietario di un file per tutte
+                              le operazioni privilegiate non coperte dalle
+                              precedenti \const{CAP\_DAC\_OVERRIDE} e
+                              \const{CAP\_DAC\_READ\_SEARCH}. Queste
+                              comprendono i cambiamenti dei permessi e dei
+                              tempi del file (vedi sez.~\ref{sec:file_chmod} e
+                              sez.~\ref{sec:file_utime}), le impostazioni degli
+                              attributi estesi (con il comando \cmd{chattr}) e
+                              delle ACL, poter ignorare lo
+                              \itindex{sticky~bit} \textit{sticky bit} nella
+                              cancellazione dei file (vedi
+                              sez.~\ref{sec:file_sticky}), la possibilità di
+                              impostare il flag di \const{O\_NOATIME} con
+                              \func{open} e \func{fcntl} (vedi
+                              sez.~\ref{sec:file_open} e
+                              sez.~\ref{sec:file_fcntl}).\\
+    \const{CAP\_FSETID}     & la capacità di evitare la cancellazione
+                              automatica dei bit \itindex{suid~bit} \acr{suid}
+                              e \itindex{sgid~bit} \acr{sgid} quando un file
+                              per i quali sono impostati viene modificato da
+                              un processo senza questa capacità e la capacità
+                              di impostare il bit \acr{sgid} su un file anche
+                              quando questo è relativo ad un gruppo cui non si
+                              appartiene (vedi sez.~\ref{sec:file_chmod}).\\ 
+    \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\_KILL}       & la capacità di mandare segnali a qualunque
+                              processo (vedi sez.~\ref{sec:sig_kill_raise}).\\
+    \const{CAP\_LEASE}      & la capacità di creare dei \textit{file lease}
+                              \index{file!lease} su di un file (vedi
+                              sez.~\ref{sec:file_asyncronous_lease})
+                              indipendentemente dalla proprietà dello
+                              stesso.\footnotemark\\
+    \const{CAP\_LINUX\_IMMUTABLE}& la capacità di impostare gli attributi
+                              \textit{immutable} e \textit{append only} per i
+                              file su un filesystem che supporta questi
+                              attributi estesi.\\ 
+    \const{CAP\_MKNOD}      & la capacità di creare file di dispositivo con la
+                              funzione \func{mknod} (vedi
+                              sez.~\ref{sec:file_mknod}).\footnotemark\\ 
+    \const{CAP\_NET\_ADMIN} & la capacità di eseguire alcune operazioni
+                              privilegiate sulla rete (impostare le opzioni
+                              privilegiate dei socket, abilitare il
+                              multicasting, impostare interfacce di rete e
+                              tabella di instradamento).\\
+    \const{CAP\_NET\_BIND\_SERVICE}& la capacità di porre in ascolto server
+                              su porte riservate (vedi
+                              sez.~\ref{sec:TCP_func_bind}).\\ 
+    \const{CAP\_NET\_BROADCAST}& la capacità di consentire l'uso di socket in
+                              broadcast e multicast.\\
+    \const{CAP\_NET\_RAW}   & la capacità di usare socket \texttt{RAW} e
+                              \texttt{PACKET} (quelli che permettono di creare
+                              pacchetti nei protocolli di basso livello).\\
+    \const{CAP\_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 \index{socket} socket
+                              \textit{unix domain} (vedi
+                              sez.~\ref{sec:unix_socket}).\\
+    \const{CAP\_SETPCAP}    & la capacità di impostare o rimuovere una capacità
+                              (limitatamente a quelle che il processo
+                              chiamante ha nel suo insieme di capacità
+                              permesse) da qualunque processo.\\
+    \const{CAP\_SETUID}     & la capacità di manipolare gli user ID del
+                              processo (con \func{setuid}, \func{setreuid},
+                              \func{setresuid}, \func{setfsuid}) e di
+                              trasmettere un valore arbitrario
+                              dell'\textsl{uid} nel passaggio delle
+                              credenziali coi socket 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,
+                              rimontare e smontare filesystem, ecc.). \\
+    \const{CAP\_SYS\_BOOT}  & la capacità di fare eseguire un reboot del
+                              sistema.\\
+    \const{CAP\_SYS\_CHROOT}& la capacità di eseguire la funzione
+                              \func{chroot} (vedi
+                              sez.~\ref{sec:file_chroot}).\\
+    \const{CAP\_SYS\_MODULE}& la capacità di caricare e rimuovere moduli del
+                              kernel. \\ 
+    \const{CAP\_SYS\_NICE}  & la capacità di modificare le 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\_RAWIO} & la capacità di eseguire operazioni sulle porte
+                              di I/O con \func{ioperm} e \func{iopl} (vedi
+                              sez.~\ref{sec:file_io_port}).\\
+    \const{CAP\_SYS\_RESOURCE}& la capacità di superare le limitazioni sulle
+                              risorse, aumentare le quote disco, usare lo
+                              spazio disco riservato all'amministratore.\\ 
+    \const{CAP\_SYS\_TIME}  & la capacità di modificare il tempo di sistema
+                              (vedi sez.~\ref{sec:sys_time}).\\ 
+    \const{CAP\_SYS\_TTY\_CONFIG}& la capacità di simulare un \textit{hangup}
+                              della console, con la funzione
+                              \func{vhangup}.\\
+    \const{CAP\_SYS\_PTRACE}& consente di tracciare qualunque processo con
+                              \func{ptrace} (vedi 
+                              sez.~\ref{sec:xxx_ptrace}).\\
+% TODO documentatare ptrace 
+    \hline
+  \end{tabular}
+  \caption{Le costanti che identificano le \textit{capabilities} presenti nel
+    kernel.}
+\label{tab:proc_capabilities}
+\end{table}
+
+\footnotetext[21]{questa capacità è presente 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}; questo è attualmente definito come intero a 32 bit,
+  il che comporta un massimo di 32 \textit{capabilities} distinte.} in cui
+ciascun bit corrisponde ad una capacità diversa; se ne è riportato
+l'elenco,\footnote{si tenga presente che l'elenco delle \textit{capabilities}
+  presentato questa tabella, ripreso dalla relativa pagina di manuale
+  (accessibile con \texttt{man capabilities}), è 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
+sono mantenuti i diversi insiemi di identificatori di
+sez.~\ref{sec:proc_setuid}; il loro significato è il seguente:
+\begin{basedescript}{\desclabelwidth{2.0cm}\desclabelstyle{\nextlinelabel}}
+\item[\textit{effective}] l'insieme delle \textit{capabilities}
+  ``\textsl{effettive}'', cioè di quelle che vengono effettivamente usate dal
+  kernel quando deve eseguire il controllo di accesso per le varie operazioni
+  compiute dal processo.
+\item[\textit{permitted}] l'insieme delle \textit{capabilities}
+  ``\textsl{permesse}'', cioè l'insieme di quelle capacità che un processo
+  \textsl{può} impostare come \textsl{effettive}. Se un processo cancella una
+  capacità da questo insieme non potrà più riassumerla (almeno che non esegua
+  un programma che è \acr{suid} di root).
+\item[\textit{inherited}] l'insieme delle \textit{capabilities}
+  ``\textsl{ereditabili}'', cioè quelle che vengono trasmesse ad un nuovo
+  programma eseguito attraverso una chiamata ad \func{exec} (con l'eccezione
+  del caso che questo sia \acr{suid} di root).
+\label{sec:capabilities_set}
+\end{basedescript}
+
+Oltre a questi tre insiemi, che sono relativi al singolo processo, il kernel
+mantiene un insieme generale valido per tutto il sistema, chiamato
+\itindex{capabilities~bounding~set} \textit{capabilities bounding set}. Ogni
+volta che un programma viene posto in esecuzione con \func{exec} il contenuto
+degli insiemi \textit{effective} e \textit{permitted} vengono mascherati con
+un \textsl{AND} binario del contenuto corrente del \textit{capabilities
+  bounding set}, così che il nuovo processo potrà disporre soltanto delle
+capacità in esso elencate.
+
+Il \textit{capabilities bounding set} è un parametro di sistema, accessibile
+attraverso il contenuto del file \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 potrà soltanto rimuovere uno dei bit
+già presenti dell'insieme: questo significa che una volta rimossa una
+\textit{capability} dal \textit{capabilities bounding set} essa non sarà più
+disponibile, neanche per l'amministratore, a meno di un riavvio.
+
+Quando un programma viene messo in esecuzione\footnote{cioè quando viene
+  eseguita la \func{execve} con cui lo si lancia; in corrispondenza di una
+  \func{fork} le \textit{capabilities} non vengono modificate.} esso eredita
+(nel senso che assume negli insiemi \textit{effective} e \textit{permitted})
+le \textit{capabilities} mantenute nell'insieme \textit{inherited}, a meno che
+non sia eseguito un programma \acr{suid} di root o la \func{exec} sia stata
+eseguita da un programma con \textsl{uid} reale zero; in tal caso il programma
+ottiene tutte le \textit{capabilities} presenti nel \textit{capabilities
+  bounding set}. In questo modo si può far si che ad un processo eseguito in
+un secondo tempo possano essere trasmesse solo un insieme limitato di
+capacità, impedendogli di recuperare quelle assenti nell'insieme
+\textit{inherited}. Si tenga presente invece che attraverso una \func{fork}
+vengono mantenute le stesse capacità del processo padre.
+
+Per la gestione delle \textit{capabilities} il kernel mette a disposizione due
+funzioni che permettono rispettivamente di leggere ed impostare i valori dei
+tre insiemi illustrati in precedenza. Queste due funzioni sono \funcd{capget}
+e \funcd{capset} e costituiscono l'interfaccia di gestione basso livello; i
+loro rispettivi prototipi sono:
+\begin{functions}
+  \headdecl{sys/capability.h}
+
+  \funcdecl{int capget(cap\_user\_header\_t hdrp, cap\_user\_data\_t datap)}
+  Legge le \textit{capabilities}.
+
+  \funcdecl{int capset(cap\_user\_header\_t hdrp, const cap\_user\_data\_t
+    datap)} 
+  Imposta le \textit{capabilities}.
+
+  
+  \bodydesc{Entrambe le funzioni ritornano 0 in caso di successo e -1 in caso
+    di errore, nel qual caso \var{errno} può assumere i valori:
+    \begin{errlist}
+    \item[\errcode{ESRCH}] si è fatto riferimento ad un processo inesistente.
+    \item[\errcode{EPERM}] si è tentato di aggiungere una capacità
+      nell'insieme delle \textit{capabilities} permesse, o di impostare una
+      capacità non presente nell'insieme di quelle permesse negli insieme
+      delle effettive o ereditate, o si è cercato di impostare una
+      \textit{capability} di un altro processo senza avare
+      \const{CAP\_SETPCAP}. 
+  \end{errlist}
+  ed inoltre \errval{EFAULT} ed \errval{EINVAL}.
+}
+
+\end{functions}
+
+Queste due funzioni prendono come argomenti due tipi di dati dedicati,
+definiti come puntatori a due strutture specifiche di Linux, illustrate in
+fig.~\ref{fig:cap_kernel_struct}. Per poterle utilizzare occorre anche
+cancellare la macro \macro{\_POSIX\_SOURCE}.\footnote{per farlo occorre
+  utilizzare la direttiva di preprocessore \direct{undef}; si dovrà cioè
+  inserire una istruzione \texttt{\#undef \_POSIX\_SOURCE} prima di includere
+  \texttt{sys/capability.h}.} Si tenga presente che le strutture di
+fig.~\ref{fig:cap_kernel_struct}, come i prototipi delle due funzioni
+\func{capget} e \func{capset}, sono soggette ad essere modificate con il
+cambiamento del kernel (in particolare i tipi di dati delle strutture) ed
+anche se finora l'interfaccia è risultata stabile, non c'è nessuna
+assicurazione che questa venga mantenuta. Pertando se si vogliono scrivere
+programmi portabili che possano essere eseguiti su qualunque versione del
+kernel è opportuno utilizzare le interfacce di alto livello.
+
+\begin{figure}[!htb]
+  \footnotesize
+  \centering
+  \begin{minipage}[c]{15cm}
+    \includestruct{listati/cap_user_header_t.h}
+  \end{minipage} 
+  \normalsize 
+  \caption{Definizione delle strutture a cui fanno riferimento i puntatori
+    \structd{cap\_user\_header\_t} e \structd{cap\_user\_data\_t} usati per
+    l'interfaccia di gestione di basso livello delle \textit{capabilities}.}
+  \label{fig:cap_kernel_struct}
+\end{figure}
+
+La struttura a cui deve puntare l'argomento \param{hdrp} serve ad indicare,
+tramite il campo \var{pid}, il processo del quale si vogliono leggere o
+modificare le \textit{capabilities}. Il campo \var{version} deve essere
+impostato al valore della versione delle usata dal kernel (quello indicato
+dalla costante \const{\_LINUX\_CAPABILITY\_VERSION} di
+fig.~\ref{fig:cap_kernel_struct}) altrimenti le funzioni ritorneranno con un
+errore di \errcode{EINVAL}, restituendo nel campo stesso il valore corretto
+della versione in uso.  La struttura a cui deve puntare l'argomento
+\param{datap} invece conterrà i valori letti o da impostare per i tre insiemi
+delle capacità del processo.
+
+Dato che le precedenti funzioni, oltre ad essere specifiche di Linux, non
+garantiscono la stabilità nell'interfaccia, è sempre opportuno effettuare la
+gestione delle \textit{capabilities} utilizzando le funzioni di libreria a
+questo dedicate. Queste funzioni, che seguono quanto previsto nelle bozze
+dello standard POSIX.1e, non fanno parte delle \acr{glibc} e sono fornite in
+una libreria a parte,\footnote{la libreria è \texttt{libcap2}, nel caso di
+  Debian può essere installata con il pacchetto omonimo.} pertanto se un
+programma le utilizza si dovrà indicare esplicitamente l'uso della suddetta
+libreria attraverso l'opzione \texttt{-lcap} del compilatore.
+
+Le funzioni dell'interfaccia delle bozze di POSIX.1e prevedono l'uso di uno
+tipo di dato opaco, \type{cap\_t}, come puntatore ai dati mantenuti nel
+cosiddetto \textit{capability state},\footnote{si tratta in sostanza di un
+  puntatore ad una struttura interna utilizzata dalle librerie, i cui campi
+  non devono mai essere acceduti direttamente.} in sono memorizzati tutti i
+dati delle \textit{capabilities}. In questo modo è possibile mascherare i
+dettagli della gestione di basso livello, che potranno essere modificati senza
+dover cambiare le funzioni dell'interfaccia, che faranno riferimento soltanto
+ad oggetti di questo tipo.  L'interfaccia pertanto non soltanto fornisce le
+funzioni per modificare e leggere le \textit{capabilities}, ma anche quelle
+per gestire i dati attraverso \type{cap\_t}.
+
+La prima funzione dell'interfaccia è quella che permette di inizializzare un
+\textit{capability state}, allocando al contempo la memoria necessaria per i
+relativi dati. La funzione è \funcd{cap\_init} ed il suo prototipo è:
+\begin{functions}
+  \headdecl{sys/capability.h}
+
+  \funcdecl{cap\_t cap\_init(void)} 
+  Crea ed inizializza un \textit{capability state}.
+  
+  \bodydesc{La funzione ritorna un valore non nullo in caso di successo e
+    \macro{NULL} in caso di errore, nel qual caso \var{errno} assumerà il
+    valore \errval{ENOMEM}.
+  }
+\end{functions}
+
+La funzione restituisce il puntatore \type{cap\_t} ad uno stato inizializzato
+con tutte le \textit{capabilities} azzerate. In caso di errore (cioè quando
+non c'è memoria suffuciente ad allocare i dati) viene restituito \macro{NULL}
+ed \var{errno} viene impostata a \errval{ENOMEM}.  La memoria necessaria a
+mantenere i dati viene automaticamente allocata da \func{cap\_init}, ma dovrà
+essere disallocata esplicitamente quando non più necessaria utilizzando la
+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 di tipo
+\texttt{char *}. L'argomento \param{obj\_d} deve corrispondere ad un oggetto
+ottenuto tramite altre funzioni della libreria, altrimenti la funzione fallirà
+con un errore di \errval{EINVAL}.
+
+Infine si può creare una copia di un \textit{capability state} ottenuto in
+precedenza tramite la funzione \funcd{cap\_dup}, il cui prototipo è:
+\begin{functions}
+  \headdecl{sys/capability.h}
+
+  \funcdecl{cap\_t cap\_dup(cap\_t cap\_p)} 
+  Duplica un \textit{capability state} restituendone una copia.
+  
+  \bodydesc{La funzione ritorna un valore non nullo in caso di successo e
+    \macro{NULL} in caso di errore, nel qual caso \var{errno} potrà assumere i
+    valori \errval{ENOMEM} o \errval{EINVAL}.  
+  }
+\end{functions}
+
+La funzione crea una copia del \textit{capability state} posto all'indirizzo
+\param{cap\_p} che si è passato come argomento, restituendo il puntatore alla
+copia, che conterrà gli stessi valori delle \textit{capabilities} presenti
+nell'originale. La memoria necessaria viene allocata automaticamente dalla
+funzione. Una volta effettuata la copia i due \textit{capability state}
+potranno essere modificati in maniera completamente indipendente.
+
+Una seconda classe di funzioni di servizio sono quelle per la gestione dei
+dati contenuti all'interno di un \textit{capability state}; la prima di esse è
+\funcd{cap\_clear}, il cui prototipo è:
+\begin{functions}
+  \headdecl{sys/capability.h}
+
+  \funcdecl{int cap\_clear(cap\_t cap\_p)} 
+  Inizializza un \textit{capability state} cancellando tutte le
+  \textit{capabilities}.
+  
+  \bodydesc{La funzione ritorna 0 in caso di successo e $-1$ in caso di
+    errore, nel qual caso \var{errno} assumerà il valore \errval{EINVAL}.
+  }
+\end{functions}
+
+La funzione si limita ad azzerare tutte le \textit{capabilities} presenti nel
+\textit{capability state} all'indirizzo \param{cap\_p} passato come argomento,
+restituendo uno stato \textsl{vuoto}, analogo a quello che si ottiene nella
+creazione con \func{cap\_init}.
+
+Per la gestione dei valori delle \textit{capabilities} presenti in un
+\textit{capability state} l'interfaccia prevede due funzioni,
+\funcd{cap\_get\_flag} e \funcd{cap\_set\_flag}, che permettono
+rispettivamente di leggere o impostare il valore di un flag delle
+\textit{capabilities}; i rispettivi prototipi sono:
+\begin{functions}
+  \headdecl{sys/capability.h}
+
+  \funcdecl{int cap\_get\_flag(cap\_t cap\_p, cap\_value\_t cap, cap\_flag\_t
+    flag, cap\_flag\_value\_t *value\_p)}
+  Legge il valore di una \textit{capability}.
+
+  \funcdecl{int cap\_set\_flag(cap\_t cap\_p, cap\_flag\_t flag, int ncap,
+    cap\_value\_t *caps, cap\_flag\_value\_t value)} 
+  Imposta il valore di una \textit{capability}.
+  
+  \bodydesc{Le funzioni ritornano 0 in caso di successo e $-1$ in caso di
+    errore, nel qual caso \var{errno} assumerà il valore \errval{EINVAL}.
+}
+\end{functions}
+
+In entrambe le funzioni l'argomento \param{cap\_p} indica il puntatore al
+\textit{capability state} su cui operare, mentre l'argomento \param{flag}
+indica su quale dei tre insiemi illustrati a
+pag.~\pageref{sec:capabilities_set} si intende operare. Questi devono essere
+specificati con una variabile di tipo \type{cap\_flag\_t} che può assumere
+esclusivamente\footnote{si tratta in effetti di un tipo enumerato, come si può
+  verificare dalla sua definizione che si trova in
+  \texttt{/usr/include/sys/capability.h}.} uno dei valori illustrati in
+tab.~\ref{tab:cap_set_identifier}.
+
+\begin{table}[htb]
+  \centering
+  \footnotesize
+  \begin{tabular}[c]{|l|l|}
+    \hline
+    \textbf{Valore} & \textbf{Significato} \\
+    \hline
+    \hline
+    \const{CAP\_EFFECTIVE}  & Capacità dell'insieme \textsl{effettivo}.\\
+    \const{CAP\_PERMITTED}  & Capacità dell'insieme \textsl{permesso}.\\ 
+    \const{CAP\_INHERITABLE}& Capacità dell'insieme \textsl{ereditabile}.\\
+    \hline
+  \end{tabular}
+  \caption{Valori possibili per il tipo di dato \type{cap\_flag\_t} che
+    identifica gli insiemi delle \textit{capabilities}.}
+  \label{tab:cap_set_identifier}
+\end{table}
+
+La capacità che si intende controllare o impostare invece deve essere
+specificata attraverso una variabile di tipo \type{cap\_value\_t}, che può
+prendere come valore uno qualunque di quelli riportati in
+tab.~\ref{tab:proc_capabilities}, in questo caso però non è possibile
+combinare diversi valori in una maschera binaria, una variabile di tipo
+\type{cap\_value\_t} deve indicare una sola capacità.\footnote{nel file di
+  header citato nella nota precedente il tipo \type{cap\_value\_t} è definito
+  come \ctyp{int}, ma i valori validi sono soltanto quelli di
+  tab.~\ref{tab:proc_capabilities}.}  Infine lo stato di una capacità è
+descritto ad una variabile di tipo \type{cap\_flag\_value\_t}, che a sua volta
+può assumere soltanto uno\footnote{anche questo è un tipo enumerato.} dei
+valori di tab.~\ref{tab:cap_value_type}.
+
+\begin{table}[htb]
+  \centering
+  \footnotesize
+  \begin{tabular}[c]{|l|l|}
+    \hline
+    \textbf{Valore} & \textbf{Significato} \\
+    \hline
+    \hline
+    \const{CAP\_CLEAR}& La capacità non è impostata.\\ 
+    \const{CAP\_SET}  & La capacità è impostata.\\
+    \hline
+  \end{tabular}
+  \caption{Valori possibili per il tipo di dato \type{cap\_flag\_value\_t} che
+    indica lo stato di una capacità.}
+  \label{tab:cap_value_type}
+\end{table}
+
+La funzione \func{cap\_get\_flag} legge lo stato della capacità indicata
+dall'argomento \param{cap} all'interno dell'insieme indicato dall'argomento
+\param{flag} e ne restituisce il valore nella variabile posta all'indirizzo
+puntato dall'argomento \param{value\_p}; è possibile cioè leggere soltanto uno
+stato di una capacità alla volta.
+
+La funzione \func{cap\_set\_flag} può invece impostare in una sola chiamata
+più capacità, anche se solo all'interno dello stesso insieme; per questo essa
+prende un vettore di valori di tipo \type{cap\_value\_t} nell'argomento
+\param{caps}, la cui dimensione è specificata dall'argomento \param{ncap}. Il
+tipo di impostazione da eseguire (cancellazione o impostazione) viene indicato
+dall'argomento \param{value}.
+
+Fin quei abbiamo trattato delle funzioni di manipolazione dei
+\textit{capabilities state}; quando si vuole eseguire la lettura delle
+\textit{capabilities} del processo corrente si deve usare la funzione
+\funcd{cap\_get\_proc}, il cui 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} del processo corrente
+e restituisce il puntatore ad un \textit{capabilities state} contenente il
+risultato, che provvede ad allocare autonomamente, e che occorrerà liberare
+con \func{cap\_free} quando non sarà più utilizzato.
+
+Se invece si vogliono leggere le \textit{capabilities} di un processo
+specifico occorre usare la funzione \funcd{capgetp}, il cui
+prototipo\footnote{su alcune pagine di manuale la funzione è descritta con un
+  prototipo sbagliato, che prevede un valore di ritorno di tipo \type{cap\_t},
+  ma il valore di ritorno è intero, come si può verificare anche dalla
+  dichiarazione della stessa in \texttt{sys/capability.h}.} è:
+\begin{functions}
+  \headdecl{sys/capability.h}
+
+  \funcdecl{int capgetp(pid\_t pid, cap\_t cap\_d)}
+  Legge le \textit{capabilities} del processo indicato da \param{pid}.
+  
+  \bodydesc{La funzione ritorna 0 in caso di successo e $-1$ in caso di
+    errore, nel qual caso \var{errno} può assumere i valori \errval{EINVAL},
+    \errval{EPERM} o \errval{ENOMEM}.  
+  }
+\end{functions}
+
+La funzione legge il valore delle \textit{capabilities} del processo indicato
+con l'argomento \param{pid}, salvando il risultato nel \textit{capabilities
+  state} all'indirizzo \param{cap\_d} che deve essere stato creato in
+precedenza. Qualora il processo non esista si avrà un errore di \errval{}.
+
+
+
+
+\itindend{capabilities}
 
 
 
@@ -1866,10 +2461,10 @@ scrivere codice portabile.
 \label{sec:proc_priority}
 
 In questa sezione tratteremo più approfonditamente i meccanismi con il quale
-lo \textit{scheduler}\itindex{scheduler} assegna la CPU ai vari
-processi attivi.  In particolare prenderemo in esame i vari meccanismi con cui
-viene gestita l'assegnazione del tempo di CPU, ed illustreremo le varie
-funzioni di gestione.
+lo \textit{scheduler}\itindex{scheduler} assegna la CPU ai vari processi
+attivi.  In particolare prenderemo in esame i vari meccanismi con cui viene
+gestita l'assegnazione del tempo di CPU, ed illustreremo le varie funzioni di
+gestione.
 
 
 \subsection{I meccanismi di \textit{scheduling}}
@@ -2102,9 +2697,10 @@ l'utente correnti.
     \param{which} & \param{who} & \textbf{Significato} \\
     \hline
     \hline
-    \const{PRIO\_PROCESS} & \type{pid\_t} &  processo  \\
-    \const{PRIO\_PRGR}    & \type{pid\_t} &  process group  \\
-    \const{PRIO\_USER}    & \type{uid\_t} &  utente \\
+    \const{PRIO\_PROCESS} & \type{pid\_t} & processo  \\
+    \const{PRIO\_PRGR}    & \type{pid\_t} & \itindex{process~group}
+                                            \textit{process group}  \\ 
+    \const{PRIO\_USER}    & \type{uid\_t} & utente \\
     \hline
   \end{tabular}
   \caption{Legenda del valore dell'argomento \param{which} e del tipo
@@ -2184,7 +2780,7 @@ eseguito per primo quello con priorit
 processi con la stessa priorità assoluta questi vengono tenuti in una coda e
 tocca al kernel decidere quale deve essere eseguito.  Il meccanismo con cui
 vengono gestiti questi processi dipende dalla politica di scheduling che si è
-scelto; lo standard ne prevede due:
+scelta; lo standard ne prevede due:
 \begin{basedescript}{\desclabelwidth{1.2cm}\desclabelstyle{\nextlinelabel}}
 \item[\textit{FIFO}] \textit{First In First Out}. Il processo viene eseguito
   fintanto che non cede volontariamente la CPU (con \func{sched\_yield}), si
@@ -2675,7 +3271,7 @@ file, o nell'accesso a meccanismi di intercomunicazione come la memoria
 condivisa. In questi casi, se non si dispone della possibilità di eseguire
 atomicamente le operazioni necessarie, occorre che quelle parti di codice in
 cui si compiono le operazioni sulle risorse condivise (le cosiddette
-\textsl{sezioni critiche}\index{sezioni~critiche}) del programma, siano
+\textsl{sezioni critiche}\index{sezione~critica}) del programma, siano
 opportunamente protette da meccanismi di sincronizzazione (torneremo su queste
 problematiche di questo tipo in cap.~\ref{cha:IPC}).
 
@@ -2716,10 +3312,11 @@ multi-thread, ma si hanno gli stessi problemi quando si vogliono chiamare
 delle funzioni all'interno dei gestori dei segnali.
 
 Fintanto che una funzione opera soltanto con le variabili locali è rientrante;
-queste infatti vengono allocate nello stack, e un'altra invocazione non fa
-altro che allocarne un'altra copia. Una funzione può non essere rientrante
-quando opera su memoria che non è nello stack.  Ad esempio una funzione non è
-mai rientrante se usa una variabile globale o statica.
+queste infatti vengono allocate nello \itindex{stack} stack, e un'altra
+invocazione non fa altro che allocarne un'altra copia. Una funzione può non
+essere rientrante quando opera su memoria che non è nello \itindex{stack}
+stack.  Ad esempio una funzione non è mai rientrante se usa una variabile
+globale o statica.
 
 Nel caso invece la funzione operi su un oggetto allocato dinamicamente, la
 cosa viene a dipendere da come avvengono le operazioni: se l'oggetto è creato