From 743ef11e68d40acfca27b95a3438b4cec6c59a8a Mon Sep 17 00:00:00 2001 From: Simone Piccardi Date: Sun, 19 Aug 2018 18:22:19 +0200 Subject: [PATCH] Revisione mount (e riorganizzazione della trattazione dei mount flag) --- filedir.tex | 1756 ++++++---------------------------------- gapil.tex | 2 +- img/dir_links.dia | Bin 3069 -> 3189 bytes img/dir_struct.dia | Bin 3836 -> 3954 bytes img/disk_struct.dia | Bin 2389 -> 2480 bytes img/filesys_struct.dia | Bin 5448 -> 5579 bytes procadv.tex | 1301 +++++++++++++++++++++++++++++ process.tex | 2 +- prochand.tex | 2 +- sources/mymount.c | 3 + 10 files changed, 1564 insertions(+), 1502 deletions(-) diff --git a/filedir.tex b/filedir.tex index 51f6868..3a371a4 100644 --- a/filedir.tex +++ b/filedir.tex @@ -22,9 +22,9 @@ Esamineremo poi le funzioni di libreria che si usano per copiare, spostare e cambiare i nomi di file e directory e l'interfaccia che permette la manipolazione dei loro attributi. Tratteremo inoltre la struttura di base del sistema delle protezioni e del controllo dell'accesso ai file e le successive -estensioni (\textit{Extended Attributes}, ACL, quote disco, -\textit{capabilities}). Tutto quello che riguarda invece la gestione dell'I/O -sui file è lasciato al capitolo successivo. +estensioni (\textit{Extended Attributes}, ACL, quote disco). Tutto quello che +riguarda invece la gestione dell'I/O sui file è lasciato al capitolo +successivo. @@ -35,8 +35,8 @@ In questa sezione tratteremo con maggiori dettagli rispetto a quanto visto in sez.~\ref{sec:file_arch_overview} il \textit{Virtual File System} di Linux e come il kernel può gestire diversi tipi di filesystem, descrivendo prima le caratteristiche generali di un filesystem di un sistema unix-like, per poi -fare una panoramica sul filesystem più usato con Linux, l'\acr{ext2} ed i suoi -successori. +fare una panoramica sul filesystem tradizionalmente più usato con Linux, +l'\acr{ext2} ed i suoi successori. \subsection{Il funzionamento del \textit{Virtual File System} di Linux} @@ -428,7 +428,7 @@ directory che tratteremo nel prosieguo del capitolo. In particolare è opportuno tenere sempre presente che: -\begin{enumerate} +\begin{enumerate*} \item L'\textit{inode} contiene i cosiddetti \textsl{metadati}, vale dire le informazioni riguardanti le proprietà del file come oggetto del filesystem: @@ -481,11 +481,11 @@ opportuno tenere sempre presente che: per gli \textit{inode}. Nel primo caso non sarà possibile allocare ulteriore spazio, ma si potranno creare file (vuoti), nel secondo non si potranno creare nuovi file, ma si potranno estendere quelli che ci - sono.\footnote{questo comportamento non è generale, alcuni filesystem - evoluti possono evitare il problema dell'esaurimento degli \textit{inode} - riallocando lo spazio disco libero per i blocchi.} + sono.\footnote{questo comportamento non è generale, alcuni filesystem più + sofisticati possono evitare il problema dell'esaurimento degli + \textit{inode} riallocando lo spazio disco libero per i blocchi.} -\end{enumerate} +\end{enumerate*} \begin{figure}[!htb] \centering @@ -523,11 +523,11 @@ di più è la famiglia di filesystem evolutasi a partire dal \textit{second grande sviluppo e diverse evoluzioni, fra cui l'aggiunta del \textit{journaling} con il passaggio ad \acr{ext3}, che probabilmente è ancora il filesystem più diffuso, ed una serie di ulteriori miglioramenti con il -successivo \acr{ext4}, che sta iniziando a sostituirlo gradualmente. In futuro -è previsto che questo debba essere sostituito da un filesystem completamente -diverso, \acr{btrfs}, che dovrebbe diventare il filesystem standard di Linux, -ma questo al momento è ancora in fase di sviluppo.\footnote{si fa riferimento - al momento dell'ultima revisione di di questo paragrafo, l'inizio del 2012.} +successivo \acr{ext4}. In futuro è previsto che questo debba essere sostituito +da un filesystem completamente diverso, \acr{btrfs}, che dovrebbe diventare il +filesystem standard di Linux, ma questo al momento è ancora in fase di +sviluppo.\footnote{si fa riferimento al momento dell'ultima revisione di di + questo paragrafo, l'inizio del 2012.} Il filesystem \acr{ext2} nasce come filesystem nativo per Linux a partire dalle prime versioni del kernel e supporta tutte le caratteristiche di un @@ -540,7 +540,7 @@ significative ne mantengono le caratteristiche fondamentali. Oltre alle caratteristiche standard, \acr{ext2} fornisce alcune estensioni che non sono presenti su un classico filesystem di tipo Unix; le principali sono le seguenti: -\begin{itemize} +\begin{itemize*} \item gli attributi estesi (vedi sez.~\ref{sec:file_xattr}) che consentono di estendere le informazioni salvabili come metadati e le ACL (vedi sez.~\ref{sec:file_ACL}) che consentono di estendere il modello tradizionale @@ -567,7 +567,7 @@ le seguenti: cioè essere soltanto letti) per la protezione di file di configurazione sensibili, o come \textit{append-only} (che possono essere aperti in scrittura solo per aggiungere dati) per la protezione dei file di log. -\end{itemize} +\end{itemize*} La struttura di \acr{ext2} è stata ispirata a quella del filesystem di BSD: un filesystem è composto da un insieme di blocchi, la struttura generale è quella @@ -656,7 +656,8 @@ memorizzati. L'operazione di attivazione del filesystem è chiamata \textit{superblock} non valido, o si è cercato di rimontare un filesystem non ancora montato, o di montarlo senza che \param{target} sia un \textit{mount point} o di spostarlo quando \param{target} non è un - \textit{mount point} o è la radice. + \textit{mount point} o è la radice o si è usato un valore di + \param{mountflags} non valido. \item[\errcode{ELOOP}] si è cercato di spostare un \textit{mount point} su una sottodirectory di \param{source} o si sono incontrati troppi collegamenti simbolici nella risoluzione di un nome. @@ -677,12 +678,12 @@ memorizzati. L'operazione di attivazione del filesystem è chiamata \itindbeg{mount~point} -La funzione monta sulla directory indicata da \param{target}, detta -\textit{mount point}, il filesystem contenuto nel file di dispositivo indicato -da \param{source}. In entrambi i casi, come daremo per assunto da qui in -avanti tutte le volte che si parla di directory o file nel passaggio di un -argomento di una funzione, si intende che questi devono essere indicati con la -stringa contenente il loro \textit{pathname}. +L'uso più comune della funzione è quello di montare sulla directory indicata +da \param{target}, detta \textit{mount point}, il filesystem contenuto nel +file di dispositivo indicato da \param{source}. In entrambi i casi, come +daremo per assunto da qui in avanti tutte le volte che si parla di directory o +file nel passaggio di un argomento di una funzione, si intende che questi +devono essere indicati con la stringa contenente il loro \textit{pathname}. Normalmente un filesystem è contenuto su un disco o una partizione, ma come illustrato in sez.~\ref{sec:file_vfs_work} la struttura del \textit{Virtual @@ -691,10 +692,9 @@ diversi da un disco. Ad esempio usando il \textit{loop device} si può montare un file qualunque (come l'immagine di un CD-ROM o di un floppy) che contiene l'immagine di un filesystem, inoltre alcuni tipi di filesystem, come \texttt{proc} o \texttt{sysfs} sono virtuali e non hanno un supporto che ne -contenga i dati, che invece sono generati al volo ad ogni lettura, e passati -indietro al kernel ad ogni scrittura.\footnote{costituiscono quindi un - meccanismo di comunicazione, attraverso l'ordinaria interfaccia dei file, - con il kernel.} +contenga i dati che sono generati al volo dal kernel ad ogni lettura, e +inviati al kernel ad ogni scrittura (costituiscono quindi un meccanismo di +comunicazione, attraverso l'ordinaria interfaccia dei file, con il kernel). Il tipo di filesystem che si vuole montare è specificato dall'argomento \param{filesystemtype}, che deve essere una delle stringhe @@ -716,100 +716,238 @@ Dopo l'esecuzione della funzione il contenuto del filesystem viene resto disponibile nella directory specificata come \textit{mount point}, il precedente contenuto di detta directory viene mascherato dal contenuto della directory radice del filesystem montato. Fino ai kernel della serie 2.2.x non -era possibile montare un filesystem se un \textit{mount point} era già in uso. - -A partire dal kernel 2.4.x inoltre è divenuto possibile sia spostare -atomicamente un \textit{mount point} da una directory ad un'altra, sia montare -lo stesso filesystem in diversi \textit{mount point}, sia montare più -filesystem sullo stesso \textit{mount point} impilandoli l'uno sull'altro, nel -qual caso vale comunque quanto detto in precedenza, e cioè che solo il -contenuto dell'ultimo filesystem montato sarà visibile. +era possibile montare un filesystem se un \textit{mount point} era già in uso, +coi kernel successivi è possibile montare più filesystem sullo stesso +\textit{mount point} impilandoli l'uno sull'altro, anche in questo caso vale +quanto appena detto, e solo il contenuto dell'ultimo filesystem montato sarà +visibile, mascherando quelli sottostanti. + +In realtà quella di montare un filesystem è solo una delle operazioni che si +possono effettuare con \func{mount}, la funzione infatti è dedicata a tutte le +operazioni relative alla gestione del montaggio dei filesystem e dei +\textit{mount-point}. Ad esempio fin dalle sue origini poteva essere +utilizzata per effettuare il rimontaggio di un filesystem con opzioni diverse, +ed a partire dal kernel 2.4.x è divenuto possibile usarla per spostare +atomicamente un \textit{mount point} da una directory ad un'altra, per montare +lo stesso filesystem in diversi \textit{mount point}, per montare una +directory su un'altra (il cosiddetto \textit{bind-mount}). \itindend{mount~point} -Oltre alle opzioni specifiche di ciascun filesystem, che si passano nella -forma della lista di parole chiave indicata con l'argomento \param{data}, -esistono pure alcune opzioni che si possono applicare in generale, anche se -non è detto che tutti i filesystem le supportino, che si specificano tramite -l'argomento \param{mountflags}. L'argomento inoltre può essere utilizzato per -modificare il comportamento della funzione \func{mount}, facendole compiere -una operazione diversa (ad esempio un rimontaggio, invece che un montaggio). - -In Linux \param{mountflags} deve essere un intero a 32 bit; fino ai kernel -della serie 2.2.x i 16 più significativi avevano un valore riservato che -doveva essere specificato obbligatoriamente,\footnote{il valore era il - \textit{magic number} \code{0xC0ED}, si può usare la costante +Il tipo di operazione compiuto da \func{mount} viene stabilito in base al +valore dell'argomento \param{mountflags}, che oltre alla selezione del tipo di +operazione da compiere, consente anche di indicare alcune opzioni generiche +valide per qualunque filesystem.\footnote{benché queste siano espresse nel + comando \cmd{mount} con l'opzione \texttt{-o} esse non vengono impostate nei + valori di \param{data}, che serve solo per le opzioni specifiche di ogni + filesystem.} Il valore dell'argomento deve essere espresso come maschera +binaria e i vari bit che lo compongono, detti anche \textit{mount flags}, +devono essere impostati con un OR aritmetico dei valori dalle opportune +costanti che illustreremo a breve. + +In Linux \param{mountflags} deve essere un intero a 32 bit; +fino ai kernel della serie 2.2.x i 16 più significativi avevano un valore +riservato che doveva essere specificato obbligatoriamente,\footnote{il valore + era il \textit{magic number} \code{0xC0ED}, si può usare la costante \constd{MS\_MGC\_MSK} per ottenere la parte di \param{mountflags} riservata al \textit{magic number}, mentre per specificarlo si può dare un OR - aritmetico con la costante \constd{MS\_MGC\_VAL}.} e si potevano usare solo i -16 meno significativi. Oggi invece, con un numero di opzioni superiore, sono + aritmetico con la costante \constd{MS\_MGC\_VAL}.} e si potevano usare solo +i 16 meno significativi. Oggi invece, con un numero di opzioni superiore, sono utilizzati tutti e 32 i bit, ma qualora nei 16 più significativi sia presente -detto valore, che non esprime una combinazione valida, esso viene ignorato. Il -valore dell'argomento deve essere espresso come maschera binaria e i vari bit -che lo compongono, detti anche \textit{mount flags}, devono essere impostati -con un OR aritmetico dei valori dalle costanti riportate nell'elenco seguente: +detto valore, che non esprime una combinazione valida, esso viene ignorato. + +Come accennato il tipo di operazione eseguito da \func{mount} viene stabilito +in base al contenuto di \param{mountflags}, la scelta viene effettuata +controllando nell'ordine: +\begin{enumerate*} +\item se è presente il flag \const{MS\_REMOUNT} nel qual caso verrà eseguito + il rimontaggio del filesystem, con le nuove opzioni indicate da \param{data} + e dagli altri flag di \param{mountflags}; +\item se è presente il flag \const{MS\_BIND} nel qual caso verrà eseguito un + \textit{bind-mount} (argometo che tratteremo più avanti); +\item se è presente uno fra \const{MS\_SHARED}, \const{MS\_PRIVATE}, + \const{MS\_SLAVE}, \const{MS\_UNBINDABLE} nel qual caso viene cambiata la + modalità di propagazione del montaggio (detti valori sono mutualmente + esclusivi). +\item se è presente \const{MS\_MOVE}, nel qual caso viene effettuato uno + spostamento del \textit{mount-point}; +\item se nessuno dei precedenti è presente si tratta di una ordinaria + operazione di montaggio di un filesystem. +\end{enumerate*} + +Il fatto che questi valori vengano controllati in quest'ordine significa che +l'effetto di alcuni di questi flag possono cambiare se usati in combinazione +con gli altri che vengono prima nella sequenza (è quanto avviene ad esempio +per \const{MS\_BIND} usato con \const{MS\_REMOUNT}). Tratteremo questi +\textit{mount flags} speciali per primi, tornando sugli altri più avanti. + +Usando il flag \constd{MS\_REMOUNT} si richiede a \func{mount} di rimontare un +filesystem già montato cambiandone le opzioni di montaggio in maniera atomica +(non è cioè necessario smontare e rimontare il filsystem per effettuare il +cambiamento). In questo modo si possono modificare le opzioni del filesystem +anche se questo è in uso. Gli argomenti \param{source} e \param{target} devono +essere gli stessi usati per il montaggio originale, mentre sia \param{data} +che \param{mountflags} conterranno le nuove opzioni, \param{filesystemtype} +viene ignorato. Perché l'operazione abbia successo occorre comunque che il +cambiamento sia possibile (ad esempio non sarà possibile rimontare in sola +lettura un filesystem su cui sono aperti file per la lettura/scrittura). + +Qualunque opzione specifica del filesystem indicata con \param{data} può +essere modificata (ma si dovranno rielencare tutte quelle volute), mentre con +\param{mountflags} possono essere modificate solo alcune opzioni generiche: +\const{MS\_LAZYTIME}, \const{MS\_MANDLOCK}, \const{MS\_NOATIME}, +\const{MS\_NODEV}, \const{MS\_NODIRATIME}, \const{MS\_NOEXEC}, +\const{MS\_NOSUID}, \const{MS\_RELATIME}, \const{MS\_RDONLY}, +\const{MS\_STRICTATIME} e \const{MS\_SYNCHRONOUS}. Inoltre dal kernel 3.17 il +comportamento relativo alle opzioni che operano sul tempo di ultimo accesso +(vedi sez.~\ref{sec:file_file_times}) è cambiato e se non si è indicato +nessuno dei vari \texttt{MS\_*ATIME} vengono mantenute le impostazioni +esistenti anziché forzare l'uso di \const{MS\_RELATIME}. -\begin{basedescript}{\desclabelwidth{1.9cm}\desclabelstyle{\nextlinelabel}} \itindbeg{bind~mount} -\item[\constd{MS\_BIND}] Effettua un cosiddetto \textit{bind mount}, in cui è - possibile montare una directory di un filesystem in un'altra directory, - l'opzione è disponibile a partire dai kernel della serie 2.4. In questo caso - verranno presi in considerazione solo gli argomenti \param{source}, che - stavolta indicherà la directory che si vuole montare e non un file di - dispositivo, e \param{target} che indicherà la directory su cui verrà - effettuato il \textit{bind mount}. Gli argomenti \param{filesystemtype} - e \param{data} vengono ignorati. - - In sostanza quello che avviene è che in corrispondenza del \textit{pathname} - indicato da \param{target} viene montato l'\textit{inode} di \param{source}, - così che la porzione di albero dei file presente sotto \param{source} - diventi visibile allo stesso modo sotto \param{target}. Trattandosi - esattamente dei dati dello stesso filesystem, ogni modifica fatta in uno - qualunque dei due rami di albero sarà visibile nell'altro, visto che - entrambi faranno riferimento agli stessi \textit{inode}. - - Dal punto di vista del VFS l'operazione è analoga al montaggio di un - filesystem proprio nel fatto che anche in questo caso si inserisce in - corrispondenza della \textit{dentry} di \texttt{target} un diverso - \textit{inode}, che stavolta, invece di essere quello della radice del - filesystem indicato da un file di dispositivo, è quello di una directory già - montata. - - Si tenga presente che proprio per questo sotto \param{target} comparirà il - contenuto che è presente sotto \param{source} all'interno del filesystem in - cui quest'ultima è contenuta. Questo potrebbe non corrispondere alla - porzione di albero che sta sotto \param{source} qualora in una - sottodirectory di quest'ultima si fosse effettuato un altro montaggio. In - tal caso infatti nella porzione di albero sotto \param{source} si troverebbe - il contenuto del nuovo filesystem (o di un altro \textit{bind mount}) mentre - sotto \param{target} ci sarebbe il contenuto presente nel filesystem - originale.\footnote{questo evita anche il problema dei \textit{loop} di - fig.~\ref{fig:file_link_loop}, dato che se anche si montasse su - \param{target} una directory in cui essa è contenuta, il cerchio non - potrebbe chiudersi perché ritornati a \param{target} dentro il - \textit{bind mount} vi si troverebbe solo il contenuto originale e non si - potrebbe tornare indietro.} - - Fino al kernel 2.6.26 questo flag doveva essere usato da solo, in quanto il - \textit{bind mount} continuava ad utilizzare le stesse opzioni del montaggio - originale, dal 2.6.26 è stato introdotto il supporto per il cosiddetto - \textit{read-only bind mount} e viene onorata la presenza aggiuntiva del - flag \const{MS\_RDONLY}. In questo modo si ottiene che l'accesso ai file - sotto \param{target} sia effettuabile esclusivamente in sola lettura. - - Il supporto per il \textit{bind mount} consente di superare i limiti - presenti per gli \textit{hard link} (di cui parleremo in - sez.~\ref{sec:link_symlink_rename}) con la possibilità di fare riferimento - alla porzione dell'albero dei file di un filesystem presente a partire da - una certa directory, utilizzando una qualunque altra directory, anche se - questa sta su un filesystem diverso. Si può così fornire una alternativa - all'uso dei collegamenti simbolici (di cui parleremo in - sez.~\ref{sec:link_symlink_rename}) che funziona correttamente anche - all'intero di un \textit{chroot} (argomento su cui torneremo in - sez.~\ref{sec:file_chroot}). + +Usando il flag \constd{MS\_BIND} si richiede a \func{mount} di effettuare un +cosiddetto \textit{bind mount}, l'operazione che consente di montare una +directory di un filesystem in un'altra directory. L'opzione è disponibile a +partire dai kernel della serie 2.4. In questo caso verranno presi in +considerazione solo gli argomenti \param{source}, che stavolta indicherà la +directory che si vuole montare e non un file di dispositivo, e \param{target} +che indicherà la directory su cui verrà effettuato il \textit{bind mount}. Gli +argomenti \param{filesystemtype} e \param{data} vengono ignorati. + +In sostanza quello che avviene è che in corrispondenza del \textit{pathname} +indicato da \param{target} viene montato l'\textit{inode} di \param{source}, +così che la porzione di albero dei file presente sotto \param{source} diventi +visibile allo stesso modo sotto \param{target}. Trattandosi esattamente dei +dati dello stesso filesystem, ogni modifica fatta in uno qualunque dei due +rami di albero sarà visibile nell'altro, visto che entrambi faranno +riferimento agli stessi \textit{inode}. + +Dal punto di vista del VFS l'operazione è analoga al montaggio di un +filesystem proprio nel fatto che anche in questo caso si inserisce in +corrispondenza della \textit{dentry} di \texttt{target} un diverso +\textit{inode}, che stavolta, invece di essere quello della radice del +filesystem indicato da un file di dispositivo, è quello di una directory già +montata. + +Si tenga presente che proprio per questo sotto \param{target} comparirà il +contenuto che è presente sotto \param{source} all'interno del filesystem in +cui quest'ultima è contenuta. Questo potrebbe non corrispondere alla porzione +di albero che sta sotto \param{source} qualora in una sottodirectory di +quest'ultima si fosse effettuato un altro montaggio. In tal caso infatti nella +porzione di albero sotto \param{source} si troverebbe il contenuto del nuovo +filesystem (o di un altro \textit{bind mount}) mentre sotto \param{target} ci +sarebbe il contenuto presente nel filesystem originale.\footnote{questo evita + anche il problema dei \textit{loop} di fig.~\ref{fig:file_link_loop}, dato + che se anche si montasse su \param{target} una directory in cui essa è + contenuta, il cerchio non potrebbe chiudersi perché ritornati a + \param{target} dentro il \textit{bind mount} vi si troverebbe solo il + contenuto originale e non si potrebbe tornare indietro.} + +L'unico altro \textit{mount flag} usabile direttamente con \const{MS\_BIND} è +\const{MS\_REC} che consente di eseguire una operazione di \textit{bind mount} +ricorsiva, in cui nel nuovo \textit{mount point} vengono montati +ricorsivamente anche tutti gli eventuali \textit{bind mount} presenti al di +sotto della directory di origine. + +E' però possibile, a partire dal kernel 2.6.26 usare questo flag insieme a +\const{MS\_REMOUNT}, nel qual caso consente di effettuare una modifica delle +opzioni di montaggio del \textit{bind mount} ed in particolare effettuare il +cosiddetto \textit{read-only bind mount} in cui viene onorata anche la +presenza aggiuntiva del flag \const{MS\_RDONLY}. In questo modo si ottiene che +l'accesso ai file sotto \param{target} sia effettuabile esclusivamente in sola +lettura, senza dover cambiare le opzione del \textit{mount-point} originale. + +Il supporto per il \textit{bind mount} consente di superare i limiti presenti +per gli \textit{hard link} (di cui parleremo in +sez.~\ref{sec:link_symlink_rename}) con la possibilità di fare riferimento +alla porzione dell'albero dei file di un filesystem presente a partire da una +certa directory, utilizzando una qualunque altra directory, anche se questa +sta su un filesystem diverso. Si può così fornire una alternativa all'uso dei +collegamenti simbolici (di cui parleremo in +sez.~\ref{sec:link_symlink_rename}) che funziona correttamente anche +all'intero di un \textit{chroot} (argomento su cui torneremo in +sez.~\ref{sec:file_chroot}). \itindend{bind~mount} +\itindbeg{shared~subtree} + +I quattro flag \const{MS\_PRIVATE}, \const{MS\_SHARED}, \const{MS\_SLAVE} e +\const{MS\_UNBINDABLE} sono stati introdotti a partire dal kernel 2.6.15 per +realizzare l'infrastruttura dei cosiddetti \textit{shared subtree}, che +estendono le funzionalità dei \textit{bind mount} per rendere possibile +propagare automaticamente o meno le eventuali operazioni di montaggio eseguite +al di sotto di un \textit{bind mount} a tutti gli altri \textit{mount-point} + + +consentendo di impostare le +politiche di propagazione di ulteriori eventuali operazione di montaggio +effettuate al di sotto di un \textit{bind-mount}. + +L'uso di uno di questi \textit{mount flag}, che si ricordi sono esclusivi fra +loro, è compatibile solo con In tutti gli altri casi \func{mount} fallirà con +un errore di \errval{EINVAL}. + +\begin{basedescript}{\desclabelwidth{1.9cm}\desclabelstyle{\nextlinelabel}} + +\item[\constd{MS\_PRIVATE}] Marca un \textit{mount point} come privato. In + questo caso \param{target} dovrà fare riferimento al \textit{mount point} + che si intende marcare, e tutti gli altri argomenti verranno ignorati. + + Di default, finché non lo si marca altrimenti con una delle altre opzioni + dell'interfaccia come \textit{shared subtree}, ogni \textit{mount point} è + privato. Ogni \textit{bind mount} ottenuto da un \textit{mount point} di + tipo \textit{private} si comporta come descritto nella trattazione di + \const{MS\_BIND}. Si usa questo flag principalmente per revocare gli effetti + delle altre opzioni e riportare il comportamento a quello ordinario. + +\item[\constd{MS\_SHARED}] Marca un \textit{mount point} come \textit{shared + mount}. In questo caso \param{target} dovrà fare riferimento al + \textit{mount point} che si intende marcare, e tutti gli altri argomenti + verranno ignorati. + + Lo scopo dell'opzione è ottenere che tutti i successivi \textit{bind mount} + effettuati da un \textit{mount point} marcato da essa siano di tipo + \textit{shared}, cioè ``\textsl{condividano}'' con l'originale e fra di loro + ogni ulteriore operazione di montaggio o smontaggio che avviene su una + directory al di sotto di uno qualunque di essi. Le operazioni di montaggio e + smontaggio effettuate al di sotto di un qualunque \textit{mount point} così + marcato verranno ``\textsl{propagate}'' a tutti i \textit{mount point} della + stessa condivisione, e la sezione di albero di file vista al di sotto di + ciascuno di essi sarà sempre identica. + +\item[\constd{MS\_SLAVE}] Marca un \textit{mount point} come \textit{slave + mount}. In questo caso \param{target} dovrà fare riferimento al + \textit{mount point} che si intende marcare, e tutti gli altri argomenti + verranno ignorati. + + Lo scopo dell'opzione è ottenere che tutti i successivi \textit{bind mount} + effettuati da un \textit{mount point} marcato da essa siano di tipo + \textit{slave}, cioè ``\textsl{condividano}'' ogni ulteriore operazione di + montaggio o smontaggio che avviene su una directory al di sotto del + \textit{mount point} originale. Le operazioni di montaggio e smontaggio in + questo caso vengono ``\textsl{propagate}'' soltanto dal \textit{mount point} + originale (detto anche \textit{master}) verso gli \textit{slave}, mentre + essi potranno eseguire al loro interno ulteriori montaggi che non saranno + propagati né negli altri né nel \textit{mount point} originale. + +\item[\constd{MS\_UNBINDABLE}] Marca un \textit{mount point} come + \textit{unbindable mount}. In questo caso \param{target} dovrà fare + riferimento al \textit{mount point} che si intende marcare, e tutti gli + altri argomenti verranno ignorati. + + Un \textit{mount point} marcato in questo modo disabilita la capacità di + eseguire dei \textit{bind mount} del suo contenuto. Si comporta cioè come + allo stesso modo di un \textit{mount point} ordinario di tipo + \textit{private} con in più la restrizione che nessuna sua sottodirectory + (anche se relativa ad un ulteriore montaggio) possa essere utilizzata per un + come sorgente di un \textit{bind mount}. + +\end{basedescript} +\itindend{shared~subtree} + +\begin{basedescript}{\desclabelwidth{1.9cm}\desclabelstyle{\nextlinelabel}} \item[\constd{MS\_DIRSYNC}] Richiede che ogni modifica al contenuto di una directory venga immediatamente registrata su disco in maniera sincrona (introdotta a partire dai kernel della serie 2.6). L'opzione si applica a @@ -907,35 +1045,24 @@ con un OR aritmetico dei valori dalle costanti riportate nell'elenco seguente: di un altro utente, che gli consentirebbe di eseguirlo per conto di quest'ultimo. -\item[\constd{MS\_PRIVATE}] Marca un \textit{mount point} come privato. Si - tratta di una delle nuove opzioni (insieme a \const{MS\_SHARED}, - \const{MS\_SLAVE} e \const{MS\_UNBINDABLE}) facenti parte - dell'infrastruttura degli \textit{shared subtree} introdotta a partire dal - kernel 2.6.15, che estendono le funzionalità dei \textit{bind mount}. In - questo caso \param{target} dovrà fare riferimento al \textit{mount point} - che si intende marcare, e tutti gli altri argomenti verranno ignorati. - - Di default, finché non lo si marca altrimenti con una delle altre opzioni - dell'interfaccia come \textit{shared subtree}, ogni \textit{mount point} è - privato. Ogni \textit{bind mount} ottenuto da un \textit{mount point} di - tipo \textit{private} si comporta come descritto nella trattazione di - \const{MS\_BIND}. Si usa questo flag principalmente per revocare gli effetti - delle altre opzioni e riportare il comportamento a quello ordinario. - \item[\constd{MS\_RDONLY}] Esegue il montaggio del filesystem in sola lettura, non sarà possibile nessuna modifica ai suoi contenuti. Viene usato tutte le volte che si deve accedere ai contenuti di un filesystem con la certezza che questo non venga modificato (ad esempio per ispezionare un filesystem corrotto). All'avvio di default il kernel monta la radice in questa - modalità. + modalità. Si tenga presente che se non viene indicato il filesystem verrà + montato, o rimontanto nel caso lo si usi con \const{MS\_REMOUNT}, in + lettura/scrittura; questo significa in sostanza che non esiste una opzione + separata per indicare il montaggio in lettura/scrittura. \item[\constd{MS\_REC}] Applica ricorsivamente a tutti i \textit{mount point} presenti al di sotto del \textit{mount point} indicato gli effetti della opzione degli \textit{shared subtree} associata. Anche questo caso l'argomento \param{target} deve fare riferimento ad un \textit{mount point} - e tutti gli altri argomenti sono ignorati, ed il flag deve essere indicato - assieme ad una fra \const{MS\_PRIVATE}, \const{MS\_SHARED}, - \const{MS\_SLAVE} e \const{MS\_UNBINDABLE}. + e tutti gli altri argomenti sono ignorati, ed il flag deve essere indicato o + con \const{MS\_BIND} o assieme ad una fra \const{MS\_PRIVATE}, + \const{MS\_SHARED}, \const{MS\_SLAVE} e \const{MS\_UNBINDABLE}. Presente dal + kernel 2.4.11. % TODO trattare l'opzione \texttt{lazytime} introdotta con il kernel 4.0, % vedi http://lwn.net/Articles/621046/ @@ -961,68 +1088,12 @@ con un OR aritmetico dei valori dalle costanti riportate nell'elenco seguente: l'introduzione di questo comportamento l'uso delle alternative \const{MS\_NOATIME} e \const{MS\_NODIRATIME} è sostanzialmente inutile. -\item[\constd{MS\_REMOUNT}] Consente di rimontare un filesystem già montato - cambiandone le opzioni di montaggio in maniera atomica. In questo modo si - possono modificare le opzioni del filesystem anche se questo è in uso. Gli - argomenti \param{source} e \param{target} devono essere gli stessi usati per - il montaggio originale, mentre sia \param{data} che \param{mountflags} - conterranno le nuove opzioni, \param{filesystemtype} viene ignorato. - - Qualunque opzione specifica del filesystem indicata con \param{data} può - essere modificata, mentre con \param{mountflags} possono essere modificate - solo alcune opzioni generiche. Con i kernel più recenti queste sono soltanto - \const{MS\_MANDLOCK}, \const{MS\_RDONLY} e \const{MS\_SYNCHRONOUS}, prima - del kernel 2.6.16 potevano essere modificate anche le ulteriori - \const{MS\_NOATIME} e \const{MS\_NODIRATIME}, ed infine prima del kernel - 2.4.10 anche \const{MS\_NODEV}, \const{MS\_NOEXEC} e \const{MS\_NOSUID}. - -\itindbeg{shared~subtree} - -\item[\constd{MS\_SHARED}] Marca un \textit{mount point} come \textit{shared - mount}. Si tratta di una delle nuove opzioni (insieme a - \const{MS\_PRIVATE}, \const{MS\_SLAVE} e \const{MS\_UNBINDABLE}) facenti - parte dell'infrastruttura dei cosiddetti \textit{shared subtree} introdotta - a partire dal kernel 2.6.15, che estendono le funzionalità dei \textit{bind - mount}. In questo caso \param{target} dovrà fare riferimento al - \textit{mount point} che si intende marcare, e tutti gli altri argomenti - verranno ignorati. - - Lo scopo dell'opzione è ottenere che tutti i successivi \textit{bind mount} - effettuati da un \textit{mount point} marcato da essa siano di tipo - \textit{shared}, cioè ``\textsl{condividano}'' con l'originale e fra di loro - ogni ulteriore operazione di montaggio o smontaggio che avviene su una - directory al di sotto di uno qualunque di essi. Le operazioni di montaggio e - smontaggio effettuate al di sotto di un qualunque \textit{mount point} così - marcato verranno ``\textsl{propagate}'' a tutti i \textit{mount point} della - stessa condivisione, e la sezione di albero di file vista al di sotto di - ciascuno di essi sarà sempre identica. - -\itindend{shared~subtree} - \item[\constd{MS\_SILENT}] Richiede la soppressione di alcuni messaggi di avvertimento nei log del kernel (vedi sez.~\ref{sec:sess_daemon}). L'opzione è presente a partire dal kernel 2.6.17 e sostituisce, utilizzando un nome non fuorviante, la precedente \const{MS\_VERBOSE}, introdotta nel kernel 2.6.12, che aveva lo stesso effetto. -\item[\constd{MS\_SLAVE}] Marca un \textit{mount point} come \textit{slave - mount}. Si tratta di una delle nuove opzioni (insieme a - \const{MS\_PRIVATE}, \const{MS\_SHARED} e \const{MS\_UNBINDABLE}) facenti - parte dell'infrastruttura degli \textit{shared subtree} introdotta a partire - dal kernel 2.6.15, che estendono le funzionalità dei \textit{bind mount}. - In questo caso \param{target} dovrà fare riferimento al \textit{mount point} - che si intende marcare, e tutti gli altri argomenti verranno ignorati. - - Lo scopo dell'opzione è ottenere che tutti i successivi \textit{bind mount} - effettuati da un \textit{mount point} marcato da essa siano di tipo - \textit{slave}, cioè ``\textsl{condividano}'' ogni ulteriore operazione di - montaggio o smontaggio che avviene su una directory al di sotto del - \textit{mount point} originale. Le operazioni di montaggio e smontaggio in - questo caso vengono ``\textsl{propagate}'' soltanto dal \textit{mount point} - originale (detto anche \textit{master}) verso gli \textit{slave}, mentre - essi potranno eseguire al loro interno ulteriori montaggi che non saranno - propagati né negli altri né nel \textit{mount point} originale. - \item[\constd{MS\_STRICTATIME}] Ripristina il comportamento tradizionale per cui l'\textit{access time} viene aggiornato ad ogni accesso al file. L'opzione è disponibile solo a partire dal kernel 2.6.30 quando il @@ -1041,21 +1112,6 @@ con un OR aritmetico dei valori dalle costanti riportate nell'elenco seguente: compromesso in cui questo comportamento avviene solo per le directory, ed ha quindi una incidenza nettamente minore, si può usare \const{MS\_DIRSYNC}. -\item[\constd{MS\_UNBINDABLE}] Marca un \textit{mount point} come - \textit{unbindable mount}. Si tratta di una delle nuove opzioni (insieme a - \const{MS\_PRIVATE}, \const{MS\_SHARED} e \const{MS\_SLAVE}) facenti parte - dell'infrastruttura degli \textit{shared subtree} introdotta a partire dal - kernel 2.6.15, che estendono le funzionalità dei \textit{bind mount}. In - questo caso \param{target} dovrà fare riferimento al \textit{mount point} - che si intende marcare, e tutti gli altri argomenti verranno ignorati. - - Un \textit{mount point} marcato in questo modo disabilita la capacità di - eseguire dei \textit{bind mount} del suo contenuto. Si comporta cioè come - allo stesso modo di un \textit{mount point} ordinario di tipo - \textit{private} con in più la restrizione che nessuna sua sottodirectory - (anche se relativa ad un ulteriore montaggio) possa essere utilizzata per un - come sorgente di un \textit{bind mount}. - \end{basedescript} % NOTE per \const{MS\_SLAVE},\const{MS\_SHARE}, \const{MS\_PRIVATE} e @@ -6359,1304 +6415,6 @@ restituire nessun dato in caso di successo si usa (\texttt{\small 10}) una apposita funzione di uscita, mentre si restituisce come prima una eccezione con il valore di \var{errno} in caso di errore (\texttt{\small 12-13}). - -\subsection{La gestione delle \textit{capabilities}} -\label{sec:proc_capabilities} - -\itindbeg{capabilities} - -Come accennato in sez.~\ref{sec:proc_access_id} l'architettura classica della -gestione dei privilegi in un sistema unix-like ha il sostanziale problema di -fornire all'amministratore dei poteri troppo ampi. Questo comporta che anche -quando si siano predisposte delle misure di protezione per in essere in grado -di difendersi dagli effetti di una eventuale compromissione del sistema (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 misure potranno essere comunque -rimosse (nei casi elencati nella precedente nota si potrà sempre rimontare il -sistema in lettura-scrittura, o togliere l'attributo 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 risolvere questo problema sono possibili varie soluzioni ed ad esempio dai -kernel 2.5 è stata introdotta la struttura dei -\itindex{Linux~Security~Modules} \textit{Linux Security Modules} che han -permesso di aggiungere varie forme di \itindex{Mandatory~Access~Control~(DAC)} -\textit{Mandatory Access Control} (MAC), in cui si potessero parcellizzare e -controllare nei minimi dettagli tutti i privilegi e le modalità in cui questi -possono essere usati dai programmi e trasferiti agli utenti, con la creazione -di varie estensioni (come \textit{SELinux}, \textit{Smack}, \textit{Tomoyo}, -\textit{AppArmor}) che consentono di superare l'architettura tradizionale dei -permessi basati sul modello classico del controllo di accesso chiamato -\itindex{Discrectionary~Access~Control~(DAC)} \textit{Discrectionary Access - Control} (DAC). - -Ma già in precedenza, a partire dai kernel della serie 2.2, era 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 situazione -originaria di ``\textsl{tutto o nulla}''. - -\itindbeg{file~capabilities} - -Il meccanismo completo delle \textit{capabilities} (l'implementazione si rifà -ad una bozza di quello che doveva diventare lo standard POSIX.1e, poi -abbandonato) prevede inoltre la possibilità di associare le stesse ai singoli -file eseguibili, in modo da poter stabilire quali capacità possono essere -utilizzate quando viene messo in esecuzione uno specifico programma; ma il -supporto per questa funzionalità, chiamata \textit{file capabilities}, è stato -introdotto soltanto a partire dal kernel 2.6.24. Fino ad allora doveva essere -il programma stesso ad eseguire una riduzione esplicita delle sue capacità, -cosa che ha reso l'uso di questa funzionalità poco diffuso, vista la presenza -di meccanismi alternativi per ottenere limitazioni delle capacità -dell'amministratore a livello di sistema operativo, come \textit{SELinux}. - -Con questo supporto e con le ulteriori modifiche introdotte con il kernel -2.6.25 il meccanismo delle \textit{capabilities} è stato totalmente -rivoluzionato, rendendolo più aderente alle intenzioni originali dello -standard POSIX, rimuovendo il significato che fino ad allora aveva avuto la -capacità \const{CAP\_SETPCAP} e cambiando le modalità di funzionamento del -cosiddetto \textit{capabilities bounding set}. Ulteriori modifiche sono state -apportate con il kernel 2.6.26 per consentire la rimozione non ripristinabile -dei privilegi di amministratore. Questo fa sì che il significato ed il -comportamento del kernel finisca per dipendere dalla versione dello stesso e -dal fatto che le nuove \textit{file capabilities} siano abilitate o meno. Per -capire meglio la situazione e cosa è cambiato conviene allora spiegare con -maggiori dettagli come funziona il meccanismo delle \textit{capabilities}. - -Il primo passo per frazionare i privilegi garantiti all'amministratore, -supportato fin dalla introduzione iniziale del kernel 2.2, è stato quello in -cui a ciascun processo sono stati associati tre distinti insiemi di -\textit{capabilities}, denominati rispettivamente \textit{permitted}, -\textit{inheritable} ed \textit{effective}. Questi insiemi vengono mantenuti -in forma di tre diverse maschere binarie,\footnote{il kernel li mantiene, come - i vari identificatori di sez.~\ref{sec:proc_setuid}, all'interno della - \texttt{task\_struct} di ciascun processo (vedi - fig.~\ref{fig:proc_task_struct}), nei tre campi \texttt{cap\_effective}, - \texttt{cap\_inheritable}, \texttt{cap\_permitted} del tipo - \texttt{kernel\_cap\_t}; questo era, fino al kernel 2.6.25 definito come - intero a 32 bit per un massimo di 32 \textit{capabilities} distinte, - attualmente è stato aggiornato ad un vettore in grado di mantenerne fino a - 64.} in cui ciascun bit corrisponde ad una capacità diversa. - -L'utilizzo di tre distinti insiemi serve a fornire una interfaccia flessibile -per l'uso delle \textit{capabilities}, con scopi analoghi a quelli per cui -sono mantenuti i diversi insiemi di identificatori di -sez.~\ref{sec:proc_setuid}; il loro significato, che è rimasto sostanzialmente -lo stesso anche dopo le modifiche seguite alla introduzione delle -\textit{file capabilities} è il seguente: -\begin{basedescript}{\desclabelwidth{2.1cm}\desclabelstyle{\nextlinelabel}} -\item[\textit{permitted}] l'insieme delle \textit{capabilities} - ``\textsl{permesse}'', cioè l'insieme di quelle capacità che un processo - \textsl{può} impostare come \textsl{effettive} o come - \textsl{ereditabili}. Se un processo cancella una capacità da questo insieme - non potrà più riassumerla.\footnote{questo nei casi ordinari, sono - previste però una serie di eccezioni, dipendenti anche dal tipo di - supporto, che vedremo meglio in seguito dato il notevole intreccio nella - casistica.} -\item[\textit{inheritable}] l'insieme delle \textit{capabilities} - ``\textsl{ereditabili}'', cioè di quelle che verranno trasmesse come insieme - delle \textsl{permesse} ad un nuovo programma eseguito attraverso una - chiamata ad \func{exec}. -\item[\textit{effective}] l'insieme delle \textit{capabilities} - ``\textsl{effettive}'', cioè di quelle che vengono effettivamente usate dal - kernel quando deve eseguire il controllo di accesso per le varie operazioni - compiute dal processo. -\label{sec:capabilities_set} -\end{basedescript} - -Con l'introduzione delle \textit{file capabilities} sono stati introdotti -altri tre insiemi associabili a ciascun file.\footnote{la realizzazione viene - eseguita con l'uso di uno specifico attributo esteso, - \texttt{security.capability}, la cui modifica è riservata, (come illustrato - in sez.~\ref{sec:file_xattr}) ai processi dotato della capacità - \const{CAP\_SYS\_ADMIN}.} Le \textit{file capabilities} hanno effetto -soltanto quando il file che le porta viene eseguito come programma con una -\func{exec}, e forniscono un meccanismo che consente l'esecuzione dello stesso -con maggiori privilegi; in sostanza sono una sorta di estensione del -\acr{suid} bit limitato ai privilegi di amministratore. Anche questi tre -insiemi sono identificati con gli stessi nomi di quello dei processi, ma il -loro significato è diverso: -\begin{basedescript}{\desclabelwidth{2.1cm}\desclabelstyle{\nextlinelabel}} -\item[\textit{permitted}] (chiamato originariamente \textit{forced}) l'insieme - delle capacità che con l'esecuzione del programma verranno aggiunte alle - capacità \textsl{permesse} del processo. -\item[\textit{inheritable}] (chiamato originariamente \textit{allowed}) - l'insieme delle capacità che con l'esecuzione del programma possono essere - ereditate dal processo originario (che cioè non vengono tolte - dall'\textit{inheritable set} del processo originale all'esecuzione di - \func{exec}). -\item[\textit{effective}] in questo caso non si tratta di un insieme ma di un - unico valore logico; se attivo all'esecuzione del programma tutte le - capacità che risulterebbero \textsl{permesse} verranno pure attivate, - inserendole automaticamente nelle \textsl{effettive}, se disattivato nessuna - capacità verrà attivata (cioè l'\textit{effective set} resterà vuoto). -\end{basedescript} - -\itindbeg{capabilities~bounding~set} - -Infine come accennato, esiste un ulteriore insieme, chiamato -\textit{capabilities bounding set}, il cui scopo è quello di costituire un -limite alle capacità che possono essere attivate per un programma. Il suo -funzionamento però è stato notevolmente modificato con l'introduzione delle -\textit{file capabilities} e si deve pertanto prendere in considerazione una -casistica assai complessa. - -Per i kernel fino al 2.6.25, o se non si attiva il supporto per le -\textit{file capabilities}, il \textit{capabilities bounding set} è un -parametro generale di sistema, il cui valore viene riportato nel file -\sysctlfiled{kernel/cap-bound}. Il suo valore iniziale è definito in sede di -compilazione del kernel, e da sempre ha previsto come default la presenza di -tutte le \textit{capabilities} eccetto \const{CAP\_SETPCAP}. In questa -situazione solo il primo processo eseguito nel sistema (quello con -\textsl{pid} 1, di norma \texttt{/sbin/init}) ha la possibilità di -modificarlo; ogni processo eseguito successivamente, se dotato dei privilegi -di amministratore, è in grado soltanto di rimuovere una delle -\textit{capabilities} già presenti dell'insieme.\footnote{per essere precisi - occorre la capacità \const{CAP\_SYS\_MODULE}.} - -In questo caso l'effetto complessivo del \textit{capabilities bounding set} è -che solo le capacità in esso presenti possono essere trasmesse ad un altro -programma attraverso una \func{exec}. Questo in sostanza significa che se un -qualunque programma elimina da esso una capacità, considerato che -\texttt{init} (almeno nelle versioni ordinarie) non supporta la reimpostazione -del \textit{bounding set}, questa non sarà più disponibile per nessun processo -a meno di un riavvio, eliminando così in forma definitiva quella capacità per -tutti, compreso l'amministratore.\footnote{la qual cosa, visto il default - usato per il \textit{capabilities bounding set}, significa anche che - \const{CAP\_SETPCAP} non è stata praticamente mai usata nella sua forma - originale.} - -Con il kernel 2.6.25 e le \textit{file capabilities} il \textit{bounding set} -è diventato una proprietà di ciascun processo, che viene propagata invariata -sia attraverso una \func{fork} che una \func{exec}. In questo caso il file -\sysctlfile{kernel/cap-bound} non esiste e \texttt{init} non ha nessun -ruolo speciale, inoltre in questo caso all'avvio il valore iniziale prevede la -presenza di tutte le capacità (compresa \const{CAP\_SETPCAP}). - -Con questo nuovo meccanismo il \textit{bounding set} continua a ricoprire un -ruolo analogo al precedente nel passaggio attraverso una \func{exec}, come -limite alle capacità che possono essere aggiunte al processo in quanto -presenti nel \textit{permitted set} del programma messo in esecuzione, in -sostanza il nuovo programma eseguito potrà ricevere una capacità presente nel -suo \textit{permitted set} (quello del file) solo se questa è anche nel -\textit{bounding set} (del processo). In questo modo si possono rimuovere -definitivamente certe capacità da un processo, anche qualora questo dovesse -eseguire un programma privilegiato che prevede di riassegnarle. - -Si tenga presente però che in questo caso il \textit{bounding set} blocca -esclusivamente le capacità indicate nel \textit{permitted set} del programma -che verrebbero attivate in caso di esecuzione, e non quelle eventualmente già -presenti nell'\textit{inheritable set} del processo (ad esempio perché -presenti prima di averle rimosse dal \textit{bounding set}). In questo caso -eseguendo un programma che abbia anche lui dette capacità nel suo -\textit{inheritable set} queste verrebbero assegnate. - -In questa seconda versione inoltre il \textit{bounding set} costituisce anche -un limite per le capacità che possono essere aggiunte all'\textit{inheritable - set} del processo stesso con \func{capset}, sempre nel senso che queste -devono essere presenti nel \textit{bounding set} oltre che nel -\textit{permitted set} del processo. Questo limite vale anche per processi con -i privilegi di amministratore,\footnote{si tratta sempre di avere la - \textit{capability} \const{CAP\_SETPCAP}.} per i quali invece non vale la -condizione che le \textit{capabilities} da aggiungere nell'\textit{inheritable - set} debbano essere presenti nel proprio \textit{permitted set}.\footnote{lo - scopo anche in questo caso è ottenere una rimozione definitiva della - possibilità di passare una capacità rimossa dal \textit{bounding set}.} - -Come si può notare per fare ricorso alle \textit{capabilities} occorre -comunque farsi carico di una notevole complessità di gestione, aggravata dalla -presenza di una radicale modifica del loro funzionamento con l'introduzione -delle \textit{file capabilities}. Considerato che il meccanismo originale era -incompleto e decisamente problematico nel caso di programmi che non ne -sapessero tener conto,\footnote{c'è stato un grosso problema di sicurezza con - \texttt{sendmail}, riuscendo a rimuovere \const{CAP\_SETGID} - dall'\textit{inheritable set} di un processo si ottenne di far fallire - \func{setuid} in maniera inaspettata per il programma (che aspettandosi - sempre il successo della funzione non ne controllava lo stato di uscita) con - la conseguenza di effettuare come amministratore operazioni che altrimenti - sarebbero state eseguite, senza poter apportare danni, da utente normale.} -ci soffermeremo solo sulla implementazione completa presente a partire dal -kernel 2.6.25, tralasciando ulteriori dettagli riguardo la versione -precedente. - -Riassumendo le regole finora illustrate tutte le \textit{capabilities} vengono -ereditate senza modifiche attraverso una \func{fork} mentre, indicati con -\texttt{orig\_*} i valori degli insiemi del processo chiamante, con -\texttt{file\_*} quelli del file eseguito e con \texttt{bound\_set} il -\textit{capabilities bounding set}, dopo l'invocazione di \func{exec} il -processo otterrà dei nuovi insiemi di capacità \texttt{new\_*} secondo la -formula espressa dal seguente pseudo-codice C: - -\includecodesnip{listati/cap-results.c} - -% \begin{figure}[!htbp] -% \footnotesize \centering -% \begin{minipage}[c]{12cm} -% \includecodesnip{listati/cap-results.c} -% \end{minipage} -% \caption{Espressione della modifica delle \textit{capabilities} attraverso -% una \func{exec}.} -% \label{fig:cap_across_exec} -% \end{figure} - -\noindent e si noti come in particolare il \textit{capabilities bounding set} -non venga comunque modificato e resti lo stesso sia attraverso una \func{fork} -che attraverso una \func{exec}. - - -\itindend{capabilities~bounding~set} - -A queste regole se ne aggiungono delle altre che servono a riprodurre il -comportamento tradizionale di un sistema unix-like in tutta una serie di -circostanze. La prima di queste è relativa a quello che avviene quando si -esegue un file senza \textit{capabilities}; se infatti si considerasse questo -equivalente al non averne assegnata alcuna, non essendo presenti capacità né -nel \textit{permitted set} né nell'\textit{inheritable set} del file, -nell'esecuzione di un qualunque programma l'amministratore perderebbe tutti i -privilegi originali dal processo. - -Per questo motivo se un programma senza \textit{capabilities} assegnate viene -eseguito da un processo con \ids{UID} reale 0, esso verrà trattato come -se tanto il \textit{permitted set} che l'\textit{inheritable set} fossero con -tutte le \textit{capabilities} abilitate, con l'\textit{effective set} attivo, -col risultato di fornire comunque al processo tutte le capacità presenti nel -proprio \textit{bounding set}. Lo stesso avviene quando l'eseguibile ha attivo -il \acr{suid} bit ed appartiene all'amministratore, in entrambi i casi si -riesce così a riottenere il comportamento classico di un sistema unix-like. - -Una seconda circostanza è quella relativa a cosa succede alle -\textit{capabilities} di un processo nelle possibili transizioni da \ids{UID} -nullo a \ids{UID} non nullo o viceversa (corrispondenti rispettivamente a -cedere o riottenere i i privilegi di amministratore) che si possono effettuare -con le varie funzioni viste in sez.~\ref{sec:proc_setuid}. In questo caso la -casistica è di nuovo alquanto complessa, considerata anche la presenza dei -diversi gruppi di identificatori illustrati in tab.~\ref{tab:proc_uid_gid}, si -avrà allora che: -\begin{enumerate*} -\item se si passa da \ids{UID} effettivo nullo a non nullo - l'\textit{effective set} del processo viene totalmente azzerato, se - viceversa si passa da \ids{UID} effettivo non nullo a nullo il - \textit{permitted set} viene copiato nell'\textit{effective set}; -\item se si passa da \textit{file system} \ids{UID} nullo a non nullo verranno - cancellate dall'\textit{effective set} del processo tutte le capacità - attinenti i file, e cioè \const{CAP\_LINUX\_IMMUTABLE}, \const{CAP\_MKNOD}, - \const{CAP\_DAC\_OVERRIDE}, \const{CAP\_DAC\_READ\_SEARCH}, - \const{CAP\_MAC\_OVERRIDE}, \const{CAP\_CHOWN}, \const{CAP\_FSETID} e - \const{CAP\_FOWNER} (le prime due a partire dal kernel 2.2.30), nella - transizione inversa verranno invece inserite nell'\textit{effective set} - quelle capacità della precedente lista che sono presenti nel suo - \textit{permitted set}. -\item se come risultato di una transizione riguardante gli identificativi dei - gruppi \textit{real}, \textit{saved} ed \textit{effective} in cui si passa - da una situazione in cui uno di questi era nullo ad una in cui sono tutti - non nulli,\footnote{in sostanza questo è il caso di quando si chiama - \func{setuid} per rimuovere definitivamente i privilegi di amministratore - da un processo.} verranno azzerati completamente sia il \textit{permitted - set} che l'\textit{effective set}. -\end{enumerate*} -\label{sec:capability-uid-transition} - -La combinazione di tutte queste regole consente di riprodurre il comportamento -ordinario di un sistema di tipo Unix tradizionale, ma può risultare -problematica qualora si voglia passare ad una configurazione di sistema -totalmente basata sull'applicazione delle \textit{capabilities}; in tal caso -infatti basta ad esempio eseguire un programma con \acr{suid} bit di proprietà -dell'amministratore per far riottenere ad un processo tutte le capacità -presenti nel suo \textit{bounding set}, anche se si era avuta la cura di -cancellarle dal \textit{permitted set}. - -\itindbeg{securebits} - -Per questo motivo a partire dal kernel 2.6.26, se le \textit{file - capabilities} sono abilitate, ad ogni processo viene stata associata una -ulteriore maschera binaria, chiamata \textit{securebits flags}, su cui sono -mantenuti una serie di flag (vedi tab.~\ref{tab:securebits_values}) il cui -valore consente di modificare queste regole speciali che si applicano ai -processi con \ids{UID} nullo. La maschera viene sempre mantenuta -attraverso una \func{fork}, mentre attraverso una \func{exec} viene sempre -cancellato il flag \const{SECURE\_KEEP\_CAPS}. - -\begin{table}[htb] - \centering - \footnotesize - \begin{tabular}{|l|p{10cm}|} - \hline - \textbf{Flag} & \textbf{Descrizione} \\ - \hline - \hline - \constd{SECURE\_KEEP\_CAPS}&Il processo non subisce la cancellazione delle - sue \textit{capabilities} quando tutti i suoi - \ids{UID} passano ad un valore non - nullo (regola di compatibilità per il cambio - di \ids{UID} n.~3 del precedente - elenco), sostituisce il precedente uso - dell'operazione \const{PR\_SET\_KEEPCAPS} di - \func{prctl}.\\ - \constd{SECURE\_NO\_SETUID\_FIXUP}&Il processo non subisce le modifiche - delle sue \textit{capabilities} nel passaggio - da nullo a non nullo degli \ids{UID} - dei gruppi \textit{effective} e - \textit{file system} (regole di compatibilità - per il cambio di \ids{UID} nn.~1 e 2 del - precedente elenco).\\ - \constd{SECURE\_NOROOT} & Il processo non assume nessuna capacità - aggiuntiva quando esegue un programma, anche - se ha \ids{UID} nullo o il programma ha - il \acr{suid} bit attivo ed appartiene - all'amministratore (regola di compatibilità - per l'esecuzione di programmi senza - \textit{capabilities}).\\ - \hline - \end{tabular} - \caption{Costanti identificative dei flag che compongono la maschera dei - \textit{securebits}.} - \label{tab:securebits_values} -\end{table} - -A ciascuno dei flag di tab.~\ref{tab:securebits_values} è inoltre abbinato un -corrispondente flag di blocco, identificato da una costante omonima con -l'estensione \texttt{\_LOCKED}, la cui attivazione è irreversibile ed ha -l'effetto di rendere permanente l'impostazione corrente del corrispondente -flag ordinario; in sostanza con \constd{SECURE\_KEEP\_CAPS\_LOCKED} si rende -non più modificabile \const{SECURE\_KEEP\_CAPS}, ed analogamente avviene con -\constd{SECURE\_NO\_SETUID\_FIXUP\_LOCKED} per -\const{SECURE\_NO\_SETUID\_FIXUP} e con \constd{SECURE\_NOROOT\_LOCKED} per -\const{SECURE\_NOROOT}. - -Per l'impostazione di questi flag sono state predisposte due specifiche -operazioni di \func{prctl} (vedi sez.~\ref{sec:process_prctl}), -\const{PR\_GET\_SECUREBITS}, che consente di ottenerne il valore, e -\const{PR\_SET\_SECUREBITS}, che consente di modificarne il valore; per -quest'ultima sono comunque necessari i privilegi di amministratore ed in -particolare la capacità \const{CAP\_SETPCAP}. Prima dell'introduzione dei -\textit{securebits} era comunque possibile ottenere lo stesso effetto di -\const{SECURE\_KEEP\_CAPS} attraverso l'uso di un'altra operazione di -\func{prctl}, \const{PR\_SET\_KEEPCAPS}. - -\itindend{securebits} - -Oltre alla gestione dei \textit{securebits} la nuova versione delle -\textit{file capabilities} prevede l'uso di \func{prctl} anche per la gestione -del \textit{capabilities bounding set}, attraverso altre due operazioni -dedicate, \const{PR\_CAPBSET\_READ} per controllarne il valore e -\const{PR\_CAPBSET\_DROP} per modificarlo; quest'ultima di nuovo è una -operazione privilegiata che richiede la capacità \const{CAP\_SETPCAP} e che, -come indica chiaramente il nome, permette solo la rimozione di una -\textit{capability} dall'insieme; per i dettagli sull'uso di tutte queste -operazioni si rimanda alla rilettura di sez.~\ref{sec:process_prctl}. - -\itindend{file~capabilities} - - -% NOTE per dati relativi al process capability bounding set, vedi: -% http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=3b7391de67da515c91f48aa371de77cb6cc5c07e - -% NOTE riferimenti ai vari cambiamenti vedi: -% http://lwn.net/Articles/280279/ -% http://lwn.net/Articles/256519/ -% http://lwn.net/Articles/211883/ - - -Un elenco delle delle \textit{capabilities} disponibili su Linux, con una -breve descrizione ed il nome delle costanti che le identificano, è riportato -in tab.~\ref{tab:proc_capabilities};\footnote{l'elenco presentato questa - tabella, ripreso dalla pagina di manuale (accessibile con \texttt{man - capabilities}) e dalle definizioni in - \texttt{include/linux/capabilities.h}, è aggiornato al kernel 3.2.} la -tabella è divisa in due parti, la prima riporta le \textit{capabilities} -previste anche nella bozza dello standard POSIX1.e, la seconda quelle -specifiche di Linux. Come si può notare dalla tabella alcune -\textit{capabilities} attengono a singole funzionalità e sono molto -specializzate, mentre altre hanno un campo di applicazione molto vasto, che è -opportuno dettagliare maggiormente. - -\begin{table}[!h!btp] - \centering - \footnotesize - \begin{tabular}{|l|p{10cm}|} - \hline - \textbf{Capacità}&\textbf{Descrizione}\\ - \hline - \hline -% -% POSIX-draft defined capabilities. -% - \constd{CAP\_AUDIT\_CONTROL}& Abilitare e disabilitare il - controllo dell'auditing (dal kernel 2.6.11).\\ - \constd{CAP\_AUDIT\_WRITE}&Scrivere dati nel giornale di - auditing del kernel (dal kernel 2.6.11).\\ - % TODO verificare questa roba dell'auditing - \constd{CAP\_BLOCK\_SUSPEND}&Utilizzare funzionalità che possono bloccare - la sospensione del sistema (dal kernel 3.5).\\ - \constd{CAP\_CHOWN} & Cambiare proprietario e gruppo - proprietario di un file (vedi - sez.~\ref{sec:file_ownership_management}).\\ - \constd{CAP\_DAC\_OVERRIDE}& Evitare il controllo dei - permessi di lettura, scrittura ed esecuzione dei - file, (vedi sez.~\ref{sec:file_access_control}).\\ - \constd{CAP\_DAC\_READ\_SEARCH}& Evitare il controllo dei - permessi di lettura ed esecuzione per - le directory (vedi - sez.~\ref{sec:file_access_control}).\\ - \const{CAP\_FOWNER} & Evitare il controllo della proprietà di un file - per tutte le operazioni privilegiate non coperte - dalle precedenti \const{CAP\_DAC\_OVERRIDE} e - \const{CAP\_DAC\_READ\_SEARCH}.\\ - \constd{CAP\_FSETID} & Evitare la cancellazione automatica dei bit - \acr{suid} e \acr{sgid} quando un file - per i quali sono impostati viene modificato da - un processo senza questa capacità e la capacità - di impostare il bit \acr{sgid} su un file anche - quando questo è relativo ad un gruppo cui non si - appartiene (vedi - sez.~\ref{sec:file_perm_management}).\\ - \constd{CAP\_KILL} & Mandare segnali a qualunque - processo (vedi sez.~\ref{sec:sig_kill_raise}).\\ - \constd{CAP\_SETFCAP} & Impostare le \textit{capabilities} di un file - (dal kernel 2.6.24).\\ - \constd{CAP\_SETGID} & Manipolare i group ID dei - processi, sia il principale che i supplementari, - (vedi sez.~\ref{sec:proc_setgroups}) che quelli - trasmessi tramite i socket \textit{unix domain} - (vedi sez.~\ref{sec:unix_socket}).\\ - \constd{CAP\_SETUID} & Manipolare gli user ID del - processo (vedi sez.~\ref{sec:proc_setuid}) e di - trasmettere un user ID arbitrario nel passaggio - delle credenziali coi socket \textit{unix - domain} (vedi sez.~\ref{sec:unix_socket}).\\ -% -% Linux specific capabilities -% -\hline - \constd{CAP\_IPC\_LOCK} & Effettuare il \textit{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}). \\ -% TODO verificare l'interazione con SHM_HUGETLB - \constd{CAP\_IPC\_OWNER}& Evitare il controllo dei permessi - per le operazioni sugli oggetti di - intercomunicazione fra processi (vedi - sez.~\ref{sec:ipc_sysv}).\\ - \constd{CAP\_LEASE} & Creare dei \textit{file lease} (vedi - sez.~\ref{sec:file_asyncronous_lease}) - pur non essendo proprietari del file (dal kernel - 2.4).\\ - \constd{CAP\_LINUX\_IMMUTABLE}& Impostare sui file gli attributi - \textit{immutable} e \textit{append-only} (vedi - sez.~\ref{sec:file_perm_overview}) se - supportati.\\ - \constd{CAP\_MAC\_ADMIN}& Amministrare il \textit{Mandatory - Access Control} di \textit{Smack} (dal kernel - 2.6.25).\\ - \constd{CAP\_MAC\_OVERRIDE}& Evitare il \textit{Mandatory - Access Control} di \textit{Smack} (dal kernel - 2.6.25).\\ - \constd{CAP\_MKNOD} & Creare file di dispositivo con \func{mknod} (vedi - sez.~\ref{sec:file_mknod}) (dal kernel 2.4).\\ - \const{CAP\_NET\_ADMIN} & Eseguire alcune operazioni - privilegiate sulla rete.\\ - \constd{CAP\_NET\_BIND\_SERVICE}& Porsi in ascolto su porte riservate (vedi - sez.~\ref{sec:TCP_func_bind}).\\ - \constd{CAP\_NET\_BROADCAST}& Consentire l'uso di socket in - \textit{broadcast} e \textit{multicast}.\\ - \constd{CAP\_NET\_RAW} & Usare socket \texttt{RAW} e \texttt{PACKET} - (vedi sez.~\ref{sec:sock_type}).\\ - \const{CAP\_SETPCAP} & Effettuare modifiche privilegiate alle - \textit{capabilities}.\\ - \const{CAP\_SYS\_ADMIN} & Eseguire una serie di compiti amministrativi.\\ - \constd{CAP\_SYS\_BOOT} & Eseguire un riavvio del sistema (vedi - sez.~\ref{sec:sys_reboot}).\\ - \constd{CAP\_SYS\_CHROOT}& Eseguire la funzione \func{chroot} (vedi - sez.~\ref{sec:file_chroot}).\\ - \constd{CAP\_SYS\_MODULE}& Caricare e rimuovere moduli del kernel.\\ - \const{CAP\_SYS\_NICE} & Modificare le varie priorità dei processi (vedi - sez.~\ref{sec:proc_priority}).\\ - \constd{CAP\_SYS\_PACCT}& Usare le funzioni di \textit{accounting} dei - processi (vedi - sez.~\ref{sec:sys_bsd_accounting}).\\ - \constd{CAP\_SYS\_PTRACE}& La capacità di tracciare qualunque processo con - \func{ptrace} (vedi - sez.~\ref{sec:process_ptrace}).\\ - \constd{CAP\_SYS\_RAWIO}& Operare sulle porte di I/O con \func{ioperm} e - \func{iopl} (vedi - sez.~\ref{sec:process_io_port}).\\ - \const{CAP\_SYS\_RESOURCE}& Superare le varie limitazioni sulle risorse.\\ - \constd{CAP\_SYS\_TIME} & Modificare il tempo di sistema (vedi - sez.~\ref{sec:sys_time}).\\ - \constd{CAP\_SYS\_TTY\_CONFIG}&Simulare un \textit{hangup} della console, - con la funzione \func{vhangup}.\\ - \constd{CAP\_SYSLOG} & Gestire il buffer dei messaggi - del kernel, (vedi sez.~\ref{sec:sess_daemon}), - introdotta dal kernel 2.6.38 come capacità - separata da \const{CAP\_SYS\_ADMIN}.\\ - \constd{CAP\_WAKE\_ALARM}&Usare i timer di tipo - \const{CLOCK\_BOOTTIME\_ALARM} e - \const{CLOCK\_REALTIME\_ALARM}, vedi - sez.~\ref{sec:sig_timer_adv} (dal kernel 3.0).\\ - \hline - \end{tabular} - \caption{Le costanti che identificano le \textit{capabilities} presenti nel - kernel.} -\label{tab:proc_capabilities} -\end{table} - -\constbeg{CAP\_SETPCAP} - -Prima di dettagliare il significato della capacità più generiche, conviene -però dedicare un discorso a parte a \const{CAP\_SETPCAP}, il cui significato è -stato completamente cambiato con l'introduzione delle \textit{file - capabilities} nel kernel 2.6.24. In precedenza questa capacità era quella -che permetteva al processo che la possedeva di impostare o rimuovere le -\textit{capabilities} presenti nel suo \textit{permitted set} su un qualunque -altro processo. In realtà questo non è mai stato l'uso inteso nelle bozze -dallo standard POSIX, ed inoltre, come si è già accennato, dato che questa -capacità è sempre stata assente (a meno di specifiche ricompilazioni del -kernel) nel \textit{capabilities bounding set} usato di default, essa non è -neanche mai stata realmente disponibile. - -Con l'introduzione \textit{file capabilities} e il cambiamento del significato -del \textit{capabilities bounding set} la possibilità di modificare le -capacità di altri processi è stata completamente rimossa, e -\const{CAP\_SETPCAP} ha acquisito quello che avrebbe dovuto essere il suo -significato originario, e cioè la capacità del processo di poter inserire nel -suo \textit{inheritable set} qualunque capacità presente nel \textit{bounding - set}. Oltre a questo la disponibilità di \const{CAP\_SETPCAP} consente ad un -processo di eliminare una capacità dal proprio \textit{bounding set} (con la -conseguente impossibilità successiva di eseguire programmi con quella -capacità), o di impostare i \textit{securebits} delle \textit{capabilities}. - -\constend{CAP\_SETPCAP} -\constbeg{CAP\_FOWNER} - -La prima fra le capacità ``\textsl{ampie}'' che occorre dettagliare -maggiormente è \const{CAP\_FOWNER}, che rimuove le restrizioni poste ad un -processo che non ha la proprietà di un file in un vasto campo di -operazioni;\footnote{vale a dire la richiesta che l'\ids{UID} effettivo del - processo (o meglio l'\ids{UID} di filesystem, vedi - sez.~\ref{sec:proc_setuid}) coincida con quello del proprietario.} queste -comprendono i cambiamenti dei permessi e dei tempi del file (vedi -sez.~\ref{sec:file_perm_management} e sez.~\ref{sec:file_file_times}), le -impostazioni degli attributi dei file e delle ACL (vedi -sez.~\ref{sec:file_xattr} e \ref{sec:file_ACL}), poter ignorare lo -\textit{sticky bit} nella cancellazione dei file (vedi -sez.~\ref{sec:file_special_perm}), la possibilità di impostare il flag di -\const{O\_NOATIME} con \func{open} e \func{fcntl} (vedi -sez.~\ref{sec:file_open_close} e sez.~\ref{sec:file_fcntl_ioctl}) senza -restrizioni. - -\constend{CAP\_FOWNER} -\constbeg{CAP\_NET\_ADMIN} - -Una seconda capacità che copre diverse operazioni, in questo caso riguardanti -la rete, è \const{CAP\_NET\_ADMIN}, che consente di impostare le opzioni -privilegiate dei socket (vedi sez.~\ref{sec:sock_generic_options}), abilitare -il \textit{multicasting} (vedi sez.\ref{sec:sock_ipv4_options}), eseguire la -configurazione delle interfacce di rete (vedi -sez.~\ref{sec:sock_ioctl_netdevice}) ed impostare la tabella di instradamento. - -\constend{CAP\_NET\_ADMIN} -\constbeg{CAP\_SYS\_ADMIN} - -Una terza \textit{capability} con vasto campo di applicazione è -\const{CAP\_SYS\_ADMIN}, che copre una serie di operazioni amministrative, -come impostare le quote disco (vedi sez.\ref{sec:disk_quota}), attivare e -disattivare la swap, montare, rimontare e smontare filesystem (vedi -sez.~\ref{sec:filesystem_mounting}), effettuare operazioni di controllo su -qualunque oggetto dell'IPC di SysV (vedi sez.~\ref{sec:ipc_sysv}), operare -sugli attributi estesi dei file di classe \texttt{security} o \texttt{trusted} -(vedi sez.~\ref{sec:file_xattr}), specificare un \ids{UID} arbitrario nella -trasmissione delle credenziali dei socket (vedi -sez.~\ref{sec:socket_credential_xxx}), assegnare classi privilegiate -(\const{IOPRIO\_CLASS\_RT} e prima del kernel 2.6.25 anche -\const{IOPRIO\_CLASS\_IDLE}) per lo scheduling dell'I/O (vedi -sez.~\ref{sec:io_priority}), superare il limite di sistema sul numero massimo -di file aperti,\footnote{quello indicato da \sysctlfiled{fs/file-max}.} -effettuare operazioni privilegiate sulle chiavi mantenute dal kernel (vedi -sez.~\ref{sec:keyctl_management}), usare la funzione \func{lookup\_dcookie}, -usare \const{CLONE\_NEWNS} con \func{unshare} e \func{clone}, (vedi -sez.~\ref{sec:process_clone}). - -\constend{CAP\_SYS\_ADMIN} -\constbeg{CAP\_SYS\_NICE} - -Originariamente \const{CAP\_SYS\_NICE} riguardava soltanto la capacità di -aumentare le priorità di esecuzione dei processi, come la diminuzione del -valore di \textit{nice} (vedi sez.~\ref{sec:proc_sched_stand}), l'uso delle -priorità \textit{real-time} (vedi sez.~\ref{sec:proc_real_time}), o -l'impostazione delle affinità di processore (vedi -sez.~\ref{sec:proc_sched_multiprocess}); ma con l'introduzione di priorità -anche riguardo le operazioni di accesso al disco, e, nel caso di sistemi NUMA, -alla memoria, essa viene a coprire anche la possibilità di assegnare priorità -arbitrarie nell'accesso a disco (vedi sez.~\ref{sec:io_priority}) e nelle -politiche di allocazione delle pagine di memoria ai nodi di un sistema NUMA. - -\constend{CAP\_SYS\_NICE} -\constbeg{CAP\_SYS\_RESOURCE} - -Infine la \textit{capability} \const{CAP\_SYS\_RESOURCE} attiene alla -possibilità di superare i limiti imposti sulle risorse di sistema, come usare -lo spazio disco riservato all'amministratore sui filesystem che lo supportano, -usare la funzione \func{ioctl} per controllare il \textit{journaling} sul -filesystem \acr{ext3}, non subire le quote disco, aumentare i limiti sulle -risorse di un processo (vedi sez.~\ref{sec:sys_resource_limit}) e quelle sul -numero di processi, ed i limiti sulle dimensioni dei messaggi delle code del -SysV IPC (vedi sez.~\ref{sec:ipc_sysv_mq}). - -\constend{CAP\_SYS\_RESOURCE} - -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 di sistema sono -\funcd{capget} e \funcd{capset} e costituiscono l'interfaccia di gestione -basso livello; i loro rispettivi prototipi sono: - -\begin{funcproto}{ -\fhead{sys/capability.h} -\fdecl{int capget(cap\_user\_header\_t hdrp, cap\_user\_data\_t datap)} -\fdesc{Legge le \textit{capabilities}.} -\fdecl{int capset(cap\_user\_header\_t hdrp, const cap\_user\_data\_t datap)} -\fdesc{Imposta le \textit{capabilities}.} -} - -{Le funzioni ritornano $0$ in caso di successo e $-1$ per un errore, nel qual - caso \var{errno} assumerà uno dei valori: - \begin{errlist} - \item[\errcode{EFAULT}] si è indicato un puntatore sbagliato o nullo - per \param{hdrp} o \param{datap} (quest'ultimo può essere nullo solo se si - usa \func{capget} per ottenere la versione delle \textit{capabilities} - usata dal kernel). - \item[\errcode{EINVAL}] si è specificato un valore non valido per uno dei - campi di \param{hdrp}, in particolare una versione non valida della - versione delle \textit{capabilities}. - \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}. - \item[\errcode{ESRCH}] si è fatto riferimento ad un processo inesistente. - \end{errlist} -} -\end{funcproto} - -Queste due funzioni prendono come argomenti due tipi di dati dedicati, -definiti come puntatori a due strutture specifiche di Linux, illustrate in -fig.~\ref{fig:cap_kernel_struct}. Per un certo periodo di tempo era anche -indicato che per poterle utilizzare fosse necessario che la macro -\macro{\_POSIX\_SOURCE} risultasse non definita (ed era richiesto di inserire -una istruzione \texttt{\#undef \_POSIX\_SOURCE} prima di includere -\headfiled{sys/capability.h}) requisito che non risulta più -presente.\footnote{e non è chiaro neanche quanto sia mai stato davvero - necessario.} - -\begin{figure}[!htb] - \footnotesize - \centering - \begin{minipage}[c]{0.8\textwidth} - \includestruct{listati/cap_user_header_t.h} - \end{minipage} - \normalsize - \caption{Definizione delle strutture a cui fanno riferimento i puntatori - \structd{cap\_user\_header\_t} e \structd{cap\_user\_data\_t} usati per - l'interfaccia di gestione di basso livello delle \textit{capabilities}.} - \label{fig:cap_kernel_struct} -\end{figure} - -Si tenga presente che le strutture di fig.~\ref{fig:cap_kernel_struct}, come i -prototipi delle due funzioni \func{capget} e \func{capset}, sono soggette ad -essere modificate con il cambiamento del kernel (in particolare i tipi di dati -delle strutture) ed anche se finora l'interfaccia è risultata stabile, non c'è -nessuna assicurazione che questa venga mantenuta,\footnote{viene però - garantito che le vecchie funzioni continuino a funzionare.} Pertanto se si -vogliono scrivere programmi portabili che possano essere eseguiti senza -modifiche o adeguamenti su qualunque versione del kernel è opportuno -utilizzare le interfacce di alto livello che vedremo più avanti. - -La struttura a cui deve puntare l'argomento \param{hdrp} serve ad indicare, -tramite il campo \var{pid}, il \ids{PID} del processo del quale si vogliono -leggere o modificare le \textit{capabilities}. Con \func{capset} questo, se si -usano le \textit{file capabilities}, può essere solo 0 o il \ids{PID} del -processo chiamante, che sono equivalenti. Non tratteremo, essendo comunque di -uso irrilevante, il caso in cui, in mancanza di tale supporto, la funzione può -essere usata per modificare le \textit{capabilities} di altri processi, per il -quale si rimanda, se interessati, alla lettura della pagina di manuale. - -Il campo \var{version} deve essere impostato al valore della versione delle -stesse usata dal kernel (quello indicato da una delle costanti -\texttt{\_LINUX\_CAPABILITY\_VERSION\_n} di fig.~\ref{fig:cap_kernel_struct}) -altrimenti le funzioni ritorneranno con un errore di \errcode{EINVAL}, -restituendo nel campo stesso il valore corretto della versione in uso. La -versione due è comunque deprecata e non deve essere usata, ed il kernel -stamperà un avviso se lo si fa. - -I valori delle \textit{capabilities} devono essere passati come maschere -binarie;\footnote{e si tenga presente che i valori di - tab.~\ref{tab:proc_capabilities} non possono essere combinati direttamente, - indicando il numero progressivo del bit associato alla relativa capacità.} -con l'introduzione delle \textit{capabilities} a 64 bit inoltre il -puntatore \param{datap} non può essere più considerato come relativo ad una -singola struttura, ma ad un vettore di due strutture.\footnote{è questo cambio - di significato che ha portato a deprecare la versione 2, che con - \func{capget} poteva portare ad un buffer overflow per vecchie applicazioni - che continuavano a considerare \param{datap} come puntatore ad una singola - struttura.} - -Dato che le precedenti funzioni, oltre ad essere specifiche di Linux, non -garantiscono la stabilità nell'interfaccia, è sempre opportuno effettuare la -gestione delle \textit{capabilities} utilizzando le funzioni di libreria a -questo dedicate. Queste funzioni, che seguono quanto previsto nelle bozze -dello standard POSIX.1e, non fanno parte della \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 al compilatore l'uso -della suddetta libreria attraverso l'opzione \texttt{-lcap}. - -\itindbeg{capability~state} - -Le funzioni dell'interfaccia alle \textit{capabilities} definite nelle bozze -dello standard POSIX.1e prevedono l'uso di un tipo di dato opaco, -\typed{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 fanno 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 i \textit{capability state}, che presentano notevoli affinità, -essendo parte di bozze dello stesso standard, con quelle già viste per le ACL. - -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{funcproto}{ -\fhead{sys/capability.h} -\fdecl{cap\_t cap\_init(void)} -\fdesc{Crea ed inizializza un \textit{capability state}.} -} - -{La funzione ritorna un \textit{capability state} in caso di successo e - \val{NULL} per un errore, nel qual caso \var{errno} potrà assumere solo il - valore \errval{ENOMEM}. } -\end{funcproto} - -La funzione restituisce il puntatore \type{cap\_t} ad uno stato inizializzato -con tutte le \textit{capabilities} azzerate. In caso di errore (cioè quando -non c'è memoria sufficiente ad allocare i dati) viene restituito \val{NULL} -ed \var{errno} viene impostata a \errval{ENOMEM}. - -La memoria necessaria a mantenere i dati viene automaticamente allocata da -\func{cap\_init}, ma dovrà essere disallocata esplicitamente quando non è più -necessaria utilizzando, per questo l'interfaccia fornisce una apposita -funzione, \funcd{cap\_free}, il cui prototipo è: - -\begin{funcproto}{ -\fhead{sys/capability.h} -\fdecl{int cap\_free(void *obj\_d)} -\fdesc{Disalloca la memoria allocata per i dati delle \textit{capabilities}..} -} - -{La funzione ritorna $0$ in caso di successo e $-1$ per un errore, nel qual - caso \var{errno} potrà assumere solo il valore \errval{EINVAL}. -} -\end{funcproto} - - -La funzione permette di liberare la memoria allocata dalle altre funzioni -della libreria sia per un \textit{capability state}, nel qual caso l'argomento -sarà 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 sarà un dato di tipo -\texttt{char *}. Per questo motivo l'argomento \param{obj\_d} è dichiarato -come \texttt{void *}, per evitare la necessità di eseguire un \textit{cast}, -ma dovrà comunque corrispondere ad un puntatore ottenuto tramite le altre -funzioni della libreria, altrimenti la funzione fallirà con un errore di -\errval{EINVAL}. - -Infine si può creare una copia di un \textit{capability state} ottenuto in -precedenza tramite la funzione \funcd{cap\_dup}, il cui prototipo è: - -\begin{funcproto}{ -\fhead{sys/capability.h} -\fdecl{cap\_t cap\_dup(cap\_t cap\_p)} -\fdesc{Duplica un \textit{capability state} restituendone una copia.} -} - -{La funzione ritorna un \textit{capability state} in caso di successo e - \val{NULL} per un errore, nel qual caso \var{errno} assumerà i valori - \errval{ENOMEM} o \errval{EINVAL} nel loro significato generico.} -\end{funcproto} - - -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, ed alla fine -delle operazioni si dovrà disallocare anche la copia, oltre all'originale. - -Una seconda classe di funzioni di servizio previste dall'interfaccia sono -quelle per la gestione dei dati contenuti all'interno di un \textit{capability - state}; la prima di queste è \funcd{cap\_clear}, il cui prototipo è: - -\begin{funcproto}{ -\fhead{sys/capability.h} -\fdecl{int cap\_clear(cap\_t cap\_p)} -\fdesc{Inizializza un \textit{capability state} cancellando tutte le - \textit{capabilities}.} -} - -{La funzione ritorna $0$ in caso di successo e $-1$ per un errore, nel qual - caso \var{errno} potrà assumere solo il valore \errval{EINVAL}. -} -\end{funcproto} - -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}. - -Una variante di \func{cap\_clear} è \funcd{cap\_clear\_flag} che cancella da -un \textit{capability state} tutte le \textit{capabilities} di un certo -insieme fra quelli elencati a pag.~\pageref{sec:capabilities_set}, il suo -prototipo è: - -\begin{funcproto}{ -\fhead{sys/capability.h} -\fdecl{int cap\_clear\_flag(cap\_t cap\_p, cap\_flag\_t flag)} -\fdesc{Cancella delle \textit{capabilities} da un \textit{capability state}.} -} - -{La funzione ritorna $0$ in caso di successo e $-1$ per un errore, nel qual - caso \var{errno} potrà assumere solo il valore \errval{EINVAL}. -} -\end{funcproto} - -La funzione richiede che si indichi quale degli insiemi si intente cancellare -da \param{cap\_p} con l'argomento \param{flag}. Questo deve essere specificato -con una variabile di tipo \type{cap\_flag\_t} che può assumere -esclusivamente\footnote{si tratta in effetti di un tipo enumerato, come si può - verificare dalla sua definizione che si trova in - \headfile{sys/capability.h}.} uno dei valori illustrati in -tab.~\ref{tab:cap_set_identifier}. - -\begin{table}[htb] - \centering - \footnotesize - \begin{tabular}[c]{|l|l|} - \hline - \textbf{Valore} & \textbf{Significato} \\ - \hline - \hline - \constd{CAP\_EFFECTIVE} & Capacità dell'insieme \textsl{effettivo}.\\ - \constd{CAP\_PERMITTED} & Capacità dell'insieme \textsl{permesso}.\\ - \constd{CAP\_INHERITABLE}& Capacità dell'insieme \textsl{ereditabile}.\\ - \hline - \end{tabular} - \caption{Valori possibili per il tipo di dato \typed{cap\_flag\_t} che - identifica gli insiemi delle \textit{capabilities}.} - \label{tab:cap_set_identifier} -\end{table} - -Si possono inoltre confrontare in maniera diretta due diversi -\textit{capability state} con la funzione \funcd{cap\_compare}; il suo -prototipo è: - -\begin{funcproto}{ -\fhead{sys/capability.h} -\fdecl{int cap\_compare(cap\_t cap\_a, cap\_t cap\_b)} -\fdesc{Confronta due \textit{capability state}.} -} - -{La funzione ritorna $0$ se i \textit{capability state} sono identici - ed un valore positivo se differiscono, non sono previsti errori.} -\end{funcproto} - - -La funzione esegue un confronto fra i due \textit{capability state} passati -come argomenti e ritorna in un valore intero il risultato, questo è nullo se -sono identici o positivo se vi sono delle differenze. Il valore di ritorno -della funzione consente inoltre di per ottenere ulteriori informazioni su -quali sono gli insiemi di \textit{capabilities} che risultano differenti. Per -questo si può infatti usare la apposita macro \macro{CAP\_DIFFERS}: - -{\centering -\vspace{3pt} -\begin{funcbox}{ -\fhead{sys/capability.h} -\fdecl{int \macrod{CAP\_DIFFERS}(value, flag)} -\fdesc{Controlla lo stato di eventuali differenze delle \textit{capabilities} - nell'insieme \texttt{flag}.} -} -\end{funcbox} -} - -La macro richiede che si passi nell'argomento \texttt{value} il risultato -della funzione \func{cap\_compare} e in \texttt{flag} l'indicazione (coi -valori di tab.~\ref{tab:cap_set_identifier}) dell'insieme che si intende -controllare; restituirà un valore diverso da zero se le differenze rilevate da -\func{cap\_compare} sono presenti nell'insieme indicato. - -Per la gestione dei singoli valori delle \textit{capabilities} presenti in un -\textit{capability state} l'interfaccia prevede due funzioni specifiche, -\funcd{cap\_get\_flag} e \funcd{cap\_set\_flag}, che permettono -rispettivamente di leggere o impostare il valore di una capacità all'interno -in uno dei tre insiemi già citati; i rispettivi prototipi sono: - -\begin{funcproto}{ -\fhead{sys/capability.h} -\fdecl{int cap\_get\_flag(cap\_t cap\_p, cap\_value\_t cap, cap\_flag\_t -flag,\\ -\phantom{int cap\_get\_flag(}cap\_flag\_value\_t *value\_p)} -\fdesc{Legge il valore di una \textit{capability}.} -\fdecl{int cap\_set\_flag(cap\_t cap\_p, cap\_flag\_t flag, int ncap, - cap\_value\_t *caps, \\ -\phantom{int cap\_set\_flag(}cap\_flag\_value\_t value)} -\fdesc{Imposta il valore di una \textit{capability}.} -} - -{Le funzioni ritornano $0$ in caso di successo e $-1$ per un errore, nel qual - caso \var{errno} potrà assumere solo il valore \errval{EINVAL}. -} -\end{funcproto} - -In entrambe le funzioni l'argomento \param{cap\_p} indica il puntatore al -\textit{capability state} su cui operare, mentre l'argomento \param{flag} -indica su quale dei tre insiemi si intende operare, sempre con i valori di -tab.~\ref{tab:cap_set_identifier}. La capacità che si intende controllare o -impostare invece deve essere specificata attraverso una variabile di tipo -\typed{cap\_value\_t}, che può prendere come valore uno qualunque di quelli -riportati in tab.~\ref{tab:proc_capabilities}, in questo caso però non è -possibile combinare diversi valori in una maschera binaria, una variabile di -tipo \type{cap\_value\_t} può indicare una sola capacità.\footnote{in - \headfile{sys/capability.h} il tipo \type{cap\_value\_t} è definito come - \ctyp{int}, ma i valori validi sono soltanto quelli di - tab.~\ref{tab:proc_capabilities}.} - -Infine lo stato di una capacità è descritto ad una variabile di tipo -\type{cap\_flag\_value\_t}, che a sua volta può assumere soltanto -uno\footnote{anche questo è un tipo enumerato.} dei valori di -tab.~\ref{tab:cap_value_type}. - -\begin{table}[htb] - \centering - \footnotesize - \begin{tabular}[c]{|l|l|} - \hline - \textbf{Valore} & \textbf{Significato} \\ - \hline - \hline - \constd{CAP\_CLEAR}& La capacità non è impostata.\\ - \constd{CAP\_SET} & La capacità è impostata.\\ - \hline - \end{tabular} - \caption{Valori possibili per il tipo di dato \typed{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 lo restituisce come \textit{value result argument} nella -variabile puntata dall'argomento \param{value\_p}. Questa deve essere di tipo -\type{cap\_flag\_value\_t} ed assumerà uno dei valori di -tab.~\ref{tab:cap_value_type}. La funzione consente pertanto di leggere solo -lo stato di una capacità alla volta. - -La funzione \func{cap\_set\_flag} può invece impostare in una sola chiamata -più \textit{capabilities}, anche se solo all'interno dello stesso insieme ed -allo stesso valore. Per questo motivo essa prende un vettore di valori di tipo -\type{cap\_value\_t} nell'argomento \param{caps}, la cui dimensione viene -specificata dall'argomento \param{ncap}. Il tipo di impostazione da eseguire -(cancellazione o attivazione) per le capacità elencate in \param{caps} viene -indicato dall'argomento \param{value} sempre con i valori di -tab.~\ref{tab:cap_value_type}. - -Per semplificare la gestione delle \textit{capabilities} l'interfaccia prevede -che sia possibile utilizzare anche una rappresentazione testuale del contenuto -di un \textit{capability state} e fornisce le opportune funzioni di -gestione;\footnote{entrambe erano previste dalla bozza dello standard - POSIX.1e.} la prima di queste, che consente di ottenere la rappresentazione -testuale, è \funcd{cap\_to\_text}, il cui prototipo è: - -\begin{funcproto}{ -\fhead{sys/capability.h} -\fdecl{char *cap\_to\_text(cap\_t caps, ssize\_t *length\_p)} -\fdesc{Genera una visualizzazione testuale delle \textit{capabilities}.} -} - -{La funzione ritorna un puntatore alla stringa con la descrizione delle - \textit{capabilities} in caso di successo e \val{NULL} per un errore, nel - qual caso \var{errno} assumerà i valori \errval{EINVAL} o \errval{ENOMEM} - nel loro significato generico.} -\end{funcproto} - -La funzione ritorna l'indirizzo di una stringa contente la descrizione -testuale del contenuto del \textit{capability state} \param{caps} passato come -argomento, e, qualora l'argomento \param{length\_p} sia diverso da \val{NULL}, -restituisce come \textit{value result argument} nella variabile intera da -questo puntata la lunghezza della stringa. La stringa restituita viene -allocata automaticamente dalla funzione e pertanto dovrà essere liberata con -\func{cap\_free}. - -La rappresentazione testuale, che viene usata anche dai programmi di gestione a -riga di comando, prevede che lo stato venga rappresentato con una stringa di -testo composta da una serie di proposizioni separate da spazi, ciascuna delle -quali specifica una operazione da eseguire per creare lo stato finale. Nella -rappresentazione si fa sempre conto di partire da uno stato in cui tutti gli -insiemi sono vuoti e si provvede a impostarne i contenuti. - -Ciascuna proposizione è nella forma di un elenco di capacità, espresso con i -nomi di tab.~\ref{tab:proc_capabilities} separati da virgole, seguito da un -operatore, e dall'indicazione degli insiemi a cui l'operazione si applica. I -nomi delle capacità possono essere scritti sia maiuscoli che minuscoli, viene -inoltre riconosciuto il nome speciale \texttt{all} che è equivalente a -scrivere la lista completa. Gli insiemi sono identificati dalle tre lettere -iniziali: ``\texttt{p}'' per il \textit{permitted}, ``\texttt{i}'' per -l'\textit{inheritable} ed ``\texttt{e}'' per l'\textit{effective} che devono -essere sempre minuscole, e se ne può indicare più di uno. - -Gli operatori possibili sono solo tre: ``\texttt{+}'' che aggiunge le capacità -elencate agli insiemi indicati, ``\texttt{-}'' che le toglie e ``\texttt{=}'' -che le assegna esattamente. I primi due richiedono che sia sempre indicato sia -un elenco di capacità che gli insiemi a cui esse devono applicarsi, e -rispettivamente attiveranno o disattiveranno le capacità elencate nell'insieme -o negli insiemi specificati, ignorando tutto il resto. I due operatori possono -anche essere combinati nella stessa proposizione, per aggiungere e togliere le -capacità dell'elenco da insiemi diversi. - -L'assegnazione si applica invece su tutti gli insiemi allo stesso tempo, -pertanto l'uso di ``\texttt{=}'' è equivalente alla cancellazione preventiva -di tutte le capacità ed alla impostazione di quelle elencate negli insiemi -specificati, questo significa che in genere lo si usa una sola volta -all'inizio della stringa. In tal caso l'elenco delle capacità può non essere -indicato e viene assunto che si stia facendo riferimento a tutte quante senza -doverlo scrivere esplicitamente. - -Come esempi avremo allora che un processo non privilegiato di un utente, che -non ha nessuna capacità attiva, avrà una rappresentazione nella forma -``\texttt{=}'' che corrisponde al fatto che nessuna capacità viene assegnata a -nessun insieme (vale la cancellazione preventiva), mentre un processo con -privilegi di amministratore avrà una rappresentazione nella forma -``\texttt{=ep}'' in cui tutte le capacità vengono assegnate agli insiemi -\textit{permitted} ed \textit{effective} (e l'\textit{inheritable} è ignorato -in quanto per le regole viste a pag.~\ref{sec:capability-uid-transition} le -capacità verranno comunque attivate attraverso una \func{exec}). Infine, come -esempio meno banale dei precedenti, otterremo per \texttt{init} una -rappresentazione nella forma ``\texttt{=ep cap\_setpcap-e}'' dato che come -accennato tradizionalmente \const{CAP\_SETPCAP} è sempre stata rimossa da -detto processo. - -Viceversa per ottenere un \textit{capability state} dalla sua rappresentazione -testuale si può usare la funzione \funcd{cap\_from\_text}, il cui prototipo è: - -\begin{funcproto}{ -\fhead{sys/capability.h} -\fdecl{cap\_t cap\_from\_text(const char *string)} -\fdesc{Crea un \textit{capability state} dalla sua rappresentazione testuale.} -} - -{La funzione ritorna un \textit{capability state} in caso di successo e - \val{NULL} per un errore, nel qual caso \var{errno} assumerà i valori - \errval{EINVAL} o \errval{ENOMEM} nel loro significato generico.} -\end{funcproto} - - -La funzione restituisce il puntatore ad un \textit{capability state} -inizializzato con i valori indicati nella stringa \param{string} che ne -contiene la rappresentazione testuale. La memoria per il \textit{capability - state} viene allocata automaticamente dalla funzione e dovrà essere liberata -con \func{cap\_free}. - -Alle due funzioni citate se ne aggiungono altre due che consentono di -convertire i valori delle costanti di tab.~\ref{tab:proc_capabilities} nelle -stringhe usate nelle rispettive rappresentazioni e viceversa. Le due funzioni, -\funcd{cap\_to\_name} e \funcd{cap\_from\_name}, sono estensioni specifiche di -Linux ed i rispettivi prototipi sono: - -\begin{funcproto}{ -\fhead{sys/capability.h} -\fdecl{char *cap\_to\_name(cap\_value\_t cap)} -\fdesc{Converte il valore numerico di una \textit{capabilities} alla sua - rappresentazione testuale.} -\fdecl{int cap\_from\_name(const char *name, cap\_value\_t *cap\_p)} - -\fdesc{Converte la rappresentazione testuale di una \textit{capabilities} al - suo valore numerico.} -} - -{La funzione \func{cap\_to\_name} ritorna un puntatore ad una stringa in caso - di successo e \val{NULL} per un errore, mentre \func{cap\_to\_name} ritorna - $0$ in caso di successo e $-1$ per un errore, per entrambe in caso di errore - \var{errno} assumerà i valori \errval{EINVAL} o \errval{ENOMEM} nel loro - significato generico. -} -\end{funcproto} - -La prima funzione restituisce la stringa (allocata automaticamente e che dovrà -essere liberata con \func{cap\_free}) che corrisponde al valore della -capacità \param{cap}, mentre la seconda restituisce nella variabile puntata -da \param{cap\_p}, come \textit{value result argument}, il valore della -capacità rappresentata dalla stringa \param{name}. - -Fin quei abbiamo trattato solo le funzioni di servizio relative alla -manipolazione dei \textit{capability state} come strutture di dati; -l'interfaccia di gestione prevede però anche le funzioni per trattare le -\textit{capabilities} presenti nei processi. La prima di queste funzioni è -\funcd{cap\_get\_proc} che consente la lettura delle \textit{capabilities} del -processo corrente, il suo prototipo è: - -\begin{funcproto}{ -\fhead{sys/capability.h} -\fdecl{cap\_t cap\_get\_proc(void)} -\fdesc{Legge le \textit{capabilities} del processo corrente.} -} - -{La funzione ritorna un \textit{capability state} in caso di successo e - \val{NULL} per un errore, nel qual caso \var{errno} assumerà i valori - \errval{EINVAL}, \errval{EPERM} o \errval{ENOMEM} nel loro significato - generico.} -\end{funcproto} - -La funzione legge il valore delle \textit{capabilities} associate al processo -da cui viene invocata, restituendo il risultato tramite il puntatore ad un -\textit{capability state} contenente tutti i dati che provvede ad allocare -autonomamente e che di nuovo occorrerà liberare con \func{cap\_free} quando -non sarà più utilizzato. - -Se invece si vogliono leggere le \textit{capabilities} di un processo -specifico occorre usare la funzione \funcd{cap\_get\_pid}, il cui -prototipo\footnote{su alcune pagine di manuale la funzione è descritta con un - prototipo sbagliato, che prevede un valore di ritorno di tipo \type{cap\_t}, - ma il valore di ritorno è intero, come si può verificare anche dalla - dichiarazione della stessa in \headfile{sys/capability.h}.} è: - -\begin{funcproto}{ -\fhead{sys/capability.h} -\fdecl{cap\_t cap\_get\_pid(pid\_t pid)} -\fdesc{Legge le \textit{capabilities} di un processo.} -} - -{La funzione ritorna un \textit{capability state} in caso di successo e - \val{NULL} per un errore, nel qual caso \var{errno} assumerà i valori - \errval{ESRCH} o \errval{ENOMEM} nel loro significato generico. } -\end{funcproto} - -La funzione legge il valore delle \textit{capabilities} del processo indicato -con l'argomento \param{pid}, e restituisce il risultato tramite il puntatore -ad un \textit{capability state} contenente tutti i dati che provvede ad -allocare autonomamente e che al solito deve essere disallocato con -\func{cap\_free}. Qualora il processo indicato non esista si avrà un errore di -\errval{ESRCH}. Gli stessi valori possono essere letti direttamente nel -filesystem \textit{proc}, nei file \texttt{/proc//status}; ad esempio per -\texttt{init} si otterrà qualcosa del tipo: -\begin{Console} -piccardi@hain:~/gapil$ \textbf{cat /proc/1/status} -... -CapInh: 0000000000000000 -CapPrm: 00000000fffffeff -CapEff: 00000000fffffeff -... -\end{Console} -%$ - -\itindend{capability~state} - -Infine per impostare le \textit{capabilities} del processo corrente (nella -bozza dello standard POSIX.1e non esiste una funzione che permetta di cambiare -le \textit{capabilities} di un altro processo) si deve usare la funzione -\funcd{cap\_set\_proc}, il cui prototipo è: - -\begin{funcproto}{ -\fhead{sys/capability.h} -\fdecl{int cap\_set\_proc(cap\_t cap\_p)} -\fdesc{Imposta le \textit{capabilities} del processo corrente.} -} - -{La funzione ritorna $0$ in caso di successo e $-1$ per un errore, nel qual - caso \var{errno} assumerà i valori: - \begin{errlist} - \item[\errcode{EPERM}] si è cercato di attivare una capacità non permessa. - \end{errlist} ed inoltre \errval{EINVAL} nel suo significato generico.} -\end{funcproto} - -La funzione modifica le \textit{capabilities} del processo corrente secondo -quanto specificato con l'argomento \param{cap\_p}, posto che questo sia -possibile nei termini spiegati in precedenza (non sarà ad esempio possibile -impostare capacità non presenti nell'insieme di quelle permesse). - -In caso di successo i nuovi valori saranno effettivi al ritorno della -funzione, in caso di fallimento invece lo stato delle capacità resterà -invariato. Si tenga presente che \textsl{tutte} le capacità specificate -tramite \param{cap\_p} devono essere permesse; se anche una sola non lo è la -funzione fallirà, e per quanto appena detto, lo stato delle -\textit{capabilities} non verrà modificato (neanche per le parti eventualmente -permesse). - -Oltre a queste funzioni su Linux sono presenti due ulteriori funzioni, -\funcm{capgetp} e \funcm{capsetp}, che svolgono un compito analogo. Queste -funzioni risalgono alla implementazione iniziale delle \textit{capabilities} -ed in particolare \funcm{capsetp} consentirebbe anche, come possibile in quel -caso, di cambiare le capacità di un altro processo. Le due funzioni oggi sono -deprecate e pertanto eviteremo di trattarle, per chi fosse interessato si -rimanda alla lettura della loro pagina di manuale. - -Come esempio di utilizzo di queste funzioni nei sorgenti allegati alla guida -si è distribuito il programma \texttt{getcap.c}, che consente di leggere le -\textit{capabilities} del processo corrente\footnote{vale a dire di sé stesso, - quando lo si lancia, il che può sembrare inutile, ma serve a mostrarci quali - sono le \textit{capabilities} standard che ottiene un processo lanciato - dalla riga di comando.} o tramite l'opzione \texttt{-p}, quelle di un -processo qualunque il cui \ids{PID} viene passato come parametro dell'opzione. - -\begin{figure}[!htbp] - \footnotesize \centering - \begin{minipage}[c]{\codesamplewidth} - \includecodesample{listati/getcap.c} - \end{minipage} - \normalsize - \caption{Corpo principale del programma \texttt{getcap.c}.} - \label{fig:proc_getcap} -\end{figure} - -La sezione principale del programma è riportata in fig.~\ref{fig:proc_getcap}, -e si basa su una condizione sulla variabile \var{pid} che se si è usato -l'opzione \texttt{-p} è impostata (nella sezione di gestione delle opzioni, -che si è tralasciata) al valore del \ids{PID} del processo di cui si vuole -leggere le \textit{capabilities} e nulla altrimenti. Nel primo caso -(\texttt{\small 1-6}) si utilizza (\texttt{\small 2}) \func{cap\_get\_proc} -per ottenere lo stato delle capacità del processo, nel secondo (\texttt{\small - 7-13}) si usa invece \func{cap\_get\_pid} (\texttt{\small 8}) per leggere -il valore delle capacità del processo indicato. - -Il passo successivo è utilizzare (\texttt{\small 15}) \func{cap\_to\_text} per -tradurre in una stringa lo stato, e poi (\texttt{\small 16}) stamparlo; infine -(\texttt{\small 18-19}) si libera la memoria allocata dalle precedenti -funzioni con \func{cap\_free} per poi ritornare dal ciclo principale della -funzione. - -\itindend{capabilities} - -% TODO vedi http://lwn.net/Articles/198557/ e -% http://www.madore.org/~david/linux/newcaps/ - - - \subsection{La gestione dei {chroot}} \label{sec:file_chroot} diff --git a/gapil.tex b/gapil.tex index 34d2f1b..9ac34e8 100644 --- a/gapil.tex +++ b/gapil.tex @@ -184,7 +184,7 @@ hyperfootnotes=false]{hyperref} % comment following to have reference to incomplete section using \unavref % command removed -%\def\incomplete{\relax} +\def\incomplete{\relax} \part{Programmazione di sistema} \label{part:progr-di-sist} diff --git a/img/dir_links.dia b/img/dir_links.dia index c378a1ae68eac7c5392f6230a2aa2ce279013b34..549ded66294df95e335df8d8555e7f8f74ae5cc3 100644 GIT binary patch literal 3189 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 bMsIO(chOwPf3qT*-(CC(x=H584f+58KkF2k literal 3069 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 Luh!z0h>89WFV3Cz literal 3836 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 diff --git a/img/disk_struct.dia b/img/disk_struct.dia index 977b794474db23dc6092ea39b3f3318a3aab995a..455cb358961de9bed531e71c94a1cd24dd7f4b80 100644 GIT binary patch literal 2480 zcmV;h2~YMPiwFP!000021MOW=bLuu0e$TJ)a9`#Q#~&7LNFfw2(jDj^<^#{BAscetrhYs$gZ7gCu?g z1t0&9B?%jgM&r@lmE-Jo5V4ZU_tx*SvdrVjW67PAE%@zd!lqwmdG?q_qpH=q-84(G z+<9Wj?dZ$H`Y{@>I~wox^h)nbHsh0=v#;%)L-7d1^EzMhyx#F*nH8~UQm&QsJL2vn)vdrFz!;0$;e|m6DWPa{ zPfj;C>DOG+uerQmb8&IM%w zdy0#AlJKSx#%ZZN=QiE1y6L_?OVm2D{d3J(S@qVsP(=avxOdJ%HG7OBUc52k_uI7e zG+#Fxzjfd1?KE#q6c@{ctzI8Oy-`bFEG=WfbFAP|M{LwarzueH_$pp6E>Ig##?B zd$^`N50GmYkUBmO?^Rp>lS#e%Tn;szCH%#NOFdykJb#Y@;A8Ka0D`^qZ1RLJ?x$Iv z9?I#?#-(hi1@Lfeo5jzqFMe3V)||()dD(6Zo!9py%Ojq@H4+G*S6j#3^Xy5m-Z%Jh zZ)3E10T^!)aW+JdE<_**t|9OZA_M{|00Mz00iy7so=xIIYf#6)Ll~&dDPr*vi)A3c z-&c1H`flR*D2r|1|gF0TZ51Q*arx;26YSwF>u5EhsEHL7?d8?u8%c* z47$1)B!&^_g75`_VL!_tF^fMBc>D14E&e_M{{G_M${hfrH2{hJB8UYfkWnQXPzgK; zLWHFl^|18agyDdm3B*#~j5nfZwKi=Zs@nG0YggMLSxoYlEs|Hl4sAi|EG?UC$@iTH zwuqCJxFnVqBc~`=(yZ9E7_haE>XK#Itn4n?FvTJ}w%fzpsUunmh92LRjr z#+eIRTF=fhQ~t2C{q5~2IE>8JI_-x1JYDj`!ecc{ei%TAw&drE#XA@f`7K#q#{U&J zom&nx&4JZqv>Z544#bz?Kwp;wed8SH?{grv95^Hnlr9>jh!BtNx@TrM(6<~oWDax< zb6|52it18eXgm-c?gWBS2yh>9sL*sIIJA){8;N=mB7t@!iU49*i69sF5V?1cbHuwlS|WsiBx^IrH5yXxTu!Xv{3^%9NRn}?SDI%Yq&7g>g27Xc!(jN}7~ zUKmN33kJhTmW}#hBj2*o$6zDWiI-@Wj?gA)Nb!*{7z{@u&9eo!q|^^79Zp5dO7EMM zTC(|Z7fzdN*lD9L=Uu8yV&lhMv<7ud{1^dyyyf$z4xy^cn$AzRG0@`k^bW%GdKO%dqS{Posk)xo?iI2~6nR?N1>< zrpvnZrZfGgbef3I`iOb0)4S5&?Q-hOt|L~=6Q0gqzwlS;HgunGTFbVA2lJrek5O}` z7VUa#pbgX7>8kRevtdxnJ$>OiDNu`7b+#IMp#rrR1cpIH6q9QQJ*4@f%?6H&uFh&&L48x|B|1EE23;O~|LjmP$>rNH4*AiNL*YUjYZ zs=`!gG-?yVs&tlD9Y_qqs(98gQeb5Y*i|8hl-X0+#!0Z6je%vsfeJxfZ>I|r5m zY>C0os-il&J$f?Cofc%I@xbprbNaJ0~+xyC0!ZgwWlPQ7Cl6P(w!8Dh1O@LC#0( zFAY~Igoc$u%a#~ML#QS-q zE^ws^5b8%3XpQQ)FDs$@CF%mJ6W*sz&`usC%HN_!ok%y_hy)KnG#G{O%b!;fFQ$3C zv}rRvXoPAeT8%JNjc}PNwm8r~M`Aj1;O&Ibd{q|3xJ2-P@z{ZXR(RJ+guW$$c3zq3 zK!OK|E0by08o>viFEuqCQqIiPBrX?hX;p&pl4e#T3|J!s7tsiAC&e7iY6M?ZDylR> zpmx%YYXq%9S&i_4G=hutbI(ny1R)1@RYCyJpj1MfW)Zh4p(m9P}ErBF_GEMHBR+T9;rQ=#2Ko=>s` zIZscRJnhWkg(~g3+Ub_aH;iZsP)LvhG(k%J%PPAP&t7Qy(4qepo@J#Hi|7xE==v&q zQjJ}7p(493?WAIgQ9xJ89vDzqMKq!7%VPMD4#80o-C*Y-PI$2@O1`+Dvl1LQD>r{k ulK4NnUhxO3oZ?!C<=uRPRP}ShRy@DEs(ujvXE|HkUHu`)(7+uTOIXd_1>hkk1-xjI&EQ&J8v%3)jaO8<> zn#V~tyBq!I&)S*Yc$)IDJZL<+zwx}?24Y@u_1XGUUR6ahd8&k$@rAe>P5AWdtjM3TcvK&?K5m+) zdEq_t^ltR!Q9nlGbu;6=cHU@v$!B6x2>!LZX(%62bWYPtQ8b%fEb}svhg7TO!66;( zsOOzy)<>1{plo*kX?aWs>W^R1b}DjbMH0Ua+`S_@T6sz0YX0!;t;+?08Uniyg9}*OTlHq|IVqD# zD%yIOWR>xF*fhVoO!LhzCLXH z-c@fNckG3!KWa?q+C<7%qF6Wo+jc7V);D;~N*<&=h+mgSUgPgB0H247wea{p$X=&ZyRzUO>)5ow&o(4 z&8u!>=)ATkc@c}^y`De-{RU5x^X!%L{Nn1O&3GK|`is2SJ3elA%6UUYj%=vNLZ*r7p%haf!w;T{l$+ zd-slO#Dy1=q9ZW;Mx>-GG?!;pn=SRZ_sADXx{{~FvvTB>)k?Yal4k3#{#~TcqDrQG zH}Y`$863d96_pfrI-utm-5-J7qYxuAJ5Bg^u0lX)W{9WBEL({7n<=uVMN3ret+-lS zXy`OVJnK_xVq$wLM}`olx#ZDlB`KynfY;_P-dvK>dTds?_Jh6cU++fYVa%)1=w+zS zH>Ex-JypBZhXI6WOMOI6+~I(zZ^?@)`LDd_!ZDz22CN68W57W&AifR*2Br)cSZBas zp8=U;z#%c9a?Th-l=^JfF|)&ffn&hoG9av{- zuuheN03oIVQCRzAH2C=BH108k_^F11cvPLQ2-cv91I^hF6xJi0>?$4fs4>Z{6o8B zgf>Y+nvJBva5(a4o-c%>q<$#ra40%X`pBHrk++X8;jR(O?izdD*-~c>Ti@7X)Tv{l z#t68LEZ=LIFuFjVuwBH}5}-yL)A14Oh;#eMzO#K~|4cH`1`axi2`M5_t(o}hRZU7T zh={VPUeB|v!m$q`i*-*<>R%g}(78*VQhrRAP3vuYqfcoxmG}CHac$DN*52J>>ddBN zUd~gI&E7uoH}=0@KEbq+Uj+}wLCcp>du|rH^pZdqrj656)rMxvpjPYn(rwb9malpb zHS{A5YCjAugZi+8?Wqh7*Pj&Ea37lZ6j&3>ux63k0f!fgVBJ6a6ZJnUTqw|%9suLp1I-z4J45J~`5{A3Agnca)$oW#? z_(iaTuC*KkO}c;0Rj>=q?%(sO*h!1sO^D;ZAdW8raoPvO=`O@+Ul6B9K%6>=f0q#V zO(4$t@%Aw>k9gwS;M^48BU3n)w;!nIpM0IdsS`PEI{QYQI;zyN^X)%m;c@enP0L_F zI-j`)1L+40mZ9MG4}91_*9B^E26FH)tIJ`Ch8hv1UJiq5Sxkar7=fze)p0*Y!uE^Ng-#`WOqF1q zG)T3##jLuJB-%&>A3!u1eenAqH?b(EMY41WGd(DTdL%l9FieGToocl>G~YX7J8IzX zgwO(A2F1ES@PYNXL2y=R*9nBa1%h!#ne8Bg4=7Pdv}=VB06$QQnhhyi=4O&q3%+z3 z!FmBRrw|6K5W=e{1agtWjdm46peqyA3L(^M=++g2QKy_j_(TeUAoHAa+ZsWNfnALd z0yHR%kYsr*oJQzLBQUqpFyJ4(xzg@Kg3W*TCbZ0gAy9Etz4H)3z;0EE=fTjQSMf>e zer&@!`_;qHZ95#Mj}%0-CR4bphldsTD92Et+fU9*k$*f<;_({|)wGPBjGXGt8 zV%R7$nE~~rWySAdbgWQwkif^8tCVARE!z)$QCB{jXD6ouZ22ezi1~f%l z`>Tq&3eSFId!u3S9-dWg5{Kwdisw!8-@chy7>a@do6JaDblB>4n=UFz$a5ki;$+01|MKH;GWb@_7vtIV;}tE) z)u5UVXQT1-;p5f+{_DSQ%++5${qpD0xcrm*^Dr+T2ksfuh5zm2)tBY+=}#X%eEbXe*L`qy85uX(TA-&9k}~b`B2@@tMZTTn-lkC z?P)iEs^;w*KR(SCV|U5&`Dy2pj{Eq(8`rF^TDXg*51)ShtN68kNvj7o_uBVDI|o@l zmh*@4bax#0?o8^pf)$1_=H3ozjU`%W`tqK?R)*Jyhyav$d7(P7|j zUD0uu(X;zG9)f-(-^Zinm%AT_J`z&+W!C(nvEw~w8}HkAF}|Nv`(`+vE~D4n%k7`j z+`hd^f*sjBJ#tmnck47%BU8yro?@sTzK%!L;>d#EzNX_&UsjiWIQG7`uZw(ZM&rfP zqI@Q5T&~%cq;=?54#ffFsTB|F0SX+lVi-@2{Crf>DOE z>C{cfZB=icW)7~4G(*02Db^3QcClepx5%pb>XrVs*}o1}Y_obLgVpOV8xNIkI^SM? zYpnPBgIlfR|5=vPQ8^zCZU+CVek`vV8}_Tgc=Yk=cd`wH_Pgiq<~9sFU=DBMYIkzY z3e`sE?mN|W^ZWbuz2|1^cg=|8cKP4|I?+_mkQO_%$|^p6idyA8zT*}b%Ky0{uFmd}2vn5)%O|5i=D zRm<_Py!ripGXD4W>VEqx`BIG^zU+N1P2(-%6wK&m2jh)$@-?cemhYyC*e>eHyEra+S%H5ve z)$xr990*xF2+g%91Skl#1EKIxycGp;Ae4oG24TdcUIRkj1|dTXzDIcQ6!4H4;32o* zVc_8*F9se5_pb<;w*f|^0gTB27`+CJg5T6dObP*W$$*h50Hc7tAP*Q7yr37rD0sjq zNG}Kh(^tT#G=NbV03+9c(f)6Ez$gR^0;UZZodPgA16*taE*TtrjbQni!P1c@Gtqgn zLR?Egw6KC+i$d3VGVR<7(vv*d=h+z(WMn5ncA1H>?ZtW?4eD{eDpW5T^(|^6? zrW5yZzrwtdm3h@#3B#merzYs8qq}lGpMCFM&n)uJcav)Ra3tGkTVJt59?x%{HsVG* zwAitUFaI<6;;_52C(Bt#Vh=X|`|(QeEXY02rK{(%?dOtR>09dsrP<+7l46S^KnG~WBQTRp_Mhit1aF#>{I~b67YrLS^$1!0s7%`>SAdnS2jf;%3 z>fC6t@o33`72CjyfW`_U1(C8_kb@*Z3TQOD#)=9B2VSsZz_9{ZZUE8JTd@j@){MC& z419jtxaGwOtJ6P(-BMa`qWz#mo$5opI{ULTz1>Uv>%jyNCV+sI@-`v^B+jH*VJro` zz}7Pf^g>llFI3%9Qb?jg!4daEWZ;*r`R(Bs_kxgLkY9lL#l-Ln0p^#E&3?2X&KB%i zgNBi;58}Epd>F~?6ns9#K*y1yW`#Tci}sI23dooYfU!-$2zbC4gbTuD2QD%RTtEX# zHDF8#D6IiwG5`i+N>~DBkL-^{OI&o=zd**6R6)3x`KkJVv;&XwB0$}n1JWq^JB#RV zXJw-1?|mPY?&7Fu5fJsA1}t#kTX~K$HAhiaP|s1eCmc1JeZ6-xL8>|vRqZZNn}lsOfFL7Lo`xDhF!h1~uT)+_-rmYAzZzGzn^8Wrr)&)VjkpYD@;yp!N_^vkx^a z5o$~h)HM7WoyD(F=+_`>_MnC*L5a#H6{mY8a|E9;?o%PY48-{KG?*oF=(OO z-U$>ow27eBJB88ei!60z1AW zrp6aLON}oPFWu7M{TirlG;E+IPsfJ1d7+_4L;pr3#!JEsc!POr8Xe}T&C_B&ZeEB) zMB*Ef7%wxk@WEi)3QMUcOGJ`p)#umU_-p(0`xly(Ozx}VKD8ky46 zk&Z)TDdNczwlrfPOA^@95@Gx)JwcTAfEh##B4!6MCIwtuf}|fHQ6vpWL>7>U21wvt7z*sdAV~TG z5}E`gSs+5TAR;qB1Ob8oVJQFt?4Xb>2W1Tr3J(!b2L(a$?m*I^zE>%_1u9SSzzv-V zQz3k-nbEZbUvnKcLz=Q4i0~iEr}3n4cgw4{|NC?}n=WRPa#^lr_hPNP|F7BC`PflK z2DLq>T80d>k%U`L;nnu5bt$Q05=Hl5qI(9I^Omhsk0wv%S;bcrgD)u7tS6SKbP9Ym zF%%d7jN;<1y@^bnbCf*;?sOKtQHI8#oW9|3yr+kUtZK_;zgZ`7X>UYYE5~_gS_yf zV8-|dSU-5tmy>Ys8SWU*!HgW4vA@h{&J)dwR_dw3@skAgqE)C^aT6qZ{>WKKgbDv3 zWJD`&Vkp(S==`xw0viG9X02c&YN_5DHar7t1fD-a*zCeaM~n9)ytR={YokK;1m4(4 zaASkAi@tz_CIJboZIMmevIYsy01|;RaMUI_l&}5u7fF|A)I3iE}e%S z)^Lx6Nq3k6%pA}OOH&jU<2k*J=O}ZYNViVXPSq_w1LJXcN93tX)esS)LBCSPd2hoB5&|(Rxh=-u;y|n!hrC z>M8>U;ak5V3K4~C6smX>8gLYD`V;Ux{RtTMCqNYD3|^*?qcP_T!HUro2|hV9zONB4 zv~|Do!ix9rpa17Wh+O`pj=5kwd`UxyWFm_IZF@DMPyW8U7j^Mcv>MD@-zZQ?ixO^x znv!h6l~1npgOD68R6jmEKG)e4WTrgKw7njYmIgg+s-|rsjjGC_QB@7GorEsd5;rjv z+g-Ab$fOe6sT^WEwb2oQqegg6*L!&A-wgntD5*#&XTlxYLp2oK1uq#a^I{`?i(I86c{yVTKWQ#ByH|^ zmZn{Nt7#X{(X@+WmIYC>2Q?;zY2jHqN${;s5_Xf~a{LYAiw1 zf~EyQau_5ujcH+7OiME$#&QJ2I0nQJHG5FQ(wG*O#k8=kR>L}nX~BRPg2eI^riH+^ zQdpT5QWyDL=UO+fSycYa$+^ z3X_H^AOnHUKp3IwF1oD674D4(=L&X+3E0sqNFk9ckSjJNP)P(=&@)nnO(UW;pta+S z;WRW%G;O9Z&`hy4wcSfZ!H!osTRiA!*n`fU*TKl!bn)qRkc( zo-M>dAEagrahNSAvIVlmhAmhOTZnVAMVg*h64ndhnv+nU#?i#B^gE22EC?uBv}d+2 z8gc9j^g)m*noOa4>Vr^{s_+PGY*Ps$R2Zhk6dar>#L?KMI2PN~$Q8&H8?K1)K@{|^ zVt=ZTl4$J~Db%$Abw7x&8sWy^#`zv0QE0p#1u{_>HL2GXx=)nMd*`Xc^%rRA`%?Pv zOKLztiAVuVn*o+~4NF@HDl{}M?d717TdS5-5UhrE4%+|Mv=v6kJUc zH7hidxshq4|Gq3_suaj{NMYd6bc4_)HWfTJPoEcpGdDOZ>Ax?kc@rh^^14E}4JK>| z%8x*lN2dRmwtZ-;oVP2=uysESu@h#s>!!%IUbfbzs)A29KS6l73t44+K0A(_N{!4b$@Qq-hgmr9bYT#ErrB~i@k zzVECqjjt!CfKf;kSd?eg~wsctPq9>!!8(hogtti-W+OhbI266B2>91lHa-! z-H&jHK%S^*_e$%#YC1Z4j9_PW`%UNR1-RYzXZX~90UJ8Fl#>T6!^wj*Wbl@g2d9mA z(#ZqAaqT)i(EV(>dbZ))Pgbdq9(3|cd~rV&Q(x$HmYzGS$c3*PMyO`SGH>rWQEF9$ z37BMdr?}@D$1v9fIR-ffl4E!T$5;u>F9*Z$+hyvryA~tn-+HPCNKiVlkl-bmsq_Dh4n3BbTYsLKl%=5>ve2{-2S^OD zdFkozQ|I9=W|MMRu31W$GaMq}RLf8a#7M#|rz`_Wg%v5OViJ#%fKe37Shm`v4qtQ; zA|t5?5qPV{L>Ps?@S&FBchV0!q=qo$!@PV*kq>*zhwakb`S_5g;X?}DY%uU4E$kK_ zx@}@l_|WkI@?lOsbSnh;u)lmr&&7u<6(5Qm4zn9;+hKM@*$+mvLLedLB}9&d*k3|q z=ORQNpYZ3f1=3YPM5vBV0~e}7`n{nj4EoAQg?rYbC@eBzZ<$b^%~cjjm=LxC{E7?3 zDv`40!k(m280QkXFe?{g8l}fvcs4g#Cg4Jcbr$%L3$8&qaW#}I7_(g8HpUi)8jaEy zl)iMYN7TOb^6WW_FJ%lYko6~ESkT{v5{1qTdxb26En^I;kM)NJlXRqc5As;q;vf#M zT>V^57I_rpELuU%!4GoqLh2WMuo^7j0O8OlIsEyvB*&WG6GXI-L>i*rCqnAqC*^ZB Z|MW}!i~I91FCRbs^8ehEN`mS10RSLSjFSKW literal 5448 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 diff --git a/procadv.tex b/procadv.tex index 4b83f8e..98d4031 100644 --- a/procadv.tex +++ b/procadv.tex @@ -721,6 +721,1307 @@ funzionalità di \textit{Secure Computing}, fino alle funzionalità relative alla gestione delle chiavi crittografiche. + +\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 (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 misure potranno essere comunque +rimosse (nei casi elencati nella precedente nota si potrà sempre rimontare il +sistema in lettura-scrittura, o togliere l'attributo 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 risolvere questo problema sono possibili varie soluzioni ed ad esempio dai +kernel 2.5 è stata introdotta la struttura dei +\itindex{Linux~Security~Modules} \textit{Linux Security Modules} che han +permesso di aggiungere varie forme di \itindex{Mandatory~Access~Control~(DAC)} +\textit{Mandatory Access Control} (MAC), in cui si potessero parcellizzare e +controllare nei minimi dettagli tutti i privilegi e le modalità in cui questi +possono essere usati dai programmi e trasferiti agli utenti, con la creazione +di varie estensioni (come \textit{SELinux}, \textit{Smack}, \textit{Tomoyo}, +\textit{AppArmor}) che consentono di superare l'architettura tradizionale dei +permessi basati sul modello classico del controllo di accesso chiamato +\itindex{Discrectionary~Access~Control~(DAC)} \textit{Discrectionary Access + Control} (DAC). + +Ma già in precedenza, a partire dai kernel della serie 2.2, era 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 situazione +originaria di ``\textsl{tutto o nulla}''. + +\itindbeg{file~capabilities} + +Il meccanismo completo delle \textit{capabilities} (l'implementazione si rifà +ad una bozza di quello che doveva diventare lo standard POSIX.1e, poi +abbandonato) prevede inoltre la possibilità di associare le stesse ai singoli +file eseguibili, in modo da poter stabilire quali capacità possono essere +utilizzate quando viene messo in esecuzione uno specifico programma; ma il +supporto per questa funzionalità, chiamata \textit{file capabilities}, è stato +introdotto soltanto a partire dal kernel 2.6.24. Fino ad allora doveva essere +il programma stesso ad eseguire una riduzione esplicita delle sue capacità, +cosa che ha reso l'uso di questa funzionalità poco diffuso, vista la presenza +di meccanismi alternativi per ottenere limitazioni delle capacità +dell'amministratore a livello di sistema operativo, come \textit{SELinux}. + +Con questo supporto e con le ulteriori modifiche introdotte con il kernel +2.6.25 il meccanismo delle \textit{capabilities} è stato totalmente +rivoluzionato, rendendolo più aderente alle intenzioni originali dello +standard POSIX, rimuovendo il significato che fino ad allora aveva avuto la +capacità \const{CAP\_SETPCAP} e cambiando le modalità di funzionamento del +cosiddetto \textit{capabilities bounding set}. Ulteriori modifiche sono state +apportate con il kernel 2.6.26 per consentire la rimozione non ripristinabile +dei privilegi di amministratore. Questo fa sì che il significato ed il +comportamento del kernel finisca per dipendere dalla versione dello stesso e +dal fatto che le nuove \textit{file capabilities} siano abilitate o meno. Per +capire meglio la situazione e cosa è cambiato conviene allora spiegare con +maggiori dettagli come funziona il meccanismo delle \textit{capabilities}. + +Il primo passo per frazionare i privilegi garantiti all'amministratore, +supportato fin dalla introduzione iniziale del kernel 2.2, è stato quello in +cui a ciascun processo sono stati associati tre distinti insiemi di +\textit{capabilities}, denominati rispettivamente \textit{permitted}, +\textit{inheritable} ed \textit{effective}. Questi insiemi vengono mantenuti +in forma di tre diverse maschere binarie,\footnote{il kernel li mantiene, come + i vari identificatori di sez.~\ref{sec:proc_setuid}, all'interno della + \texttt{task\_struct} di ciascun processo (vedi + fig.~\ref{fig:proc_task_struct}), nei tre campi \texttt{cap\_effective}, + \texttt{cap\_inheritable}, \texttt{cap\_permitted} del tipo + \texttt{kernel\_cap\_t}; questo era, fino al kernel 2.6.25 definito come + intero a 32 bit per un massimo di 32 \textit{capabilities} distinte, + attualmente è stato aggiornato ad un vettore in grado di mantenerne fino a + 64.} in cui ciascun bit corrisponde ad una capacità diversa. + +L'utilizzo di tre distinti insiemi serve a fornire una interfaccia flessibile +per l'uso delle \textit{capabilities}, con scopi analoghi a quelli per cui +sono mantenuti i diversi insiemi di identificatori di +sez.~\ref{sec:proc_setuid}; il loro significato, che è rimasto sostanzialmente +lo stesso anche dopo le modifiche seguite alla introduzione delle +\textit{file capabilities} è il seguente: +\begin{basedescript}{\desclabelwidth{2.1cm}\desclabelstyle{\nextlinelabel}} +\item[\textit{permitted}] l'insieme delle \textit{capabilities} + ``\textsl{permesse}'', cioè l'insieme di quelle capacità che un processo + \textsl{può} impostare come \textsl{effettive} o come + \textsl{ereditabili}. Se un processo cancella una capacità da questo insieme + non potrà più riassumerla.\footnote{questo nei casi ordinari, sono + previste però una serie di eccezioni, dipendenti anche dal tipo di + supporto, che vedremo meglio in seguito dato il notevole intreccio nella + casistica.} +\item[\textit{inheritable}] l'insieme delle \textit{capabilities} + ``\textsl{ereditabili}'', cioè di quelle che verranno trasmesse come insieme + delle \textsl{permesse} ad un nuovo programma eseguito attraverso una + chiamata ad \func{exec}. +\item[\textit{effective}] l'insieme delle \textit{capabilities} + ``\textsl{effettive}'', cioè di quelle che vengono effettivamente usate dal + kernel quando deve eseguire il controllo di accesso per le varie operazioni + compiute dal processo. +\label{sec:capabilities_set} +\end{basedescript} + +Con l'introduzione delle \textit{file capabilities} sono stati introdotti +altri tre insiemi associabili a ciascun file.\footnote{la realizzazione viene + eseguita con l'uso di uno specifico attributo esteso, + \texttt{security.capability}, la cui modifica è riservata, (come illustrato + in sez.~\ref{sec:file_xattr}) ai processi dotato della capacità + \const{CAP\_SYS\_ADMIN}.} Le \textit{file capabilities} hanno effetto +soltanto quando il file che le porta viene eseguito come programma con una +\func{exec}, e forniscono un meccanismo che consente l'esecuzione dello stesso +con maggiori privilegi; in sostanza sono una sorta di estensione del +\acr{suid} bit limitato ai privilegi di amministratore. Anche questi tre +insiemi sono identificati con gli stessi nomi di quello dei processi, ma il +loro significato è diverso: +\begin{basedescript}{\desclabelwidth{2.1cm}\desclabelstyle{\nextlinelabel}} +\item[\textit{permitted}] (chiamato originariamente \textit{forced}) l'insieme + delle capacità che con l'esecuzione del programma verranno aggiunte alle + capacità \textsl{permesse} del processo. +\item[\textit{inheritable}] (chiamato originariamente \textit{allowed}) + l'insieme delle capacità che con l'esecuzione del programma possono essere + ereditate dal processo originario (che cioè non vengono tolte + dall'\textit{inheritable set} del processo originale all'esecuzione di + \func{exec}). +\item[\textit{effective}] in questo caso non si tratta di un insieme ma di un + unico valore logico; se attivo all'esecuzione del programma tutte le + capacità che risulterebbero \textsl{permesse} verranno pure attivate, + inserendole automaticamente nelle \textsl{effettive}, se disattivato nessuna + capacità verrà attivata (cioè l'\textit{effective set} resterà vuoto). +\end{basedescript} + +\itindbeg{capabilities~bounding~set} + +Infine come accennato, esiste un ulteriore insieme, chiamato +\textit{capabilities bounding set}, il cui scopo è quello di costituire un +limite alle capacità che possono essere attivate per un programma. Il suo +funzionamento però è stato notevolmente modificato con l'introduzione delle +\textit{file capabilities} e si deve pertanto prendere in considerazione una +casistica assai complessa. + +Per i kernel fino al 2.6.25, o se non si attiva il supporto per le +\textit{file capabilities}, il \textit{capabilities bounding set} è un +parametro generale di sistema, il cui valore viene riportato nel file +\sysctlfiled{kernel/cap-bound}. Il suo valore iniziale è definito in sede di +compilazione del kernel, e da sempre ha previsto come default la presenza di +tutte le \textit{capabilities} eccetto \const{CAP\_SETPCAP}. In questa +situazione solo il primo processo eseguito nel sistema (quello con +\textsl{pid} 1, di norma \texttt{/sbin/init}) ha la possibilità di +modificarlo; ogni processo eseguito successivamente, se dotato dei privilegi +di amministratore, è in grado soltanto di rimuovere una delle +\textit{capabilities} già presenti dell'insieme.\footnote{per essere precisi + occorre la capacità \const{CAP\_SYS\_MODULE}.} + +In questo caso l'effetto complessivo del \textit{capabilities bounding set} è +che solo le capacità in esso presenti possono essere trasmesse ad un altro +programma attraverso una \func{exec}. Questo in sostanza significa che se un +qualunque programma elimina da esso una capacità, considerato che +\texttt{init} (almeno nelle versioni ordinarie) non supporta la reimpostazione +del \textit{bounding set}, questa non sarà più disponibile per nessun processo +a meno di un riavvio, eliminando così in forma definitiva quella capacità per +tutti, compreso l'amministratore.\footnote{la qual cosa, visto il default + usato per il \textit{capabilities bounding set}, significa anche che + \const{CAP\_SETPCAP} non è stata praticamente mai usata nella sua forma + originale.} + +Con il kernel 2.6.25 e le \textit{file capabilities} il \textit{bounding set} +è diventato una proprietà di ciascun processo, che viene propagata invariata +sia attraverso una \func{fork} che una \func{exec}. In questo caso il file +\sysctlfile{kernel/cap-bound} non esiste e \texttt{init} non ha nessun +ruolo speciale, inoltre in questo caso all'avvio il valore iniziale prevede la +presenza di tutte le capacità (compresa \const{CAP\_SETPCAP}). + +Con questo nuovo meccanismo il \textit{bounding set} continua a ricoprire un +ruolo analogo al precedente nel passaggio attraverso una \func{exec}, come +limite alle capacità che possono essere aggiunte al processo in quanto +presenti nel \textit{permitted set} del programma messo in esecuzione, in +sostanza il nuovo programma eseguito potrà ricevere una capacità presente nel +suo \textit{permitted set} (quello del file) solo se questa è anche nel +\textit{bounding set} (del processo). In questo modo si possono rimuovere +definitivamente certe capacità da un processo, anche qualora questo dovesse +eseguire un programma privilegiato che prevede di riassegnarle. + +Si tenga presente però che in questo caso il \textit{bounding set} blocca +esclusivamente le capacità indicate nel \textit{permitted set} del programma +che verrebbero attivate in caso di esecuzione, e non quelle eventualmente già +presenti nell'\textit{inheritable set} del processo (ad esempio perché +presenti prima di averle rimosse dal \textit{bounding set}). In questo caso +eseguendo un programma che abbia anche lui dette capacità nel suo +\textit{inheritable set} queste verrebbero assegnate. + +In questa seconda versione inoltre il \textit{bounding set} costituisce anche +un limite per le capacità che possono essere aggiunte all'\textit{inheritable + set} del processo stesso con \func{capset}, sempre nel senso che queste +devono essere presenti nel \textit{bounding set} oltre che nel +\textit{permitted set} del processo. Questo limite vale anche per processi con +i privilegi di amministratore,\footnote{si tratta sempre di avere la + \textit{capability} \const{CAP\_SETPCAP}.} per i quali invece non vale la +condizione che le \textit{capabilities} da aggiungere nell'\textit{inheritable + set} debbano essere presenti nel proprio \textit{permitted set}.\footnote{lo + scopo anche in questo caso è ottenere una rimozione definitiva della + possibilità di passare una capacità rimossa dal \textit{bounding set}.} + +Come si può notare per fare ricorso alle \textit{capabilities} occorre +comunque farsi carico di una notevole complessità di gestione, aggravata dalla +presenza di una radicale modifica del loro funzionamento con l'introduzione +delle \textit{file capabilities}. Considerato che il meccanismo originale era +incompleto e decisamente problematico nel caso di programmi che non ne +sapessero tener conto,\footnote{c'è stato un grosso problema di sicurezza con + \texttt{sendmail}, riuscendo a rimuovere \const{CAP\_SETGID} + dall'\textit{inheritable set} di un processo si ottenne di far fallire + \func{setuid} in maniera inaspettata per il programma (che aspettandosi + sempre il successo della funzione non ne controllava lo stato di uscita) con + la conseguenza di effettuare come amministratore operazioni che altrimenti + sarebbero state eseguite, senza poter apportare danni, da utente normale.} +ci soffermeremo solo sulla implementazione completa presente a partire dal +kernel 2.6.25, tralasciando ulteriori dettagli riguardo la versione +precedente. + +Riassumendo le regole finora illustrate tutte le \textit{capabilities} vengono +ereditate senza modifiche attraverso una \func{fork} mentre, indicati con +\texttt{orig\_*} i valori degli insiemi del processo chiamante, con +\texttt{file\_*} quelli del file eseguito e con \texttt{bound\_set} il +\textit{capabilities bounding set}, dopo l'invocazione di \func{exec} il +processo otterrà dei nuovi insiemi di capacità \texttt{new\_*} secondo la +formula espressa dal seguente pseudo-codice C: + +\includecodesnip{listati/cap-results.c} + +% \begin{figure}[!htbp] +% \footnotesize \centering +% \begin{minipage}[c]{12cm} +% \includecodesnip{listati/cap-results.c} +% \end{minipage} +% \caption{Espressione della modifica delle \textit{capabilities} attraverso +% una \func{exec}.} +% \label{fig:cap_across_exec} +% \end{figure} + +\noindent e si noti come in particolare il \textit{capabilities bounding set} +non venga comunque modificato e resti lo stesso sia attraverso una \func{fork} +che attraverso una \func{exec}. + + +\itindend{capabilities~bounding~set} + +A queste regole se ne aggiungono delle altre che servono a riprodurre il +comportamento tradizionale di un sistema unix-like in tutta una serie di +circostanze. La prima di queste è relativa a quello che avviene quando si +esegue un file senza \textit{capabilities}; se infatti si considerasse questo +equivalente al non averne assegnata alcuna, non essendo presenti capacità né +nel \textit{permitted set} né nell'\textit{inheritable set} del file, +nell'esecuzione di un qualunque programma l'amministratore perderebbe tutti i +privilegi originali dal processo. + +Per questo motivo se un programma senza \textit{capabilities} assegnate viene +eseguito da un processo con \ids{UID} reale 0, esso verrà trattato come +se tanto il \textit{permitted set} che l'\textit{inheritable set} fossero con +tutte le \textit{capabilities} abilitate, con l'\textit{effective set} attivo, +col risultato di fornire comunque al processo tutte le capacità presenti nel +proprio \textit{bounding set}. Lo stesso avviene quando l'eseguibile ha attivo +il \acr{suid} bit ed appartiene all'amministratore, in entrambi i casi si +riesce così a riottenere il comportamento classico di un sistema unix-like. + +Una seconda circostanza è quella relativa a cosa succede alle +\textit{capabilities} di un processo nelle possibili transizioni da \ids{UID} +nullo a \ids{UID} non nullo o viceversa (corrispondenti rispettivamente a +cedere o riottenere i i privilegi di amministratore) che si possono effettuare +con le varie funzioni viste in sez.~\ref{sec:proc_setuid}. In questo caso la +casistica è di nuovo alquanto complessa, considerata anche la presenza dei +diversi gruppi di identificatori illustrati in tab.~\ref{tab:proc_uid_gid}, si +avrà allora che: +\begin{enumerate*} +\item se si passa da \ids{UID} effettivo nullo a non nullo + l'\textit{effective set} del processo viene totalmente azzerato, se + viceversa si passa da \ids{UID} effettivo non nullo a nullo il + \textit{permitted set} viene copiato nell'\textit{effective set}; +\item se si passa da \textit{file system} \ids{UID} nullo a non nullo verranno + cancellate dall'\textit{effective set} del processo tutte le capacità + attinenti i file, e cioè \const{CAP\_LINUX\_IMMUTABLE}, \const{CAP\_MKNOD}, + \const{CAP\_DAC\_OVERRIDE}, \const{CAP\_DAC\_READ\_SEARCH}, + \const{CAP\_MAC\_OVERRIDE}, \const{CAP\_CHOWN}, \const{CAP\_FSETID} e + \const{CAP\_FOWNER} (le prime due a partire dal kernel 2.2.30), nella + transizione inversa verranno invece inserite nell'\textit{effective set} + quelle capacità della precedente lista che sono presenti nel suo + \textit{permitted set}. +\item se come risultato di una transizione riguardante gli identificativi dei + gruppi \textit{real}, \textit{saved} ed \textit{effective} in cui si passa + da una situazione in cui uno di questi era nullo ad una in cui sono tutti + non nulli,\footnote{in sostanza questo è il caso di quando si chiama + \func{setuid} per rimuovere definitivamente i privilegi di amministratore + da un processo.} verranno azzerati completamente sia il \textit{permitted + set} che l'\textit{effective set}. +\end{enumerate*} +\label{sec:capability-uid-transition} + +La combinazione di tutte queste regole consente di riprodurre il comportamento +ordinario di un sistema di tipo Unix tradizionale, ma può risultare +problematica qualora si voglia passare ad una configurazione di sistema +totalmente basata sull'applicazione delle \textit{capabilities}; in tal caso +infatti basta ad esempio eseguire un programma con \acr{suid} bit di proprietà +dell'amministratore per far riottenere ad un processo tutte le capacità +presenti nel suo \textit{bounding set}, anche se si era avuta la cura di +cancellarle dal \textit{permitted set}. + +\itindbeg{securebits} + +Per questo motivo a partire dal kernel 2.6.26, se le \textit{file + capabilities} sono abilitate, ad ogni processo viene stata associata una +ulteriore maschera binaria, chiamata \textit{securebits flags}, su cui sono +mantenuti una serie di flag (vedi tab.~\ref{tab:securebits_values}) il cui +valore consente di modificare queste regole speciali che si applicano ai +processi con \ids{UID} nullo. La maschera viene sempre mantenuta +attraverso una \func{fork}, mentre attraverso una \func{exec} viene sempre +cancellato il flag \const{SECURE\_KEEP\_CAPS}. + +\begin{table}[htb] + \centering + \footnotesize + \begin{tabular}{|l|p{10cm}|} + \hline + \textbf{Flag} & \textbf{Descrizione} \\ + \hline + \hline + \constd{SECURE\_KEEP\_CAPS}&Il processo non subisce la cancellazione delle + sue \textit{capabilities} quando tutti i suoi + \ids{UID} passano ad un valore non + nullo (regola di compatibilità per il cambio + di \ids{UID} n.~3 del precedente + elenco), sostituisce il precedente uso + dell'operazione \const{PR\_SET\_KEEPCAPS} di + \func{prctl}.\\ + \constd{SECURE\_NO\_SETUID\_FIXUP}&Il processo non subisce le modifiche + delle sue \textit{capabilities} nel passaggio + da nullo a non nullo degli \ids{UID} + dei gruppi \textit{effective} e + \textit{file system} (regole di compatibilità + per il cambio di \ids{UID} nn.~1 e 2 del + precedente elenco).\\ + \constd{SECURE\_NOROOT} & Il processo non assume nessuna capacità + aggiuntiva quando esegue un programma, anche + se ha \ids{UID} nullo o il programma ha + il \acr{suid} bit attivo ed appartiene + all'amministratore (regola di compatibilità + per l'esecuzione di programmi senza + \textit{capabilities}).\\ + \hline + \end{tabular} + \caption{Costanti identificative dei flag che compongono la maschera dei + \textit{securebits}.} + \label{tab:securebits_values} +\end{table} + +A ciascuno dei flag di tab.~\ref{tab:securebits_values} è inoltre abbinato un +corrispondente flag di blocco, identificato da una costante omonima con +l'estensione \texttt{\_LOCKED}, la cui attivazione è irreversibile ed ha +l'effetto di rendere permanente l'impostazione corrente del corrispondente +flag ordinario; in sostanza con \constd{SECURE\_KEEP\_CAPS\_LOCKED} si rende +non più modificabile \const{SECURE\_KEEP\_CAPS}, ed analogamente avviene con +\constd{SECURE\_NO\_SETUID\_FIXUP\_LOCKED} per +\const{SECURE\_NO\_SETUID\_FIXUP} e con \constd{SECURE\_NOROOT\_LOCKED} per +\const{SECURE\_NOROOT}. + +Per l'impostazione di questi flag sono state predisposte due specifiche +operazioni di \func{prctl} (vedi sez.~\ref{sec:process_prctl}), +\const{PR\_GET\_SECUREBITS}, che consente di ottenerne il valore, e +\const{PR\_SET\_SECUREBITS}, che consente di modificarne il valore; per +quest'ultima sono comunque necessari i privilegi di amministratore ed in +particolare la capacità \const{CAP\_SETPCAP}. Prima dell'introduzione dei +\textit{securebits} era comunque possibile ottenere lo stesso effetto di +\const{SECURE\_KEEP\_CAPS} attraverso l'uso di un'altra operazione di +\func{prctl}, \const{PR\_SET\_KEEPCAPS}. + +\itindend{securebits} + +Oltre alla gestione dei \textit{securebits} la nuova versione delle +\textit{file capabilities} prevede l'uso di \func{prctl} anche per la gestione +del \textit{capabilities bounding set}, attraverso altre due operazioni +dedicate, \const{PR\_CAPBSET\_READ} per controllarne il valore e +\const{PR\_CAPBSET\_DROP} per modificarlo; quest'ultima di nuovo è una +operazione privilegiata che richiede la capacità \const{CAP\_SETPCAP} e che, +come indica chiaramente il nome, permette solo la rimozione di una +\textit{capability} dall'insieme; per i dettagli sull'uso di tutte queste +operazioni si rimanda alla rilettura di sez.~\ref{sec:process_prctl}. + +\itindend{file~capabilities} + + +% NOTE per dati relativi al process capability bounding set, vedi: +% http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=3b7391de67da515c91f48aa371de77cb6cc5c07e + +% NOTE riferimenti ai vari cambiamenti vedi: +% http://lwn.net/Articles/280279/ +% http://lwn.net/Articles/256519/ +% http://lwn.net/Articles/211883/ + + +Un elenco delle delle \textit{capabilities} disponibili su Linux, con una +breve descrizione ed il nome delle costanti che le identificano, è riportato +in tab.~\ref{tab:proc_capabilities};\footnote{l'elenco presentato questa + tabella, ripreso dalla pagina di manuale (accessibile con \texttt{man + capabilities}) e dalle definizioni in + \texttt{include/linux/capabilities.h}, è aggiornato al kernel 3.2.} la +tabella è divisa in due parti, la prima riporta le \textit{capabilities} +previste anche nella bozza dello standard POSIX1.e, la seconda quelle +specifiche di Linux. Come si può notare dalla tabella alcune +\textit{capabilities} attengono a singole funzionalità e sono molto +specializzate, mentre altre hanno un campo di applicazione molto vasto, che è +opportuno dettagliare maggiormente. + +\begin{table}[!h!btp] + \centering + \footnotesize + \begin{tabular}{|l|p{10cm}|} + \hline + \textbf{Capacità}&\textbf{Descrizione}\\ + \hline + \hline +% +% POSIX-draft defined capabilities. +% + \constd{CAP\_AUDIT\_CONTROL}& Abilitare e disabilitare il + controllo dell'auditing (dal kernel 2.6.11).\\ + \constd{CAP\_AUDIT\_WRITE}&Scrivere dati nel giornale di + auditing del kernel (dal kernel 2.6.11).\\ + % TODO verificare questa roba dell'auditing + \constd{CAP\_BLOCK\_SUSPEND}&Utilizzare funzionalità che possono bloccare + la sospensione del sistema (dal kernel 3.5).\\ + \constd{CAP\_CHOWN} & Cambiare proprietario e gruppo + proprietario di un file (vedi + sez.~\ref{sec:file_ownership_management}).\\ + \constd{CAP\_DAC\_OVERRIDE}& Evitare il controllo dei + permessi di lettura, scrittura ed esecuzione dei + file, (vedi sez.~\ref{sec:file_access_control}).\\ + \constd{CAP\_DAC\_READ\_SEARCH}& Evitare il controllo dei + permessi di lettura ed esecuzione per + le directory (vedi + sez.~\ref{sec:file_access_control}).\\ + \const{CAP\_FOWNER} & Evitare il controllo della proprietà di un file + per tutte le operazioni privilegiate non coperte + dalle precedenti \const{CAP\_DAC\_OVERRIDE} e + \const{CAP\_DAC\_READ\_SEARCH}.\\ + \constd{CAP\_FSETID} & Evitare la cancellazione automatica dei bit + \acr{suid} e \acr{sgid} quando un file + per i quali sono impostati viene modificato da + un processo senza questa capacità e la capacità + di impostare il bit \acr{sgid} su un file anche + quando questo è relativo ad un gruppo cui non si + appartiene (vedi + sez.~\ref{sec:file_perm_management}).\\ + \constd{CAP\_KILL} & Mandare segnali a qualunque + processo (vedi sez.~\ref{sec:sig_kill_raise}).\\ + \constd{CAP\_SETFCAP} & Impostare le \textit{capabilities} di un file + (dal kernel 2.6.24).\\ + \constd{CAP\_SETGID} & Manipolare i group ID dei + processi, sia il principale che i supplementari, + (vedi sez.~\ref{sec:proc_setgroups}) che quelli + trasmessi tramite i socket \textit{unix domain} + (vedi sez.~\ref{sec:unix_socket}).\\ + \constd{CAP\_SETUID} & Manipolare gli user ID del + processo (vedi sez.~\ref{sec:proc_setuid}) e di + trasmettere un user ID arbitrario nel passaggio + delle credenziali coi socket \textit{unix + domain} (vedi sez.~\ref{sec:unix_socket}).\\ +% +% Linux specific capabilities +% +\hline + \constd{CAP\_IPC\_LOCK} & Effettuare il \textit{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}). \\ +% TODO verificare l'interazione con SHM_HUGETLB + \constd{CAP\_IPC\_OWNER}& Evitare il controllo dei permessi + per le operazioni sugli oggetti di + intercomunicazione fra processi (vedi + sez.~\ref{sec:ipc_sysv}).\\ + \constd{CAP\_LEASE} & Creare dei \textit{file lease} (vedi + sez.~\ref{sec:file_asyncronous_lease}) + pur non essendo proprietari del file (dal kernel + 2.4).\\ + \constd{CAP\_LINUX\_IMMUTABLE}& Impostare sui file gli attributi + \textit{immutable} e \textit{append-only} (vedi + sez.~\ref{sec:file_perm_overview}) se + supportati.\\ + \constd{CAP\_MAC\_ADMIN}& Amministrare il \textit{Mandatory + Access Control} di \textit{Smack} (dal kernel + 2.6.25).\\ + \constd{CAP\_MAC\_OVERRIDE}& Evitare il \textit{Mandatory + Access Control} di \textit{Smack} (dal kernel + 2.6.25).\\ + \constd{CAP\_MKNOD} & Creare file di dispositivo con \func{mknod} (vedi + sez.~\ref{sec:file_mknod}) (dal kernel 2.4).\\ + \const{CAP\_NET\_ADMIN} & Eseguire alcune operazioni + privilegiate sulla rete.\\ + \constd{CAP\_NET\_BIND\_SERVICE}& Porsi in ascolto su porte riservate (vedi + sez.~\ref{sec:TCP_func_bind}).\\ + \constd{CAP\_NET\_BROADCAST}& Consentire l'uso di socket in + \textit{broadcast} e \textit{multicast}.\\ + \constd{CAP\_NET\_RAW} & Usare socket \texttt{RAW} e \texttt{PACKET} + (vedi sez.~\ref{sec:sock_type}).\\ + \const{CAP\_SETPCAP} & Effettuare modifiche privilegiate alle + \textit{capabilities}.\\ + \const{CAP\_SYS\_ADMIN} & Eseguire una serie di compiti amministrativi.\\ + \constd{CAP\_SYS\_BOOT} & Eseguire un riavvio del sistema (vedi + sez.~\ref{sec:sys_reboot}).\\ + \constd{CAP\_SYS\_CHROOT}& Eseguire la funzione \func{chroot} (vedi + sez.~\ref{sec:file_chroot}).\\ + \constd{CAP\_SYS\_MODULE}& Caricare e rimuovere moduli del kernel.\\ + \const{CAP\_SYS\_NICE} & Modificare le varie priorità dei processi (vedi + sez.~\ref{sec:proc_priority}).\\ + \constd{CAP\_SYS\_PACCT}& Usare le funzioni di \textit{accounting} dei + processi (vedi + sez.~\ref{sec:sys_bsd_accounting}).\\ + \constd{CAP\_SYS\_PTRACE}& La capacità di tracciare qualunque processo con + \func{ptrace} (vedi + sez.~\ref{sec:process_ptrace}).\\ + \constd{CAP\_SYS\_RAWIO}& Operare sulle porte di I/O con \func{ioperm} e + \func{iopl} (vedi + sez.~\ref{sec:process_io_port}).\\ + \const{CAP\_SYS\_RESOURCE}& Superare le varie limitazioni sulle risorse.\\ + \constd{CAP\_SYS\_TIME} & Modificare il tempo di sistema (vedi + sez.~\ref{sec:sys_time}).\\ + \constd{CAP\_SYS\_TTY\_CONFIG}&Simulare un \textit{hangup} della console, + con la funzione \func{vhangup}.\\ + \constd{CAP\_SYSLOG} & Gestire il buffer dei messaggi + del kernel, (vedi sez.~\ref{sec:sess_daemon}), + introdotta dal kernel 2.6.38 come capacità + separata da \const{CAP\_SYS\_ADMIN}.\\ + \constd{CAP\_WAKE\_ALARM}&Usare i timer di tipo + \const{CLOCK\_BOOTTIME\_ALARM} e + \const{CLOCK\_REALTIME\_ALARM}, vedi + sez.~\ref{sec:sig_timer_adv} (dal kernel 3.0).\\ + \hline + \end{tabular} + \caption{Le costanti che identificano le \textit{capabilities} presenti nel + kernel.} +\label{tab:proc_capabilities} +\end{table} + +\constbeg{CAP\_SETPCAP} + +Prima di dettagliare il significato della capacità più generiche, conviene +però dedicare un discorso a parte a \const{CAP\_SETPCAP}, il cui significato è +stato completamente cambiato con l'introduzione delle \textit{file + capabilities} nel kernel 2.6.24. In precedenza questa capacità era quella +che permetteva al processo che la possedeva di impostare o rimuovere le +\textit{capabilities} presenti nel suo \textit{permitted set} su un qualunque +altro processo. In realtà questo non è mai stato l'uso inteso nelle bozze +dallo standard POSIX, ed inoltre, come si è già accennato, dato che questa +capacità è sempre stata assente (a meno di specifiche ricompilazioni del +kernel) nel \textit{capabilities bounding set} usato di default, essa non è +neanche mai stata realmente disponibile. + +Con l'introduzione \textit{file capabilities} e il cambiamento del significato +del \textit{capabilities bounding set} la possibilità di modificare le +capacità di altri processi è stata completamente rimossa, e +\const{CAP\_SETPCAP} ha acquisito quello che avrebbe dovuto essere il suo +significato originario, e cioè la capacità del processo di poter inserire nel +suo \textit{inheritable set} qualunque capacità presente nel \textit{bounding + set}. Oltre a questo la disponibilità di \const{CAP\_SETPCAP} consente ad un +processo di eliminare una capacità dal proprio \textit{bounding set} (con la +conseguente impossibilità successiva di eseguire programmi con quella +capacità), o di impostare i \textit{securebits} delle \textit{capabilities}. + +\constend{CAP\_SETPCAP} +\constbeg{CAP\_FOWNER} + +La prima fra le capacità ``\textsl{ampie}'' che occorre dettagliare +maggiormente è \const{CAP\_FOWNER}, che rimuove le restrizioni poste ad un +processo che non ha la proprietà di un file in un vasto campo di +operazioni;\footnote{vale a dire la richiesta che l'\ids{UID} effettivo del + processo (o meglio l'\ids{UID} di filesystem, vedi + sez.~\ref{sec:proc_setuid}) coincida con quello del proprietario.} queste +comprendono i cambiamenti dei permessi e dei tempi del file (vedi +sez.~\ref{sec:file_perm_management} e sez.~\ref{sec:file_file_times}), le +impostazioni degli attributi dei file e delle ACL (vedi +sez.~\ref{sec:file_xattr} e \ref{sec:file_ACL}), poter ignorare lo +\textit{sticky bit} nella cancellazione dei file (vedi +sez.~\ref{sec:file_special_perm}), la possibilità di impostare il flag di +\const{O\_NOATIME} con \func{open} e \func{fcntl} (vedi +sez.~\ref{sec:file_open_close} e sez.~\ref{sec:file_fcntl_ioctl}) senza +restrizioni. + +\constend{CAP\_FOWNER} +\constbeg{CAP\_NET\_ADMIN} + +Una seconda capacità che copre diverse operazioni, in questo caso riguardanti +la rete, è \const{CAP\_NET\_ADMIN}, che consente di impostare le opzioni +privilegiate dei socket (vedi sez.~\ref{sec:sock_generic_options}), abilitare +il \textit{multicasting} (vedi sez.\ref{sec:sock_ipv4_options}), eseguire la +configurazione delle interfacce di rete (vedi +sez.~\ref{sec:sock_ioctl_netdevice}) ed impostare la tabella di instradamento. + +\constend{CAP\_NET\_ADMIN} +\constbeg{CAP\_SYS\_ADMIN} + +Una terza \textit{capability} con vasto campo di applicazione è +\const{CAP\_SYS\_ADMIN}, che copre una serie di operazioni amministrative, +come impostare le quote disco (vedi sez.\ref{sec:disk_quota}), attivare e +disattivare la swap, montare, rimontare e smontare filesystem (vedi +sez.~\ref{sec:filesystem_mounting}), effettuare operazioni di controllo su +qualunque oggetto dell'IPC di SysV (vedi sez.~\ref{sec:ipc_sysv}), operare +sugli attributi estesi dei file di classe \texttt{security} o \texttt{trusted} +(vedi sez.~\ref{sec:file_xattr}), specificare un \ids{UID} arbitrario nella +trasmissione delle credenziali dei socket (vedi +sez.~\ref{sec:socket_credential_xxx}), assegnare classi privilegiate +(\const{IOPRIO\_CLASS\_RT} e prima del kernel 2.6.25 anche +\const{IOPRIO\_CLASS\_IDLE}) per lo scheduling dell'I/O (vedi +sez.~\ref{sec:io_priority}), superare il limite di sistema sul numero massimo +di file aperti,\footnote{quello indicato da \sysctlfiled{fs/file-max}.} +effettuare operazioni privilegiate sulle chiavi mantenute dal kernel (vedi +sez.~\ref{sec:keyctl_management}), usare la funzione \func{lookup\_dcookie}, +usare \const{CLONE\_NEWNS} con \func{unshare} e \func{clone}, (vedi +sez.~\ref{sec:process_clone}). + +\constend{CAP\_SYS\_ADMIN} +\constbeg{CAP\_SYS\_NICE} + +Originariamente \const{CAP\_SYS\_NICE} riguardava soltanto la capacità di +aumentare le priorità di esecuzione dei processi, come la diminuzione del +valore di \textit{nice} (vedi sez.~\ref{sec:proc_sched_stand}), l'uso delle +priorità \textit{real-time} (vedi sez.~\ref{sec:proc_real_time}), o +l'impostazione delle affinità di processore (vedi +sez.~\ref{sec:proc_sched_multiprocess}); ma con l'introduzione di priorità +anche riguardo le operazioni di accesso al disco, e, nel caso di sistemi NUMA, +alla memoria, essa viene a coprire anche la possibilità di assegnare priorità +arbitrarie nell'accesso a disco (vedi sez.~\ref{sec:io_priority}) e nelle +politiche di allocazione delle pagine di memoria ai nodi di un sistema NUMA. + +\constend{CAP\_SYS\_NICE} +\constbeg{CAP\_SYS\_RESOURCE} + +Infine la \textit{capability} \const{CAP\_SYS\_RESOURCE} attiene alla +possibilità di superare i limiti imposti sulle risorse di sistema, come usare +lo spazio disco riservato all'amministratore sui filesystem che lo supportano, +usare la funzione \func{ioctl} per controllare il \textit{journaling} sul +filesystem \acr{ext3}, non subire le quote disco, aumentare i limiti sulle +risorse di un processo (vedi sez.~\ref{sec:sys_resource_limit}) e quelle sul +numero di processi, ed i limiti sulle dimensioni dei messaggi delle code del +SysV IPC (vedi sez.~\ref{sec:ipc_sysv_mq}). + +\constend{CAP\_SYS\_RESOURCE} + +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 di sistema sono +\funcd{capget} e \funcd{capset} e costituiscono l'interfaccia di gestione +basso livello; i loro rispettivi prototipi sono: + +\begin{funcproto}{ +\fhead{sys/capability.h} +\fdecl{int capget(cap\_user\_header\_t hdrp, cap\_user\_data\_t datap)} +\fdesc{Legge le \textit{capabilities}.} +\fdecl{int capset(cap\_user\_header\_t hdrp, const cap\_user\_data\_t datap)} +\fdesc{Imposta le \textit{capabilities}.} +} + +{Le funzioni ritornano $0$ in caso di successo e $-1$ per un errore, nel qual + caso \var{errno} assumerà uno dei valori: + \begin{errlist} + \item[\errcode{EFAULT}] si è indicato un puntatore sbagliato o nullo + per \param{hdrp} o \param{datap} (quest'ultimo può essere nullo solo se si + usa \func{capget} per ottenere la versione delle \textit{capabilities} + usata dal kernel). + \item[\errcode{EINVAL}] si è specificato un valore non valido per uno dei + campi di \param{hdrp}, in particolare una versione non valida della + versione delle \textit{capabilities}. + \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}. + \item[\errcode{ESRCH}] si è fatto riferimento ad un processo inesistente. + \end{errlist} +} +\end{funcproto} + +Queste due funzioni prendono come argomenti due tipi di dati dedicati, +definiti come puntatori a due strutture specifiche di Linux, illustrate in +fig.~\ref{fig:cap_kernel_struct}. Per un certo periodo di tempo era anche +indicato che per poterle utilizzare fosse necessario che la macro +\macro{\_POSIX\_SOURCE} risultasse non definita (ed era richiesto di inserire +una istruzione \texttt{\#undef \_POSIX\_SOURCE} prima di includere +\headfiled{sys/capability.h}) requisito che non risulta più +presente.\footnote{e non è chiaro neanche quanto sia mai stato davvero + necessario.} + +\begin{figure}[!htb] + \footnotesize + \centering + \begin{minipage}[c]{0.8\textwidth} + \includestruct{listati/cap_user_header_t.h} + \end{minipage} + \normalsize + \caption{Definizione delle strutture a cui fanno riferimento i puntatori + \structd{cap\_user\_header\_t} e \structd{cap\_user\_data\_t} usati per + l'interfaccia di gestione di basso livello delle \textit{capabilities}.} + \label{fig:cap_kernel_struct} +\end{figure} + +Si tenga presente che le strutture di fig.~\ref{fig:cap_kernel_struct}, come i +prototipi delle due funzioni \func{capget} e \func{capset}, sono soggette ad +essere modificate con il cambiamento del kernel (in particolare i tipi di dati +delle strutture) ed anche se finora l'interfaccia è risultata stabile, non c'è +nessuna assicurazione che questa venga mantenuta,\footnote{viene però + garantito che le vecchie funzioni continuino a funzionare.} Pertanto se si +vogliono scrivere programmi portabili che possano essere eseguiti senza +modifiche o adeguamenti su qualunque versione del kernel è opportuno +utilizzare le interfacce di alto livello che vedremo più avanti. + +La struttura a cui deve puntare l'argomento \param{hdrp} serve ad indicare, +tramite il campo \var{pid}, il \ids{PID} del processo del quale si vogliono +leggere o modificare le \textit{capabilities}. Con \func{capset} questo, se si +usano le \textit{file capabilities}, può essere solo 0 o il \ids{PID} del +processo chiamante, che sono equivalenti. Non tratteremo, essendo comunque di +uso irrilevante, il caso in cui, in mancanza di tale supporto, la funzione può +essere usata per modificare le \textit{capabilities} di altri processi, per il +quale si rimanda, se interessati, alla lettura della pagina di manuale. + +Il campo \var{version} deve essere impostato al valore della versione delle +stesse usata dal kernel (quello indicato da una delle costanti +\texttt{\_LINUX\_CAPABILITY\_VERSION\_n} di fig.~\ref{fig:cap_kernel_struct}) +altrimenti le funzioni ritorneranno con un errore di \errcode{EINVAL}, +restituendo nel campo stesso il valore corretto della versione in uso. La +versione due è comunque deprecata e non deve essere usata, ed il kernel +stamperà un avviso se lo si fa. + +I valori delle \textit{capabilities} devono essere passati come maschere +binarie;\footnote{e si tenga presente che i valori di + tab.~\ref{tab:proc_capabilities} non possono essere combinati direttamente, + indicando il numero progressivo del bit associato alla relativa capacità.} +con l'introduzione delle \textit{capabilities} a 64 bit inoltre il +puntatore \param{datap} non può essere più considerato come relativo ad una +singola struttura, ma ad un vettore di due strutture.\footnote{è questo cambio + di significato che ha portato a deprecare la versione 2, che con + \func{capget} poteva portare ad un buffer overflow per vecchie applicazioni + che continuavano a considerare \param{datap} come puntatore ad una singola + struttura.} + +Dato che le precedenti funzioni, oltre ad essere specifiche di Linux, non +garantiscono la stabilità nell'interfaccia, è sempre opportuno effettuare la +gestione delle \textit{capabilities} utilizzando le funzioni di libreria a +questo dedicate. Queste funzioni, che seguono quanto previsto nelle bozze +dello standard POSIX.1e, non fanno parte della \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 al compilatore l'uso +della suddetta libreria attraverso l'opzione \texttt{-lcap}. + +\itindbeg{capability~state} + +Le funzioni dell'interfaccia alle \textit{capabilities} definite nelle bozze +dello standard POSIX.1e prevedono l'uso di un tipo di dato opaco, +\typed{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 fanno 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 i \textit{capability state}, che presentano notevoli affinità, +essendo parte di bozze dello stesso standard, con quelle già viste per le ACL. + +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{funcproto}{ +\fhead{sys/capability.h} +\fdecl{cap\_t cap\_init(void)} +\fdesc{Crea ed inizializza un \textit{capability state}.} +} + +{La funzione ritorna un \textit{capability state} in caso di successo e + \val{NULL} per un errore, nel qual caso \var{errno} potrà assumere solo il + valore \errval{ENOMEM}. } +\end{funcproto} + +La funzione restituisce il puntatore \type{cap\_t} ad uno stato inizializzato +con tutte le \textit{capabilities} azzerate. In caso di errore (cioè quando +non c'è memoria sufficiente ad allocare i dati) viene restituito \val{NULL} +ed \var{errno} viene impostata a \errval{ENOMEM}. + +La memoria necessaria a mantenere i dati viene automaticamente allocata da +\func{cap\_init}, ma dovrà essere disallocata esplicitamente quando non è più +necessaria utilizzando, per questo l'interfaccia fornisce una apposita +funzione, \funcd{cap\_free}, il cui prototipo è: + +\begin{funcproto}{ +\fhead{sys/capability.h} +\fdecl{int cap\_free(void *obj\_d)} +\fdesc{Disalloca la memoria allocata per i dati delle \textit{capabilities}..} +} + +{La funzione ritorna $0$ in caso di successo e $-1$ per un errore, nel qual + caso \var{errno} potrà assumere solo il valore \errval{EINVAL}. +} +\end{funcproto} + + +La funzione permette di liberare la memoria allocata dalle altre funzioni +della libreria sia per un \textit{capability state}, nel qual caso l'argomento +sarà 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 sarà un dato di tipo +\texttt{char *}. Per questo motivo l'argomento \param{obj\_d} è dichiarato +come \texttt{void *}, per evitare la necessità di eseguire un \textit{cast}, +ma dovrà comunque corrispondere ad un puntatore ottenuto tramite le altre +funzioni della libreria, altrimenti la funzione fallirà con un errore di +\errval{EINVAL}. + +Infine si può creare una copia di un \textit{capability state} ottenuto in +precedenza tramite la funzione \funcd{cap\_dup}, il cui prototipo è: + +\begin{funcproto}{ +\fhead{sys/capability.h} +\fdecl{cap\_t cap\_dup(cap\_t cap\_p)} +\fdesc{Duplica un \textit{capability state} restituendone una copia.} +} + +{La funzione ritorna un \textit{capability state} in caso di successo e + \val{NULL} per un errore, nel qual caso \var{errno} assumerà i valori + \errval{ENOMEM} o \errval{EINVAL} nel loro significato generico.} +\end{funcproto} + + +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, ed alla fine +delle operazioni si dovrà disallocare anche la copia, oltre all'originale. + +Una seconda classe di funzioni di servizio previste dall'interfaccia sono +quelle per la gestione dei dati contenuti all'interno di un \textit{capability + state}; la prima di queste è \funcd{cap\_clear}, il cui prototipo è: + +\begin{funcproto}{ +\fhead{sys/capability.h} +\fdecl{int cap\_clear(cap\_t cap\_p)} +\fdesc{Inizializza un \textit{capability state} cancellando tutte le + \textit{capabilities}.} +} + +{La funzione ritorna $0$ in caso di successo e $-1$ per un errore, nel qual + caso \var{errno} potrà assumere solo il valore \errval{EINVAL}. +} +\end{funcproto} + +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}. + +Una variante di \func{cap\_clear} è \funcd{cap\_clear\_flag} che cancella da +un \textit{capability state} tutte le \textit{capabilities} di un certo +insieme fra quelli elencati a pag.~\pageref{sec:capabilities_set}, il suo +prototipo è: + +\begin{funcproto}{ +\fhead{sys/capability.h} +\fdecl{int cap\_clear\_flag(cap\_t cap\_p, cap\_flag\_t flag)} +\fdesc{Cancella delle \textit{capabilities} da un \textit{capability state}.} +} + +{La funzione ritorna $0$ in caso di successo e $-1$ per un errore, nel qual + caso \var{errno} potrà assumere solo il valore \errval{EINVAL}. +} +\end{funcproto} + +La funzione richiede che si indichi quale degli insiemi si intente cancellare +da \param{cap\_p} con l'argomento \param{flag}. Questo deve essere specificato +con una variabile di tipo \type{cap\_flag\_t} che può assumere +esclusivamente\footnote{si tratta in effetti di un tipo enumerato, come si può + verificare dalla sua definizione che si trova in + \headfile{sys/capability.h}.} uno dei valori illustrati in +tab.~\ref{tab:cap_set_identifier}. + +\begin{table}[htb] + \centering + \footnotesize + \begin{tabular}[c]{|l|l|} + \hline + \textbf{Valore} & \textbf{Significato} \\ + \hline + \hline + \constd{CAP\_EFFECTIVE} & Capacità dell'insieme \textsl{effettivo}.\\ + \constd{CAP\_PERMITTED} & Capacità dell'insieme \textsl{permesso}.\\ + \constd{CAP\_INHERITABLE}& Capacità dell'insieme \textsl{ereditabile}.\\ + \hline + \end{tabular} + \caption{Valori possibili per il tipo di dato \typed{cap\_flag\_t} che + identifica gli insiemi delle \textit{capabilities}.} + \label{tab:cap_set_identifier} +\end{table} + +Si possono inoltre confrontare in maniera diretta due diversi +\textit{capability state} con la funzione \funcd{cap\_compare}; il suo +prototipo è: + +\begin{funcproto}{ +\fhead{sys/capability.h} +\fdecl{int cap\_compare(cap\_t cap\_a, cap\_t cap\_b)} +\fdesc{Confronta due \textit{capability state}.} +} + +{La funzione ritorna $0$ se i \textit{capability state} sono identici + ed un valore positivo se differiscono, non sono previsti errori.} +\end{funcproto} + + +La funzione esegue un confronto fra i due \textit{capability state} passati +come argomenti e ritorna in un valore intero il risultato, questo è nullo se +sono identici o positivo se vi sono delle differenze. Il valore di ritorno +della funzione consente inoltre di per ottenere ulteriori informazioni su +quali sono gli insiemi di \textit{capabilities} che risultano differenti. Per +questo si può infatti usare la apposita macro \macro{CAP\_DIFFERS}: + +{\centering +\vspace{3pt} +\begin{funcbox}{ +\fhead{sys/capability.h} +\fdecl{int \macrod{CAP\_DIFFERS}(value, flag)} +\fdesc{Controlla lo stato di eventuali differenze delle \textit{capabilities} + nell'insieme \texttt{flag}.} +} +\end{funcbox} +} + +La macro richiede che si passi nell'argomento \texttt{value} il risultato +della funzione \func{cap\_compare} e in \texttt{flag} l'indicazione (coi +valori di tab.~\ref{tab:cap_set_identifier}) dell'insieme che si intende +controllare; restituirà un valore diverso da zero se le differenze rilevate da +\func{cap\_compare} sono presenti nell'insieme indicato. + +Per la gestione dei singoli valori delle \textit{capabilities} presenti in un +\textit{capability state} l'interfaccia prevede due funzioni specifiche, +\funcd{cap\_get\_flag} e \funcd{cap\_set\_flag}, che permettono +rispettivamente di leggere o impostare il valore di una capacità all'interno +in uno dei tre insiemi già citati; i rispettivi prototipi sono: + +\begin{funcproto}{ +\fhead{sys/capability.h} +\fdecl{int cap\_get\_flag(cap\_t cap\_p, cap\_value\_t cap, cap\_flag\_t +flag,\\ +\phantom{int cap\_get\_flag(}cap\_flag\_value\_t *value\_p)} +\fdesc{Legge il valore di una \textit{capability}.} +\fdecl{int cap\_set\_flag(cap\_t cap\_p, cap\_flag\_t flag, int ncap, + cap\_value\_t *caps, \\ +\phantom{int cap\_set\_flag(}cap\_flag\_value\_t value)} +\fdesc{Imposta il valore di una \textit{capability}.} +} + +{Le funzioni ritornano $0$ in caso di successo e $-1$ per un errore, nel qual + caso \var{errno} potrà assumere solo il valore \errval{EINVAL}. +} +\end{funcproto} + +In entrambe le funzioni l'argomento \param{cap\_p} indica il puntatore al +\textit{capability state} su cui operare, mentre l'argomento \param{flag} +indica su quale dei tre insiemi si intende operare, sempre con i valori di +tab.~\ref{tab:cap_set_identifier}. La capacità che si intende controllare o +impostare invece deve essere specificata attraverso una variabile di tipo +\typed{cap\_value\_t}, che può prendere come valore uno qualunque di quelli +riportati in tab.~\ref{tab:proc_capabilities}, in questo caso però non è +possibile combinare diversi valori in una maschera binaria, una variabile di +tipo \type{cap\_value\_t} può indicare una sola capacità.\footnote{in + \headfile{sys/capability.h} il tipo \type{cap\_value\_t} è definito come + \ctyp{int}, ma i valori validi sono soltanto quelli di + tab.~\ref{tab:proc_capabilities}.} + +Infine lo stato di una capacità è descritto ad una variabile di tipo +\type{cap\_flag\_value\_t}, che a sua volta può assumere soltanto +uno\footnote{anche questo è un tipo enumerato.} dei valori di +tab.~\ref{tab:cap_value_type}. + +\begin{table}[htb] + \centering + \footnotesize + \begin{tabular}[c]{|l|l|} + \hline + \textbf{Valore} & \textbf{Significato} \\ + \hline + \hline + \constd{CAP\_CLEAR}& La capacità non è impostata.\\ + \constd{CAP\_SET} & La capacità è impostata.\\ + \hline + \end{tabular} + \caption{Valori possibili per il tipo di dato \typed{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 lo restituisce come \textit{value result argument} nella +variabile puntata dall'argomento \param{value\_p}. Questa deve essere di tipo +\type{cap\_flag\_value\_t} ed assumerà uno dei valori di +tab.~\ref{tab:cap_value_type}. La funzione consente pertanto di leggere solo +lo stato di una capacità alla volta. + +La funzione \func{cap\_set\_flag} può invece impostare in una sola chiamata +più \textit{capabilities}, anche se solo all'interno dello stesso insieme ed +allo stesso valore. Per questo motivo essa prende un vettore di valori di tipo +\type{cap\_value\_t} nell'argomento \param{caps}, la cui dimensione viene +specificata dall'argomento \param{ncap}. Il tipo di impostazione da eseguire +(cancellazione o attivazione) per le capacità elencate in \param{caps} viene +indicato dall'argomento \param{value} sempre con i valori di +tab.~\ref{tab:cap_value_type}. + +Per semplificare la gestione delle \textit{capabilities} l'interfaccia prevede +che sia possibile utilizzare anche una rappresentazione testuale del contenuto +di un \textit{capability state} e fornisce le opportune funzioni di +gestione;\footnote{entrambe erano previste dalla bozza dello standard + POSIX.1e.} la prima di queste, che consente di ottenere la rappresentazione +testuale, è \funcd{cap\_to\_text}, il cui prototipo è: + +\begin{funcproto}{ +\fhead{sys/capability.h} +\fdecl{char *cap\_to\_text(cap\_t caps, ssize\_t *length\_p)} +\fdesc{Genera una visualizzazione testuale delle \textit{capabilities}.} +} + +{La funzione ritorna un puntatore alla stringa con la descrizione delle + \textit{capabilities} in caso di successo e \val{NULL} per un errore, nel + qual caso \var{errno} assumerà i valori \errval{EINVAL} o \errval{ENOMEM} + nel loro significato generico.} +\end{funcproto} + +La funzione ritorna l'indirizzo di una stringa contente la descrizione +testuale del contenuto del \textit{capability state} \param{caps} passato come +argomento, e, qualora l'argomento \param{length\_p} sia diverso da \val{NULL}, +restituisce come \textit{value result argument} nella variabile intera da +questo puntata la lunghezza della stringa. La stringa restituita viene +allocata automaticamente dalla funzione e pertanto dovrà essere liberata con +\func{cap\_free}. + +La rappresentazione testuale, che viene usata anche dai programmi di gestione a +riga di comando, prevede che lo stato venga rappresentato con una stringa di +testo composta da una serie di proposizioni separate da spazi, ciascuna delle +quali specifica una operazione da eseguire per creare lo stato finale. Nella +rappresentazione si fa sempre conto di partire da uno stato in cui tutti gli +insiemi sono vuoti e si provvede a impostarne i contenuti. + +Ciascuna proposizione è nella forma di un elenco di capacità, espresso con i +nomi di tab.~\ref{tab:proc_capabilities} separati da virgole, seguito da un +operatore, e dall'indicazione degli insiemi a cui l'operazione si applica. I +nomi delle capacità possono essere scritti sia maiuscoli che minuscoli, viene +inoltre riconosciuto il nome speciale \texttt{all} che è equivalente a +scrivere la lista completa. Gli insiemi sono identificati dalle tre lettere +iniziali: ``\texttt{p}'' per il \textit{permitted}, ``\texttt{i}'' per +l'\textit{inheritable} ed ``\texttt{e}'' per l'\textit{effective} che devono +essere sempre minuscole, e se ne può indicare più di uno. + +Gli operatori possibili sono solo tre: ``\texttt{+}'' che aggiunge le capacità +elencate agli insiemi indicati, ``\texttt{-}'' che le toglie e ``\texttt{=}'' +che le assegna esattamente. I primi due richiedono che sia sempre indicato sia +un elenco di capacità che gli insiemi a cui esse devono applicarsi, e +rispettivamente attiveranno o disattiveranno le capacità elencate nell'insieme +o negli insiemi specificati, ignorando tutto il resto. I due operatori possono +anche essere combinati nella stessa proposizione, per aggiungere e togliere le +capacità dell'elenco da insiemi diversi. + +L'assegnazione si applica invece su tutti gli insiemi allo stesso tempo, +pertanto l'uso di ``\texttt{=}'' è equivalente alla cancellazione preventiva +di tutte le capacità ed alla impostazione di quelle elencate negli insiemi +specificati, questo significa che in genere lo si usa una sola volta +all'inizio della stringa. In tal caso l'elenco delle capacità può non essere +indicato e viene assunto che si stia facendo riferimento a tutte quante senza +doverlo scrivere esplicitamente. + +Come esempi avremo allora che un processo non privilegiato di un utente, che +non ha nessuna capacità attiva, avrà una rappresentazione nella forma +``\texttt{=}'' che corrisponde al fatto che nessuna capacità viene assegnata a +nessun insieme (vale la cancellazione preventiva), mentre un processo con +privilegi di amministratore avrà una rappresentazione nella forma +``\texttt{=ep}'' in cui tutte le capacità vengono assegnate agli insiemi +\textit{permitted} ed \textit{effective} (e l'\textit{inheritable} è ignorato +in quanto per le regole viste a pag.~\ref{sec:capability-uid-transition} le +capacità verranno comunque attivate attraverso una \func{exec}). Infine, come +esempio meno banale dei precedenti, otterremo per \texttt{init} una +rappresentazione nella forma ``\texttt{=ep cap\_setpcap-e}'' dato che come +accennato tradizionalmente \const{CAP\_SETPCAP} è sempre stata rimossa da +detto processo. + +Viceversa per ottenere un \textit{capability state} dalla sua rappresentazione +testuale si può usare la funzione \funcd{cap\_from\_text}, il cui prototipo è: + +\begin{funcproto}{ +\fhead{sys/capability.h} +\fdecl{cap\_t cap\_from\_text(const char *string)} +\fdesc{Crea un \textit{capability state} dalla sua rappresentazione testuale.} +} + +{La funzione ritorna un \textit{capability state} in caso di successo e + \val{NULL} per un errore, nel qual caso \var{errno} assumerà i valori + \errval{EINVAL} o \errval{ENOMEM} nel loro significato generico.} +\end{funcproto} + + +La funzione restituisce il puntatore ad un \textit{capability state} +inizializzato con i valori indicati nella stringa \param{string} che ne +contiene la rappresentazione testuale. La memoria per il \textit{capability + state} viene allocata automaticamente dalla funzione e dovrà essere liberata +con \func{cap\_free}. + +Alle due funzioni citate se ne aggiungono altre due che consentono di +convertire i valori delle costanti di tab.~\ref{tab:proc_capabilities} nelle +stringhe usate nelle rispettive rappresentazioni e viceversa. Le due funzioni, +\funcd{cap\_to\_name} e \funcd{cap\_from\_name}, sono estensioni specifiche di +Linux ed i rispettivi prototipi sono: + +\begin{funcproto}{ +\fhead{sys/capability.h} +\fdecl{char *cap\_to\_name(cap\_value\_t cap)} +\fdesc{Converte il valore numerico di una \textit{capabilities} alla sua + rappresentazione testuale.} +\fdecl{int cap\_from\_name(const char *name, cap\_value\_t *cap\_p)} + +\fdesc{Converte la rappresentazione testuale di una \textit{capabilities} al + suo valore numerico.} +} + +{La funzione \func{cap\_to\_name} ritorna un puntatore ad una stringa in caso + di successo e \val{NULL} per un errore, mentre \func{cap\_to\_name} ritorna + $0$ in caso di successo e $-1$ per un errore, per entrambe in caso di errore + \var{errno} assumerà i valori \errval{EINVAL} o \errval{ENOMEM} nel loro + significato generico. +} +\end{funcproto} + +La prima funzione restituisce la stringa (allocata automaticamente e che dovrà +essere liberata con \func{cap\_free}) che corrisponde al valore della +capacità \param{cap}, mentre la seconda restituisce nella variabile puntata +da \param{cap\_p}, come \textit{value result argument}, il valore della +capacità rappresentata dalla stringa \param{name}. + +Fin quei abbiamo trattato solo le funzioni di servizio relative alla +manipolazione dei \textit{capability state} come strutture di dati; +l'interfaccia di gestione prevede però anche le funzioni per trattare le +\textit{capabilities} presenti nei processi. La prima di queste funzioni è +\funcd{cap\_get\_proc} che consente la lettura delle \textit{capabilities} del +processo corrente, il suo prototipo è: + +\begin{funcproto}{ +\fhead{sys/capability.h} +\fdecl{cap\_t cap\_get\_proc(void)} +\fdesc{Legge le \textit{capabilities} del processo corrente.} +} + +{La funzione ritorna un \textit{capability state} in caso di successo e + \val{NULL} per un errore, nel qual caso \var{errno} assumerà i valori + \errval{EINVAL}, \errval{EPERM} o \errval{ENOMEM} nel loro significato + generico.} +\end{funcproto} + +La funzione legge il valore delle \textit{capabilities} associate al processo +da cui viene invocata, restituendo il risultato tramite il puntatore ad un +\textit{capability state} contenente tutti i dati che provvede ad allocare +autonomamente e che di nuovo occorrerà liberare con \func{cap\_free} quando +non sarà più utilizzato. + +Se invece si vogliono leggere le \textit{capabilities} di un processo +specifico occorre usare la funzione \funcd{cap\_get\_pid}, il cui +prototipo\footnote{su alcune pagine di manuale la funzione è descritta con un + prototipo sbagliato, che prevede un valore di ritorno di tipo \type{cap\_t}, + ma il valore di ritorno è intero, come si può verificare anche dalla + dichiarazione della stessa in \headfile{sys/capability.h}.} è: + +\begin{funcproto}{ +\fhead{sys/capability.h} +\fdecl{cap\_t cap\_get\_pid(pid\_t pid)} +\fdesc{Legge le \textit{capabilities} di un processo.} +} + +{La funzione ritorna un \textit{capability state} in caso di successo e + \val{NULL} per un errore, nel qual caso \var{errno} assumerà i valori + \errval{ESRCH} o \errval{ENOMEM} nel loro significato generico. } +\end{funcproto} + +La funzione legge il valore delle \textit{capabilities} del processo indicato +con l'argomento \param{pid}, e restituisce il risultato tramite il puntatore +ad un \textit{capability state} contenente tutti i dati che provvede ad +allocare autonomamente e che al solito deve essere disallocato con +\func{cap\_free}. Qualora il processo indicato non esista si avrà un errore di +\errval{ESRCH}. Gli stessi valori possono essere letti direttamente nel +filesystem \textit{proc}, nei file \texttt{/proc//status}; ad esempio per +\texttt{init} si otterrà qualcosa del tipo: +\begin{Console} +piccardi@hain:~/gapil$ \textbf{cat /proc/1/status} +... +CapInh: 0000000000000000 +CapPrm: 00000000fffffeff +CapEff: 00000000fffffeff +... +\end{Console} +%$ + +\itindend{capability~state} + +Infine per impostare le \textit{capabilities} del processo corrente (nella +bozza dello standard POSIX.1e non esiste una funzione che permetta di cambiare +le \textit{capabilities} di un altro processo) si deve usare la funzione +\funcd{cap\_set\_proc}, il cui prototipo è: + +\begin{funcproto}{ +\fhead{sys/capability.h} +\fdecl{int cap\_set\_proc(cap\_t cap\_p)} +\fdesc{Imposta le \textit{capabilities} del processo corrente.} +} + +{La funzione ritorna $0$ in caso di successo e $-1$ per un errore, nel qual + caso \var{errno} assumerà i valori: + \begin{errlist} + \item[\errcode{EPERM}] si è cercato di attivare una capacità non permessa. + \end{errlist} ed inoltre \errval{EINVAL} nel suo significato generico.} +\end{funcproto} + +La funzione modifica le \textit{capabilities} del processo corrente secondo +quanto specificato con l'argomento \param{cap\_p}, posto che questo sia +possibile nei termini spiegati in precedenza (non sarà ad esempio possibile +impostare capacità non presenti nell'insieme di quelle permesse). + +In caso di successo i nuovi valori saranno effettivi al ritorno della +funzione, in caso di fallimento invece lo stato delle capacità resterà +invariato. Si tenga presente che \textsl{tutte} le capacità specificate +tramite \param{cap\_p} devono essere permesse; se anche una sola non lo è la +funzione fallirà, e per quanto appena detto, lo stato delle +\textit{capabilities} non verrà modificato (neanche per le parti eventualmente +permesse). + +Oltre a queste funzioni su Linux sono presenti due ulteriori funzioni, +\funcm{capgetp} e \funcm{capsetp}, che svolgono un compito analogo. Queste +funzioni risalgono alla implementazione iniziale delle \textit{capabilities} +ed in particolare \funcm{capsetp} consentirebbe anche, come possibile in quel +caso, di cambiare le capacità di un altro processo. Le due funzioni oggi sono +deprecate e pertanto eviteremo di trattarle, per chi fosse interessato si +rimanda alla lettura della loro pagina di manuale. + +Come esempio di utilizzo di queste funzioni nei sorgenti allegati alla guida +si è distribuito il programma \texttt{getcap.c}, che consente di leggere le +\textit{capabilities} del processo corrente\footnote{vale a dire di sé stesso, + quando lo si lancia, il che può sembrare inutile, ma serve a mostrarci quali + sono le \textit{capabilities} standard che ottiene un processo lanciato + dalla riga di comando.} o tramite l'opzione \texttt{-p}, quelle di un +processo qualunque il cui \ids{PID} viene passato come parametro dell'opzione. + +\begin{figure}[!htbp] + \footnotesize \centering + \begin{minipage}[c]{\codesamplewidth} + \includecodesample{listati/getcap.c} + \end{minipage} + \normalsize + \caption{Corpo principale del programma \texttt{getcap.c}.} + \label{fig:proc_getcap} +\end{figure} + +La sezione principale del programma è riportata in fig.~\ref{fig:proc_getcap}, +e si basa su una condizione sulla variabile \var{pid} che se si è usato +l'opzione \texttt{-p} è impostata (nella sezione di gestione delle opzioni, +che si è tralasciata) al valore del \ids{PID} del processo di cui si vuole +leggere le \textit{capabilities} e nulla altrimenti. Nel primo caso +(\texttt{\small 1-6}) si utilizza (\texttt{\small 2}) \func{cap\_get\_proc} +per ottenere lo stato delle capacità del processo, nel secondo (\texttt{\small + 7-13}) si usa invece \func{cap\_get\_pid} (\texttt{\small 8}) per leggere +il valore delle capacità del processo indicato. + +Il passo successivo è utilizzare (\texttt{\small 15}) \func{cap\_to\_text} per +tradurre in una stringa lo stato, e poi (\texttt{\small 16}) stamparlo; infine +(\texttt{\small 18-19}) si libera la memoria allocata dalle precedenti +funzioni con \func{cap\_free} per poi ritornare dal ciclo principale della +funzione. + +\itindend{capabilities} + +% TODO vedi http://lwn.net/Articles/198557/ e +% http://www.madore.org/~david/linux/newcaps/ + + + + + + % TODO: trattare keyctl (man 2 keyctl) % TODO trattare le funzioni di protezione della memoria pkey_alloc, pkey_free, diff --git a/process.tex b/process.tex index 6408f6f..4df632d 100644 --- a/process.tex +++ b/process.tex @@ -2947,9 +2947,9 @@ basterà scegliere una volta per tutte quale usare e attenersi alla scelta. % LocalWords: times library utmp syscall number Filesystem Hierarchy pathname % LocalWords: context assembler sysconf fork Dinamic huge segmentation program % LocalWords: break store using intptr ssize overflow ONFAULT faulting alloc +% LocalWords: scheduler pvalloc aligned ISOC ABCDEF %%% Local Variables: %%% mode: latex %%% TeX-master: "gapil" %%% End: -% LocalWords: scheduler pvalloc aligned ISOC ABCDEF diff --git a/prochand.tex b/prochand.tex index 8d50557..f50c0c5 100644 --- a/prochand.tex +++ b/prochand.tex @@ -3773,7 +3773,7 @@ essere soggetto a \textit{race condition} dato potrebbe essere interrotto in qualunque momento da un altro \textit{thread}. In tal caso occorre pianificare con estrema attenzione l'uso delle variabili ed utilizzare i vari meccanismi di sincronizzazione che anche in questo caso sono disponibili (torneremo su -queste problematiche di questo tipo in cap.~\ref{sez:pthread_sync}) +queste problematiche di questo tipo in cap.~\ref{sec:pthread_sync}) \itindbeg{deadlock} diff --git a/sources/mymount.c b/sources/mymount.c index fcb92f0..d419026 100644 --- a/sources/mymount.c +++ b/sources/mymount.c @@ -216,5 +216,8 @@ void usage(void) { printf("you always need to specify two argument, source and target,\n"); printf("matching the system call ones, if one of them is not needed\n"); printf("just pass an empty string\n"); + printf("you also need to specify options and flag, give an empty \n"); + printf("string for option if you don't want to set any, i.e. \n"); + printf(" ./mymount -t ext4 -o "" -f remount,rdonly /dev/sdb1 /mnt"); exit(1); } -- 2.30.2