X-Git-Url: https://gapil.gnulinux.it/gitweb/?p=gapil.git;a=blobdiff_plain;f=filedir.tex;h=514705b61e32b47f3b97ad09cbdb42b964d65c2e;hp=b94e1d8136f978451cffe1ce45d0dfc1a121b9ad;hb=94b4d603807121b40eef06d22d2b6cd6e06ec7fd;hpb=211c687a29a4e8732c3f12c6b321a80807e99f1e diff --git a/filedir.tex b/filedir.tex index b94e1d8..514705b 100644 --- a/filedir.tex +++ b/filedir.tex @@ -9,18 +9,830 @@ %% License". %% -\chapter{File e directory} +\chapter{La gestione di file e directory} \label{cha:files_and_dirs} In questo capitolo tratteremo in dettaglio le modalità con cui si gestiscono -file e directory, iniziando dalle funzioni di libreria che si usano per -copiarli, spostarli e cambiarne i nomi. Esamineremo poi l'interfaccia che -permette la manipolazione dei vari attributi di file e directory ed alla fine -prenderemo in esame 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 manipolazione del contenuto dei file è lasciato ai capitoli -successivi. +file e directory, iniziando da un approfondimento dell'architettura del +sistema illustrata a grandi linee in sez.~\ref{sec:file_arch_overview} ed +illustrando le principali caratteristiche di un filesystem e le interfacce +che consentono di controllarne il montaggio e lo smontaggio. + +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. + + + +\section{L'architettura della gestione dei file} +\label{sec:file_arch_func} + +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. + + +\subsection{Il funzionamento del \textit{Virtual File System} di Linux} +\label{sec:file_vfs_work} + +% articolo interessante: +% http://www.ibm.com/developerworks/linux/library/l-virtual-filesystem-switch/index.html?ca=dgr-lnxw97Linux-VFSdth-LXdW&S_TACT=105AGX59&S_CMP=GRlnxw97 + +\itindbeg{Virtual~File~System} + +Come illustrato brevemente in sez.~\ref{sec:file_arch_overview} in Linux il +concetto di \textit{everything is a file} è stato implementato attraverso il +\textit{Virtual File System}, la cui struttura generale è illustrata in +fig.~\ref{fig:file_VFS_scheme}. Il VFS definisce un insieme di funzioni che +tutti i filesystem devono implementare per l'accesso ai file che contengono e +l'interfaccia che consente di eseguire l'I/O sui file, che questi siano di +dati o dispositivi. + +L'interfaccia fornita dal VFS comprende in sostanza tutte le funzioni che +riguardano i file, le operazioni implementate dal VFS sono realizzate con una +astrazione che prevede quattro tipi di oggetti strettamente correlati: i +filesystem, le \textit{dentry}, gli \textit{inode} ed i file. A questi oggetti +corrispondono una serie di apposite strutture definite dal kernel che +contengono come campi le funzioni di gestione e realizzano l'infrastruttura +del VFS. L'interfaccia è estremamente complessa, ne faremo pertanto una +trattazione estremamente semplificata che consenta di comprenderne i principi +difunzionamento. + +Il VFS usa una tabella mantenuta dal kernel che contiene il nome di ciascun +filesystem supportato, quando si vuole inserire il supporto di un nuovo +filesystem tutto quello che occorre è chiamare la funzione +\code{register\_filesystem} passando come argomento la struttura +\kstruct{file\_system\_type} (la cui definizione è riportata in +fig.~\ref{fig:kstruct_file_system_type}) relativa a quel filesystem. Questa +verrà inserita nella tabella, ed il nuovo filesystem comparirà in +\procfile{/proc/filesystems}. + +\begin{figure}[!htb] + \footnotesize \centering + \begin{minipage}[c]{\textwidth} + \includestruct{listati/file_system_type.h} + \end{minipage} + \normalsize + \caption{Estratto della struttura \kstructd{file\_system\_type} usata dal + VFS (da \texttt{include/linux/fs.h}).} + \label{fig:kstruct_file_system_type} +\end{figure} + +La struttura \kstruct{file\_system\_type}, oltre ad una serie di dati interni, +come il nome del tipo di filesystem nel campo \var{name},\footnote{quello che + viene riportato in \procfile{/proc/filesystems} e che viene usato come + parametro dell'opzione \texttt{-t} del comando \texttt{mount}.} contiene i +riferimenti alle funzioni di base che consentono l'utilizzo di quel +filesystem. In particolare la funzione \code{mount} del quarto campo è quella +che verrà invocata tutte le volte che si dovrà effettuare il montaggio di un +filesystem di quel tipo. Per ogni nuovo filesystem si dovrà allocare una di +queste strutture ed inizializzare i relativi campi con i dati specifici diquel +filesystem, ed in particolare si dovra creare anche la relativa versione della +funzione \code{mount}. + +Come illustrato in fig.~\ref{fig:kstruct_file_system_type} questa funzione +restituisce una \textit{dentry}, abbreviazione che sta per \textit{directory + entry}. Le \textit{dentry} sono gli oggetti che il kernel usa per eseguire +la \textit{pathname resolution}, ciascuna di esse corrisponde ad un +\textit{pathname} e contiene il riferimento ad un \textit{inode}, che come +vedremo a breve è l'oggetto usato dal kernel per identificare un un +file.\footnote{in questo caso si parla di file come di un qualunque oggetto + generico che sta sul filesystem.} La \textit{dentry} ottenuta dalla chiamata +alla funzione \code{mount} sarà inserita in corrispondenza al +\textit{pathname} della directory in cui il filesystem è stato montato. + +% NOTA: struct dentry è dichiarata in include/linux/dcache.h + +Le \textit{dentry} sono oggetti del VFS che vivono esclusivamente in memoria, +nella cosiddetta \textit{directory entry cache} (spesso chiamata in breve +\textit{dcache}). Ogni volta che una \textit{system call} specifica un +\textit{pathname} viene effettuata una ricerca nella \textit{dcache} per +ottenere immediatamente la \textit{dentry} corrispondente,\footnote{il buon + funzionamento della \textit{dcache} è in effetti di una delle parti più + critiche per le prestazioni del sistema.} che a sua ci darà, tramite +l'\textit{inode}, il riferimento al file. + +Dato che normalmente non è possibile mantenere nella \textit{dcache} le +informazioni relative a tutto l'albero dei file la procedura della +\textit{pathname resolution} richiede un meccanismo con cui riempire gli +eventuali vuoti. Il meccanismo prevede che tutte le volte che si arriva ad una +\textit{dentry} mancante venga invocata la funzione \texttt{lookup} dell'inode +associato alla \textit{dentry} precedente nella risoluzione del +\textit{pathname},\footnote{che a questo punto è una directory, per cui si può + cercare al suo interno il nome di un file.} il cui scopo è risolvere il nome +mancante e fornire la sua \textit{dentry} che a questo punto verrà inserita +nella cache. + +Dato che tutte le volte che si monta un filesystem la funzione \texttt{mount} +della corrispondente \kstruct{file\_system\_type} inserisce la \textit{dentry} +iniziale nel \itindex{mount~point} \textit{mount point} dello stesso si avrà +comunque un punto di partenza. Inoltre essendo questa \textit{dentry} relativa +a quel tipo di filesystem essa farà riferimento ad un \textit{inode} di quel +filesystem, e come vedremo questo farà sì che venga eseguita una +\texttt{lookup} adatta per effettuare la risoluzione dei nomi per quel +filesystem. + +% Un secondo effetto della chiamata funzione \texttt{mount} di +% \kstruct{file\_system\_type} è quello di allocare una struttura +% \kstruct{super\_block} per ciascuna istanza montata, che contiene le +% informazioni generali di un qualunque filesystem montato, come le opzioni di +% montaggio, le dimensioni dei blocchi, quando il filesystem è stato montato +% ecc. Fra queste però viene pure inserta, nel campo \var{s\_op}, una ulteriore +% struttura \kstruct{super\_operations}, il cui contenuto sono i puntatori +% alle funzioni di gestione di un filesystem, anche inizializzata in modo da +% utilizzare le versioni specifiche di quel filesystem. + +L'oggetto più importante per il funzionamento del VFS è probabilmente +l'\textit{inode}, ma con questo nome si può fare riferimento a due cose +diverse. La prima è la struttura su disco (su cui torneremo anche in +sez.~\ref{sec:file_filesystem}) che fa parte della organizzazione dei dati +realizzata dal filesystem e che contiene le informazioni relative alle +proprietà (i cosiddetti \textsl{metadati}) di ogni oggetto presente su di esso +(si intende al solito uno qualunque dei tipi di file di +tab.~\ref{tab:file_file_types}). + +La seconda è la corrispondente struttura \kstruct{inode}, della cui +definizione si è riportato un estratto in +fig.~\ref{fig:kstruct_inode}.\footnote{l'estratto fa riferimento alla versione + del kernel 2.6.37.} Questa struttura viene mantenuta in memoria ed è a +questa che facevamo riferimento quando parlavamo dell'\textit{inode} associato +a ciascuna \textit{dentry}. Nella struttura in memoria sono presenti gli +stessi \textsl{metadati} memorizzati su disco, che vengono letti quando questa +struttura viene allocata e trascritti all'indietro se modificati. + +\begin{figure}[!htb] + \footnotesize \centering + \begin{minipage}[c]{\textwidth} + \includestruct{listati/inode.h} + \end{minipage} + \normalsize + \caption{Estratto della struttura \kstructd{inode} del kernel (da + \texttt{include/linux/fs.h}).} + \label{fig:kstruct_inode} +\end{figure} + +Il fatto che la struttura \kstruct{inode} sia mantenuta in memoria, +direttamente associata ad una \textit{dentry}, rende sostanzialmente immediate +le operazioni che devono semplicemente effettuare un accesso ai dati in essa +contenuti: è così ad esempio che viene realizzata la \textit{system call} +\func{stat} che vedremo in sez.~\ref{sec:file_stat}. Rispetto ai dati salvati +sul disco questa struttura contiene però anche quanto necessario alla +implementazione del VFS, ed in particolare è importante il campo \var{i\_op} +che, come illustrato in fig.~\ref{fig:kstruct_inode}, contiene il puntatore ad +una struttura di tipo \kstruct{inode\_operation}, la cui definizione si può +trovare nel file \texttt{include/kernel/fs.h} dei sorgenti del kernel. + +Questa struttura non è altro che una tabella di funzioni, ogni suo membro cioè +è un puntatore ad una funzione, e, come suggerisce il nome della struttura +stessa, queste funzioni, le principali delle quali sono riportate in +tab.~\ref{tab:file_inode_operations}) sono quelle che definiscono le +operazioni che il VFS può compiere su un \textit{inode}. + +\begin{table}[htb] + \centering + \footnotesize + \begin{tabular}[c]{|l|l|} + \hline + \textbf{Funzione} & \textbf{Operazione} \\ + \hline + \hline + \textsl{\code{create}} & Chiamata per creare un nuovo file (vedi + sez.~\ref{sec:file_open}).\\ + \textsl{\code{link}} & Crea un \textit{hard link} (vedi + sez.~\ref{sec:file_link}).\\ + \textsl{\code{unlink}} & Cancella un \textit{hard link} (vedi + sez.~\ref{sec:file_link}).\\ + \textsl{\code{symlink}}& Crea un link simbolico (vedi + sez.~\ref{sec:file_symlink}).\\ + \textsl{\code{mkdir}} & Crea una directory (vedi + sez.~\ref{sec:file_dir_creat_rem}).\\ + \textsl{\code{rmdir}} & Rimuove una directory (vedi + sez.~\ref{sec:file_dir_creat_rem}).\\ + \textsl{\code{mknod}} & Crea un file speciale (vedi + sez.~\ref{sec:file_mknod}).\\ + \textsl{\code{rename}} & Cambia il nome di un file (vedi + sez.~\ref{sec:file_remove}).\\ + \textsl{\code{lookup}}& Risolve il nome di un file.\\ + \hline + \end{tabular} + \caption{Le principali operazioni sugli \textit{inode} definite tramite + \kstruct{inode\_operation}.} + \label{tab:file_inode_operations} +\end{table} + +Possiamo notare come molte di queste funzioni abbiano nomi sostanzialmente +identici alle varie \textit{system call} con le quali si gestiscono file e +directory che tratteremo nel resto del capitolo. Quello che succede è che +tutte le volte che deve essere eseguita una \textit{system call}, o una +qualunque altra operazione su un \textit{inode} (come \texttt{lookup}) il VFS +andrà ad utilizzare la funzione corrispondente attraverso il puntatore +\var{i\_op}. + +Sarà allora sufficiente che nella realizzazione di un filesystem si crei una +opportuna istanza di \kstruct{inode\_operation} contenente i puntatori alla +implementazione di queste funzioni per quel filesystem e quel punto le +strutture \kstruct{inode} usate per gli oggetti di quel filesystem otterranno +il puntatore a detta istanza di \kstruct{inode\_operation} e verranno +automaticamente usate le funzioni corrette. + +Si noti però come in tab.~\ref{tab:file_inode_operations} non sia presente la +funzione \texttt{open} che invece è citata in +tab.~\ref{tab:file_file_operations}.\footnote{essa può essere comunque + invocata dato che nella struttura \kstruct{inode} è presente anche il + puntatore \func{i\_fop} alla struttura \kstruct{file\_operation} che + fornisce detta funzione.} Questo avviene perché su Linux l'apertura di un +file richiede comunque un'altra operazione: l'allocazione di una struttura di +tipo \kstruct{file} che viene associata ad ogni file aperto nel sistema. + +I motivi per cui viene usata una struttura a parte sono diversi, anzitutto, +come illustrato in sez.~\ref{sec:file_fd}, questa è necessaria per le +operazioni eseguite dai processi con l'interfaccia dei file descriptor; ogni +processo infatti mantiene il riferimento ad una struttura \kstruct{file} per +ogni file che ha aperto, ed è tramite essa che esegue le operazioni di I/O. + +Inoltre se le operazioni relative agli \textit{inode} fanno riferimento ad +oggetti posti all'interno di un filesystem e vi si applicano quindi le +funzioni fornite nell'implementazione di quest'ultimo, quando si apre un file +questo può essere anche un file di dispositivo, ed in questo caso il VFS +invece di usare le operazioni fornite dal filesystem (come farebbe per un file +di dati) dovrà invece ricorrere a quelle fornite dal driver del dispositivo. + +\begin{figure}[!htb] + \footnotesize \centering + \begin{minipage}[c]{\textwidth} + \includestruct{listati/file.h} + \end{minipage} + \normalsize + \caption{Estratto della struttura \kstructd{file} del kernel (da + \texttt{include/linux/fs.h}).} + \label{fig:kstruct_file} +\end{figure} + +Come si può notare dall'estratto di fig.~\ref{fig:kstruct_file}, la struttura +contiene, oltre ad alcune informazioni usate dall'interfaccia dei file +descriptor il cui significato emergerà più avanti, il puntatore \struct{f\_op} +ad una struttura \kstruct{file\_operation}. Questa è l'analoga per i file di +\kstruct{inode\_operation}, e definisce le operazioni generiche fornite dal +VFS per i file. Si sono riportate in tab.~\ref{tab:file_file_operations} le +più significative. + +\begin{table}[htb] + \centering + \footnotesize + \begin{tabular}[c]{|l|p{8cm}|} + \hline + \textbf{Funzione} & \textbf{Operazione} \\ + \hline + \hline + \textsl{\code{open}} & Apre il file (vedi sez.~\ref{sec:file_open}).\\ + \textsl{\code{read}} & Legge dal file (vedi sez.~\ref{sec:file_read}).\\ + \textsl{\code{write}} & Scrive sul file (vedi + sez.~\ref{sec:file_write}).\\ + \textsl{\code{llseek}} & Sposta la posizione corrente sul file (vedi + sez.~\ref{sec:file_lseek}).\\ + \textsl{\code{ioctl}} & Accede alle operazioni di controllo + (vedi sez.~\ref{sec:file_ioctl}).\\ + \textsl{\code{readdir}}& Legge il contenuto di una directory (vedi + sez.~\ref{sec:file_dir_read}).\\ + \textsl{\code{poll}} & Usata nell'I/O multiplexing (vedi + sez.~\ref{sec:file_multiplexing}).\\ + \textsl{\code{mmap}} & Mappa il file in memoria (vedi + sez.~\ref{sec:file_memory_map}).\\ + \textsl{\code{release}}& Chiamata quando l'ultimo riferimento a un file + aperto è chiuso.\\ + \textsl{\code{fsync}} & Sincronizza il contenuto del file (vedi + sez.~\ref{sec:file_sync}).\\ + \textsl{\code{fasync}} & Abilita l'I/O asincrono (vedi + sez.~\ref{sec:file_asyncronous_io}) sul file.\\ + \hline + \end{tabular} + \caption{Operazioni sui file definite tramite \kstruct{file\_operation}.} + \label{tab:file_file_operations} +\end{table} + +Anche in questo caso tutte le volte che deve essere eseguita una +\textit{system call} o una qualunque altra operazione sul file il VFS andrà ad +utilizzare la funzione corrispondente attraverso il puntatore +\var{f\_op}. Dato che è cura del VFS quando crea la struttura all'apertura del +file, assegnare a \var{f\_op} il puntatore alla versione di +\kstruct{file\_operation} corretta per quel file, sarà possibile scrivere allo +stesso modo sulla porta seriale come su un normale file di dati, e lavorare +sui file allo stesso modo indipendentemente dal filesystem. + +Il VFS realizza la quasi totalità delle operazioni relative ai file grazie +alle funzioni presenti nelle due strutture \kstruct{inode\_operation} +\kstruct{file\_operation}. Ovviamente non è detto che tutte le operazioni +possibili siano poi disponibili in tutti i casi, ad esempio una \code{seek} +non è realizzabile per un dispositivo come la porta seriale o per una fifo, +mentre sui file del filesystem \texttt{vfat} non sono disponibili i permessi, +ma resta il fatto che grazie al VFS le \textit{system call} per le operazioni +sui file restano sempre le stesse nonostante le enormi differenze che possono +esserci negli oggetti a cui si applicano. + + +\itindend{Virtual~File~System} + + +\subsection{Il funzionamento di un filesystem Unix} +\label{sec:file_filesystem} + +Come già accennato in sez.~\ref{sec:file_arch_overview} Linux (ed ogni sistema +unix-like) organizza i dati che tiene su disco attraverso l'uso di un +filesystem. Una delle caratteristiche di Linux rispetto agli altri Unix è +quella di poter supportare, grazie al VFS, una enorme quantità di filesystem +diversi, ognuno dei quali avrà una sua particolare struttura e funzionalità +proprie. Per questo non entreremo nei dettagli di un filesystem specifico, ma +daremo una descrizione a grandi linee che si adatta alle caratteristiche +comuni di qualunque filesystem di un sistema unix-like. + +Lo spazio fisico di un disco viene usualmente diviso in partizioni; ogni +partizione può contenere un filesystem. Una possibile strutturazione +dell'informazione su un disco è riportata in fig.~\ref{fig:file_disk_filesys}, +in essa per semplicità si è fatto riferimento alla struttura del filesystem +\acr{ext2}, che prevede una separazione dei dati in \textit{block group} che +replicano il cosiddetto \textit{superblock} (sulle caratteristiche di +\acr{ext2} e derivati torneremo in sez.~\ref{sec:file_ext2}). È comunque +caratteristica comune di tutti i filesystem per Unix, indipendentemente da +come poi viene strutturata nei dettagli questa informazione, prevedere una +divisione fra la lista degli \itindex{inode} \textit{inode} e lo spazio a +disposizione per i dati e le directory.\footnote{questo non è del tutto vero + per filesystem evoluti come \textsl{btrfs}, ma per il momento limitiamoci + alla implementazione classica.} + +\begin{figure}[!htb] + \centering + \includegraphics[width=14cm]{img/disk_struct} + \caption{Organizzazione dello spazio su un disco in partizioni e + filesystem.} + \label{fig:file_disk_filesys} +\end{figure} + +Se si va ad esaminare con maggiore dettaglio la strutturazione +dell'informazione all'interno del singolo filesystem, tralasciando i dettagli +relativi al funzionamento del filesystem stesso come la strutturazione in +gruppi dei blocchi, il superblock e tutti i dati di gestione possiamo +esemplificare la situazione con uno schema come quello esposto in +fig.~\ref{fig:file_filesys_detail}. + +\begin{figure}[!htb] + \centering + \includegraphics[width=14cm]{img/filesys_struct} + \caption{Strutturazione dei dati all'interno di un filesystem.} + \label{fig:file_filesys_detail} +\end{figure} + +Da fig.~\ref{fig:file_filesys_detail} si evidenziano alcune delle +caratteristiche di base di un filesystem, sulle quali è bene porre attenzione +visto che sono fondamentali per capire il funzionamento delle funzioni che +manipolano i file e le directory che tratteremo nel prossimo capitolo; in +particolare è opportuno ricordare sempre che: + +\begin{enumerate} + +\item L'\textit{inode} \itindex{inode} contiene tutte le informazioni (i + cosiddetti \textsl{metadati}) riguardanti il file: il tipo di file, i + permessi di accesso, le dimensioni, i puntatori ai blocchi fisici che + contengono i dati e così via. Le informazioni che la funzione \func{stat} + (vedi sez.~\ref{sec:file_stat}) fornisce provengono dall'\textit{inode}. + Dentro una directory si troverà solo il nome del file e il numero + \itindex{inode} dell'\textit{inode} ad esso associato, cioè quella che da + qui in poi chiameremo una \textsl{voce} (come traduzione dell'inglese + \textit{directory entry}, che non useremo anche per evitare confusione con + le \textit{dentry} del kernel di cui si parlava in + sez.~\ref{sec:file_vfs_work}). + +\item Come mostrato in fig.~\ref{fig:file_filesys_detail} si possono avere più + voci che puntano allo stesso \textit{inode}. Ogni \textit{inode} ha un + contatore che contiene il numero di riferimenti che sono stati fatti ad esso + (il cosiddetto \textit{link count}); solo quando questo contatore si annulla + i dati del file vengono effettivamente rimossi dal disco. Per questo la + funzione per cancellare un file si chiama \func{unlink} (vedi + sez.~\ref{sec:file_link}), ed in realtà non cancella affatto i dati del + file, ma si limita ad eliminare la relativa voce da una directory e + decrementare il numero di riferimenti \itindex{inode} nell'\textit{inode}. + +\item Il numero di \textit{inode} nella voce si riferisce ad un \textit{inode} + nello stesso filesystem e non ci può essere una directory che contiene + riferimenti ad \itindex{inode} \textit{inode} relativi ad altri filesystem. + Questo limita l'uso del comando \cmd{ln} (che crea una nuova voce per un + file esistente con la funzione \func{link}) al filesystem corrente. + +\item Quando si cambia nome ad un file senza cambiare filesystem, il contenuto + del file non viene spostato fisicamente, viene semplicemente creata una + nuova voce per \itindex{inode} l'\textit{inode} in questione e rimossa la + vecchia (questa è la modalità in cui opera normalmente il comando \cmd{mv} + attraverso la funzione \func{rename}, vedi + sez.~\ref{sec:file_remove}). Questa operazione non modifica minimamente + neanche l'\textit{inode} del file dato che non si opera su questo ma sulla + directory che lo contiene. + +\item Gli \textit{inode} dei file, che contengono i \textsl{metadati} ed i + blocchi di spazio disco, che contengono i dati, sono risorse indipendenti ed + in genere vengono gestite come tali anche dai diversi filesystem; è pertanto + possibile sia esaurire lo spazio disco (caso più comune) che lo spazio 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. + +\end{enumerate} + +Infine si noti che, essendo file pure loro, il numero di riferimenti esiste +anche per le directory; per cui, se a partire dalla situazione mostrata in +fig.~\ref{fig:file_filesys_detail} creiamo una nuova directory \file{img} +nella directory \file{gapil}, avremo una situazione come quella in +fig.~\ref{fig:file_dirs_link}, dove per chiarezza abbiamo aggiunto dei numeri +di \itindex{inode} inode. + +\begin{figure}[!htb] + \centering + \includegraphics[width=14cm]{img/dir_links} + \caption{Organizzazione dei \textit{link} per le directory.} + \label{fig:file_dirs_link} +\end{figure} + +La nuova directory avrà allora un numero di riferimenti pari a due, in quanto +è referenziata dalla directory da cui si era partiti (in cui è inserita la +nuova voce che fa riferimento a \texttt{img}) e dalla voce ``\texttt{.}'' che +è sempre inserita in ogni directory; questo vale sempre per ogni directory che +non contenga a sua volta altre directory. Al contempo, la directory da cui si +era partiti avrà un numero di riferimenti di almeno tre, in quanto adesso sarà +referenziata anche dalla voce ``\texttt{..}'' di \texttt{img}. + + +\subsection{I filesystem di uso comune} +\label{sec:file_ext2} + +Il filesystem standard più usato con Linux è il cosiddetto \textit{third + extended filesystem}, identificato dalla sigla \acr{ext3}.\footnote{si fa + riferimento al momento della stesura di questo paragrafo, l'inizio del + 2010.} Esso nasce come evoluzione del precedente \textit{second extended + filesystem}, o \acr{ext2}, di cui eredita gran parte delle caratteristiche +di base, per questo motivo parleremo anzitutto di questo, dato che molto di +quanto diremo si applica anche ad \acr{ext3}. A partire dal kernel 2.6.XX è +stato dichiarato stabile il nuovo filsesystem \textit{ext4}, ulteriore +evoluzione di \textit{ext3} dotato di molte caratteristiche avanzate, che sta +iniziando a sostituirlo gradualmente. + +Il filesystem \acr{ext2} nasce come filesystem nativo di Linux a partire dalle +prime versioni del kernel e supporta tutte le caratteristiche di un filesystem +standard Unix: è in grado di gestire nomi di file lunghi (256 caratteri, +estensibili a 1012) e supporta una dimensione massima dei file fino a 4~Tb. I +successivi filesystem \acr{ext3} ed \acr{ext4} sono evoluzioni di questo +filesystem, e sia pure con molti miglioramenti ed estensioni significative ne +mantengono in sostanza 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} +\item i \textit{file attributes} consentono di modificare il comportamento del + kernel quando agisce su gruppi di file. Possono essere impostati su file e + directory e in quest'ultimo caso i nuovi file creati nella directory + ereditano i suoi attributi. +\item sono supportate entrambe le semantiche di BSD e SVr4 come opzioni di + montaggio. La semantica BSD comporta che i file in una directory sono creati + con lo stesso identificatore di gruppo della directory che li contiene. La + semantica SVr4 comporta che i file vengono creati con l'identificatore del + gruppo primario del processo, eccetto il caso in cui la directory ha il bit + di \acr{sgid} impostato (per una descrizione dettagliata del significato di + questi termini si veda sez.~\ref{sec:file_access_control}), nel qual caso + file e subdirectory ereditano sia il \acr{gid} che lo \acr{sgid}. +\item l'amministratore può scegliere la dimensione dei blocchi del filesystem + in fase di creazione, a seconda delle sue esigenze (blocchi più grandi + permettono un accesso più veloce, ma sprecano più spazio disco). +\item il filesystem implementa link simbolici veloci, in cui il nome del file + non è salvato su un blocco, ma tenuto all'interno \itindex{inode} dell'inode + (evitando letture multiple e spreco di spazio), non tutti i nomi però + possono essere gestiti così per limiti di spazio (il limite è 60 caratteri). +\item vengono supportati i file immutabili (che possono solo essere letti) per + la protezione di file di configurazione sensibili, o file + \textit{append-only} che possono essere aperti in scrittura solo per + aggiungere dati (caratteristica utilizzabile per la protezione dei file di + log). +\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 +riportata in fig.~\ref{fig:file_filesys_detail}, in cui la partizione è divisa +in gruppi di blocchi.\footnote{non si confonda questa definizione con + quella riportata in fig.~\ref{fig:file_dirent_struct}; in quel caso si fa + riferimento alla struttura usata in user space per riportare i dati + contenuti in una directory generica, questa fa riferimento alla struttura + usata dal kernel per un filesystem \acr{ext2}, definita nel file + \texttt{ext2\_fs.h} nella directory \texttt{include/linux} dei sorgenti del + kernel.} + +Ciascun gruppo di blocchi contiene una copia delle informazioni essenziali del +filesystem (superblock e descrittore del filesystem sono quindi ridondati) per +una maggiore affidabilità e possibilità di recupero in caso di corruzione del +superblock principale. L'utilizzo di raggruppamenti di blocchi ha inoltre +degli effetti positivi nelle prestazioni dato che viene ridotta la distanza +fra i dati e la tabella degli \itindex{inode} inode. + +\begin{figure}[!htb] + \centering + \includegraphics[width=9cm]{img/dir_struct} + \caption{Struttura delle directory nel \textit{second extented filesystem}.} + \label{fig:file_ext2_dirs} +\end{figure} + +Le directory sono implementate come una \itindex{linked~list} \textit{linked + list} con voci di dimensione variabile. Ciascuna voce della lista contiene +il numero di inode \itindex{inode}, la sua lunghezza, il nome del file e la sua +lunghezza, secondo lo schema in fig.~\ref{fig:file_ext2_dirs}; in questo modo +è possibile implementare nomi per i file anche molto lunghi (fino a 1024 +caratteri) senza sprecare spazio disco. + +Con l'introduzione del filesystem \textit{ext3} sono state introdotte anche +alcune modifiche strutturali, la principale di queste è quella che +\textit{ext3} è un filesystem \textit{jounrnaled}, è cioè in grado di eseguire +una registrazione delle operazioni di scrittura su un giornale (uno speciale +file interno) in modo da poter garantire il ripristino della coerenza dei dati +del filesystem\footnote{si noti bene che si è parlato di dati \textsl{del} + filesystem, non di dati \textsl{nel} filesystem, quello di cui viene + garantito un veloce ripristino è relativo ai dati della struttura interna + del filesystem, non di eventuali dati contenuti nei file che potrebbero + essere stati persi.} in brevissimo tempo in caso di interruzione improvvisa +della corrente o di crollo del sistema che abbia causato una interruzione +della scrittura dei dati sul disco. + +Oltre a questo \textit{ext3} introduce ulteriori modifiche volte a migliorare +sia le prestazioni che la semplicità di gestione del filesystem, in +particolare per le directory si è passato all'uso di alberi binari con +indicizzazione tramite hash al posto delle \textit{linked list}, ottenendo un +forte guadagno di prestazioni in caso di directory contenenti un gran numero +di file. + +% TODO portare a ext3, ext4 e btrfs ed illustrare le problematiche che si +% possono incontrare (in particolare quelle relative alla perdita di contenuti +% in caso di crash del sistema) + + +\subsection{La gestione dei filesystem} +\label{sec:sys_file_config} + +Come accennato in sez.~\ref{sec:file_arch_overview} per poter accedere ai file +occorre prima rendere disponibile al sistema il filesystem su cui essi sono +memorizzati; l'operazione di attivazione del filesystem è chiamata +\textsl{montaggio}, per far questo in Linux\footnote{la funzione è specifica + di Linux e non è portabile.} si usa la funzione \funcd{mount} il cui +prototipo è: +\begin{prototype}{sys/mount.h} +{mount(const char *source, const char *target, const char *filesystemtype, + unsigned long mountflags, const void *data)} + +Monta il filesystem di tipo \param{filesystemtype} contenuto in \param{source} +sulla directory \param{target}. + + \bodydesc{La funzione ritorna 0 in caso di successo e -1 in caso di + fallimento, nel qual caso gli errori comuni a tutti i filesystem che possono + essere restituiti in \var{errno} sono: + \begin{errlist} + \item[\errcode{EPERM}] il processo non ha i privilegi di amministratore. + \item[\errcode{ENODEV}] \param{filesystemtype} non esiste o non è configurato + nel kernel. + \item[\errcode{ENOTBLK}] non si è usato un \textit{block device} per + \param{source} quando era richiesto. + \item[\errcode{EBUSY}] \param{source} è già montato, o non può essere + rimontato in read-only perché ci sono ancora file aperti in scrittura, o + \param{target} è ancora in uso. + \item[\errcode{EINVAL}] il device \param{source} presenta un + \textit{superblock} non valido, o si è cercato di rimontare un filesystem + non ancora montato, o di montarlo senza che \param{target} sia un + \itindex{mount~point} \textit{mount point} o di spostarlo + quando \param{target} non è un \itindex{mount~point} \textit{mount point} + o è \file{/}. + \item[\errcode{EACCES}] non si ha il permesso di accesso su uno dei + componenti del \itindex{pathname} \textit{pathname}, o si è cercato + di montare un filesystem disponibile in sola lettura senza averlo + specificato o il device \param{source} è su un filesystem montato con + l'opzione \const{MS\_NODEV}. + \item[\errcode{ENXIO}] il \itindex{major~number} \textit{major number} del + device \param{source} è sbagliato. + \item[\errcode{EMFILE}] la tabella dei device \textit{dummy} è piena. + \end{errlist} + ed inoltre \errval{ENOTDIR}, \errval{EFAULT}, \errval{ENOMEM}, + \errval{ENAMETOOLONG}, \errval{ENOENT} o \errval{ELOOP}.} +\end{prototype} + +La funzione monta sulla directory \param{target}, detta \itindex{mount~point} +\textit{mount point}, il filesystem contenuto in \param{source}. In generale +un filesystem è contenuto su un disco, e l'operazione di montaggio corrisponde +a rendere visibile al sistema il contenuto del suddetto disco, identificato +attraverso il file di dispositivo ad esso associato. + +Ma la struttura del \textit{Virtual File System} vista in +sez.~\ref{sec:file_vfs_work} è molto più flessibile e può essere usata anche +per oggetti 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 un filesystem, inoltre alcuni filesystem, come \file{proc} o +\file{devfs} sono del tutto virtuali, i loro dati sono generati al volo ad +ogni lettura, e passati al kernel ad ogni scrittura. + +Il tipo di filesystem è specificato da \param{filesystemtype}, che deve essere +una delle stringhe riportate nel file \procfile{/proc/filesystems}, che +contiene l'elenco dei filesystem supportati dal kernel; nel caso si sia +indicato uno dei filesystem virtuali, il contenuto di \param{source} viene +ignorato. + +Dopo l'esecuzione della funzione il contenuto del filesystem viene resto +disponibile nella directory specificata come \itindex{mount~point} +\textit{mount point}, il precedente contenuto di detta directory viene +mascherato dal contenuto della directory radice del filesystem montato. + +Dal kernel 2.4.x inoltre è divenuto possibile sia spostare atomicamente un +\itindex{mount~point} \textit{mount point} da una directory ad un'altra, sia +montare in diversi \itindex{mount~point} \textit{mount point} lo stesso +filesystem, sia montare più filesystem sullo stesso \itindex{mount~point} +\textit{mount point} (nel qual caso vale quanto appena detto, e solo il +contenuto dell'ultimo filesystem montato sarà visibile). + +Ciascun filesystem è dotato di caratteristiche specifiche che possono essere +attivate o meno, alcune di queste sono generali (anche se non è detto siano +disponibili in ogni filesystem), e vengono specificate come opzioni di +montaggio con l'argomento \param{mountflags}. + +In Linux \param{mountflags} deve essere un intero a 32 bit i cui 16 più +significativi sono un \itindex{magic~number} \textit{magic + number}\footnote{che nel caso è \code{0xC0ED}, si può usare la costante + \const{MS\_MGC\_MSK} per ottenere la parte di \param{mountflags} riservata + al \textit{magic number}.} mentre i 16 meno significativi sono usati per +specificare le opzioni; essi sono usati come maschera binaria e vanno +impostati con un OR aritmetico della costante \const{MS\_MGC\_VAL} con i +valori riportati in tab.~\ref{tab:sys_mount_flags}. + +\begin{table}[htb] + \footnotesize + \centering + \begin{tabular}[c]{|l|r|l|} + \hline + \textbf{Parametro} & \textbf{Valore}&\textbf{Significato}\\ + \hline + \hline + \const{MS\_RDONLY} & 1 & Monta in sola lettura.\\ + \const{MS\_NOSUID} & 2 & Ignora i bit \itindex{suid~bit} \acr{suid} e + \itindex{sgid~bit} \acr{sgid}.\\ + \const{MS\_NODEV} & 4 & Impedisce l'accesso ai file di dispositivo.\\ + \const{MS\_NOEXEC} & 8 & Impedisce di eseguire programmi.\\ + \const{MS\_SYNCHRONOUS}& 16 & Abilita la scrittura sincrona.\\ + \const{MS\_REMOUNT} & 32 & Rimonta il filesystem cambiando le opzioni.\\ + \const{MS\_MANDLOCK} & 64 & Consente il \textit{mandatory locking} + \itindex{mandatory~locking} (vedi + sez.~\ref{sec:file_mand_locking}).\\ + \const{S\_WRITE} & 128 & Scrive normalmente.\\ + \const{S\_APPEND} & 256 & Consente la scrittura solo in + \itindex{append~mode} \textit{append mode} + (vedi sez.~\ref{sec:file_sharing}).\\ + \const{S\_IMMUTABLE} & 512 & Impedisce che si possano modificare i file.\\ + \const{MS\_NOATIME} &1024 & Non aggiorna gli \textit{access time} (vedi + sez.~\ref{sec:file_file_times}).\\ + \const{MS\_NODIRATIME}&2048 & Non aggiorna gli \textit{access time} delle + directory.\\ + \const{MS\_BIND} &4096 & Monta il filesystem altrove.\\ + \const{MS\_MOVE} &8192 & Sposta atomicamente il punto di montaggio.\\ + \hline + \end{tabular} + \caption{Tabella dei codici dei flag di montaggio di un filesystem.} + \label{tab:sys_mount_flags} +\end{table} + +% TODO aggiornare con i nuovi flag di man mount +% gli S_* non esistono più come segnalato da Alessio... +% verificare i readonly mount bind del 2.6.26 + +Per l'impostazione delle caratteristiche particolari di ciascun filesystem si +usa invece l'argomento \param{data} che serve per passare le ulteriori +informazioni necessarie, che ovviamente variano da filesystem a filesystem. + +La funzione \func{mount} può essere utilizzata anche per effettuare il +\textsl{rimontaggio} di un filesystem, cosa che permette di cambiarne al volo +alcune delle caratteristiche di funzionamento (ad esempio passare da sola +lettura a lettura/scrittura). Questa operazione è attivata attraverso uno dei +bit di \param{mountflags}, \const{MS\_REMOUNT}, che se impostato specifica che +deve essere effettuato il rimontaggio del filesystem (con le opzioni +specificate dagli altri bit), anche in questo caso il valore di \param{source} +viene ignorato. + +Una volta che non si voglia più utilizzare un certo filesystem è possibile +\textsl{smontarlo} usando la funzione \funcd{umount}, il cui prototipo è: +\begin{prototype}{sys/mount.h}{umount(const char *target)} + + Smonta il filesystem montato sulla directory \param{target}. + + \bodydesc{La funzione ritorna 0 in caso di successo e -1 in caso di + fallimento, nel qual caso \var{errno} assumerà uno dei valori: + \begin{errlist} + \item[\errcode{EPERM}] il processo non ha i privilegi di amministratore. + \item[\errcode{EBUSY}] \param{target} è la directory di lavoro di qualche + processo, o contiene dei file aperti, o un altro mount point. + \end{errlist} + ed inoltre \errval{ENOTDIR}, \errval{EFAULT}, \errval{ENOMEM}, + \errval{ENAMETOOLONG}, \errval{ENOENT} o \errval{ELOOP}.} +\end{prototype} +\noindent la funzione prende il nome della directory su cui il filesystem è +montato e non il file o il dispositivo che è stato montato,\footnote{questo è + vero a partire dal kernel 2.3.99-pre7, prima esistevano due chiamate + separate e la funzione poteva essere usata anche specificando il file di + dispositivo.} in quanto con il kernel 2.4.x è possibile montare lo stesso +dispositivo in più punti. Nel caso più di un filesystem sia stato montato +sullo stesso \itindex{mount~point} \textit{mount point} viene smontato quello +che è stato montato per ultimo. + +Si tenga presente che la funzione fallisce quando il filesystem è +\textsl{occupato}, questo avviene quando ci sono ancora file aperti sul +filesystem, se questo contiene la directory di lavoro corrente di un qualunque +processo o il \itindex{mount~point} \textit{mount point} di un altro +filesystem; in questo caso l'errore restituito è \errcode{EBUSY}. + +Linux provvede inoltre una seconda funzione, \funcd{umount2}, che in alcuni +casi permette di forzare lo smontaggio di un filesystem, anche quando questo +risulti occupato; il suo prototipo è: +\begin{prototype}{sys/mount.h}{umount2(const char *target, int flags)} + + La funzione è identica a \func{umount} per comportamento e codici di errore, + ma con \param{flags} si può specificare se forzare lo smontaggio. +\end{prototype} + +Il valore di \param{flags} è una maschera binaria, e al momento l'unico valore +definito è il bit \const{MNT\_FORCE}; gli altri bit devono essere nulli. +Specificando \const{MNT\_FORCE} la funzione cercherà di liberare il filesystem +anche se è occupato per via di una delle condizioni descritte in precedenza. A +seconda del tipo di filesystem alcune (o tutte) possono essere superate, +evitando l'errore di \errcode{EBUSY}. In tutti i casi prima dello smontaggio +viene eseguita una sincronizzazione dei dati. + +% TODO documentare MNT_DETACH e MNT_EXPIRE ... + +Altre due funzioni specifiche di Linux,\footnote{esse si trovano anche su BSD, + ma con una struttura diversa.} utili per ottenere in maniera diretta +informazioni riguardo al filesystem su cui si trova un certo file, sono +\funcd{statfs} e \funcd{fstatfs}, i cui prototipi sono: +\begin{functions} + \headdecl{sys/vfs.h} + \funcdecl{int statfs(const char *path, struct statfs *buf)} + + \funcdecl{int fstatfs(int fd, struct statfs *buf)} + + Restituisce in \param{buf} le informazioni relative al filesystem su cui è + posto il file specificato. + + \bodydesc{Le funzioni ritornano 0 in caso di successo e -1 in caso di + errore, nel qual caso \var{errno} assumerà uno dei valori: + \begin{errlist} + \item[\errcode{ENOSYS}] il filesystem su cui si trova il file specificato non + supporta la funzione. + \end{errlist} + e \errval{EFAULT} ed \errval{EIO} per entrambe, \errval{EBADF} per + \func{fstatfs}, \errval{ENOTDIR}, \errval{ENAMETOOLONG}, \errval{ENOENT}, + \errval{EACCES}, \errval{ELOOP} per \func{statfs}.} +\end{functions} + +Queste funzioni permettono di ottenere una serie di informazioni generali +riguardo al filesystem su cui si trova il file specificato; queste vengono +restituite all'indirizzo \param{buf} di una struttura \struct{statfs} definita +come in fig.~\ref{fig:sys_statfs}, ed i campi che sono indefiniti per il +filesystem in esame sono impostati a zero. I valori del campo \var{f\_type} +sono definiti per i vari filesystem nei relativi file di header dei sorgenti +del kernel da costanti del tipo \var{XXX\_SUPER\_MAGIC}, dove \var{XXX} in +genere è il nome del filesystem stesso. + +\begin{figure}[!htb] + \footnotesize \centering + \begin{minipage}[c]{\textwidth} + \includestruct{listati/statfs.h} + \end{minipage} + \normalsize + \caption{La struttura \structd{statfs}.} + \label{fig:sys_statfs} +\end{figure} + + +Le \acr{glibc} provvedono infine una serie di funzioni per la gestione dei due +file \conffile{/etc/fstab} ed \conffile{/etc/mtab}, che convenzionalmente sono +usati in quasi tutti i sistemi unix-like per mantenere rispettivamente le +informazioni riguardo ai filesystem da montare e a quelli correntemente +montati. Le funzioni servono a leggere il contenuto di questi file in +opportune strutture \struct{fstab} e \struct{mntent}, e, per +\conffile{/etc/mtab} per inserire e rimuovere le voci presenti nel file. + +In generale si dovrebbero usare queste funzioni (in particolare quelle +relative a \conffile{/etc/mtab}), quando si debba scrivere un programma che +effettua il montaggio di un filesystem; in realtà in questi casi è molto più +semplice invocare direttamente il programma \cmd{mount}, per cui ne +tralasceremo la trattazione, rimandando al manuale delle \acr{glibc} +\cite{glibc} per la documentazione completa. + +% TODO scrivere relativamente alle varie funzioni (getfsent e getmntent &C) +% TODO documentare swapon e swapoff (man 2 ...) + + @@ -48,9 +860,8 @@ chiamandolo con nomi diversi o accedendovi da directory diverse. Questo è possibile anche in ambiente Unix, dove tali collegamenti sono usualmente chiamati \textit{link}; ma data l'architettura del sistema riguardo -la gestione dei file (ed in particolare quanto trattato in -sez.~\ref{sec:file_arch_func}) ci sono due metodi sostanzialmente diversi per -fare questa operazione. +la gestione dei file ci sono due metodi sostanzialmente diversi per fare +questa operazione. Come spiegato in sez.~\ref{sec:file_filesystem} l'accesso al contenuto di un file su disco avviene passando attraverso il suo \itindex{inode} @@ -80,7 +891,8 @@ diretto, o \textit{hard link}. Il prototipo della funzione è il seguente: errore nel qual caso \var{errno} viene impostata ai valori: \begin{errlist} \item[\errcode{EXDEV}] i file \param{oldpath} e \param{newpath} non fanno - riferimento ad un filesystem montato sullo stesso \textit{mount point}. + riferimento ad un filesystem montato sullo stesso \itindex{mount~point} + \textit{mount point}. \item[\errcode{EPERM}] il filesystem che contiene \param{oldpath} e \param{newpath} non supporta i link diretti o è una directory. \item[\errcode{EEXIST}] un file (o una directory) di nome \param{newpath} @@ -110,9 +922,9 @@ supportare i collegamenti diretti (il meccanismo non è disponibile ad esempio con il filesystem \acr{vfat} di Windows). In realtà la funzione ha un ulteriore requisito, e cioè che non solo che i due file siano sullo stesso filesystem, ma anche che si faccia riferimento ad essi sullo stesso -\textit{mount point}.\footnote{si tenga presente infatti (vedi - sez.~\ref{sec:sys_file_config}) che a partire dal kernel 2.4 uno stesso - filesystem può essere montato più volte su directory diverse.} +\itindex{mount~point} \textit{mount point}.\footnote{si tenga presente infatti + (vedi sez.~\ref{sec:sys_file_config}) che a partire dal kernel 2.4 uno + stesso filesystem può essere montato più volte su directory diverse.} La funzione inoltre opera sia sui file ordinari che sugli altri oggetti del filesystem, con l'eccezione delle directory. In alcune versioni di Unix solo @@ -289,7 +1101,7 @@ nello stesso filesystem) si usa invece la funzione \funcd{rename},\footnote{la non vuota. \item[\errcode{EBUSY}] o \param{oldpath} o \param{newpath} sono in uso da parte di qualche processo (come directory di lavoro o come radice) o del - sistema (come mount point). + sistema (come \itindex{mount~point} \textit{mount point}). \item[\errcode{EINVAL}] \param{newpath} contiene un prefisso di \param{oldpath} o più in generale si è cercato di creare una directory come sotto-directory di se stessa. @@ -584,7 +1396,7 @@ La funzione che permette la cancellazione di una directory è invece \begin{errlist} \item[\errcode{EPERM}] il filesystem non supporta la cancellazione di directory, oppure la directory che contiene \param{dirname} ha lo - \itindex{sticky~bit} \textit{sticky bit} impostato e l'user-ID effettivo + \itindex{sticky~bit} \textit{sticky bit} impostato e l'\acr{uid} effettivo del processo non corrisponde al proprietario della directory. \item[\errcode{EACCES}] non c'è il permesso di scrittura per la directory che contiene la directory che si vuole cancellare, o non c'è il permesso @@ -722,9 +1534,9 @@ serie 2.4 alla serie 2.6 è stata aumentata a 32 bit la dimensione del tipo \type{dev\_t}, con delle dimensioni passate a 12 bit per il \itindex{major~number} \textit{major number} e 20 bit per il \itindex{minor~number} \textit{minor number}. La transizione però ha anche -comportato il passaggio di \type{dev\_t} a tipo opaco, e la necessità di -specificare il numero tramite delle opportune macro, così da non avere -problemi di compatibilità con eventuali ulteriori estensioni. +comportato il passaggio di \type{dev\_t} a \index{tipo!opaco} tipo opaco, e la +necessità di specificare il numero tramite delle opportune macro, così da non +avere problemi di compatibilità con eventuali ulteriori estensioni. Le macro sono definite nel file \file{sys/sysmacros.h}, che viene automaticamente incluso quando si include \file{sys/types.h}; si possono @@ -918,7 +1730,7 @@ esaurite tutte le voci in essa presenti. \begin{figure}[!htb] \footnotesize \centering - \begin{minipage}[c]{15cm} + \begin{minipage}[c]{\textwidth} \includestruct{listati/dirent.c} \end{minipage} \normalsize @@ -1156,9 +1968,9 @@ estensione\footnote{le glibc, a partire dalla versione 2.1, effettuano anche ordina i nomi tenendo conto del numero di versione (cioè qualcosa per cui \texttt{file10} viene comunque dopo \texttt{file4}.) -\begin{figure}[!htb] +\begin{figure}[!htbp] \footnotesize \centering - \begin{minipage}[c]{15.6cm} + \begin{minipage}[c]{\codesamplewidth} \includecodesample{listati/my_ls.c} \end{minipage} \caption{Esempio di codice per eseguire la lista dei file contenuti in una @@ -1195,9 +2007,9 @@ voce presente questo è sufficiente a stampare la lista completa dei file e delle relative dimensioni. Si noti infine come si restituisca sempre 0 come valore di ritorno per indicare una esecuzione senza errori. -\begin{figure}[!htb] +\begin{figure}[!htbp] \footnotesize \centering - \begin{minipage}[c]{15.6cm} + \begin{minipage}[c]{\codesamplewidth} \includecodesample{listati/DirScan.c} \end{minipage} \caption{Codice della funzione di scansione di una directory contenuta nel @@ -1616,7 +2428,7 @@ sez.~\ref{sec:file_file_times}), o per il padding dei campi. \begin{figure}[!htb] \footnotesize \centering - \begin{minipage}[c]{15cm} + \begin{minipage}[c]{\textwidth} \includestruct{listati/stat.h} \end{minipage} \normalsize @@ -1652,13 +2464,13 @@ riportato in tab.~\ref{tab:file_type_macro}. \textbf{Macro} & \textbf{Tipo del file} \\ \hline \hline - \macro{S\_ISREG(m)} & file normale.\\ - \macro{S\_ISDIR(m)} & directory.\\ - \macro{S\_ISCHR(m)} & dispositivo a caratteri.\\ - \macro{S\_ISBLK(m)} & dispositivo a blocchi.\\ - \macro{S\_ISFIFO(m)} & fifo.\\ - \macro{S\_ISLNK(m)} & link simbolico.\\ - \macro{S\_ISSOCK(m)} & socket.\\ + \macro{S\_ISREG}\texttt{(m)} & file normale.\\ + \macro{S\_ISDIR}\texttt{(m)} & directory.\\ + \macro{S\_ISCHR}\texttt{(m)} & dispositivo a caratteri.\\ + \macro{S\_ISBLK}\texttt{(m)} & dispositivo a blocchi.\\ + \macro{S\_ISFIFO}\texttt{(m)} & fifo.\\ + \macro{S\_ISLNK}\texttt{(m)} & link simbolico.\\ + \macro{S\_ISSOCK}\texttt{(m)} & socket.\\ \hline \end{tabular} \caption{Macro per i tipi di file (definite in \texttt{sys/stat.h}).} @@ -2016,7 +2828,7 @@ puntatore nullo verrà impostato il tempo corrente. \begin{figure}[!htb] \footnotesize \centering - \begin{minipage}[c]{15cm} + \begin{minipage}[c]{\textwidth} \includestruct{listati/utimbuf.h} \end{minipage} \normalsize @@ -2079,7 +2891,7 @@ puntatore nullo di nuovo verrà utilizzato il tempo corrente. \begin{figure}[!htb] \footnotesize \centering - \begin{minipage}[c]{15cm} + \begin{minipage}[c]{\textwidth} \includestruct{listati/timeval.h} \end{minipage} \normalsize @@ -2151,7 +2963,7 @@ definizione è riportata in fig.~\ref{fig:sys_timespec_struct}. \begin{figure}[!htb] \footnotesize \centering - \begin{minipage}[c]{15cm} + \begin{minipage}[c]{\textwidth} \includestruct{listati/timespec.h} \end{minipage} \normalsize @@ -2162,7 +2974,7 @@ definizione è riportata in fig.~\ref{fig:sys_timespec_struct}. Come per le precedenti funzioni il primo elemento di \param{times} indica il tempo di ultimo accesso ed il secondo quello di ultima modifica, e se si usa -il valore \const{NULL} verrà impostato il tempo corrente sia per l'ultimo +il valore \val{NULL} verrà impostato il tempo corrente sia per l'ultimo accesso che per l'ultima modifica. Nei singoli elementi di \param{times} si possono inoltre utilizzare due valori speciali per il campo \var{tv\_nsec}: con \const{UTIME\_NOW} si richiede l'uso del tempo corrente, mentre con @@ -2355,8 +3167,8 @@ veda sez.~\ref{sec:file_special_perm}). La procedura con cui il kernel stabilisce se un processo possiede un certo permesso (di lettura, scrittura o esecuzione) si basa sul confronto fra l'utente e il gruppo a cui il file appartiene (i valori di \var{st\_uid} e -\var{st\_gid} accennati in precedenza) e l'user-ID effettivo, il group-ID -effettivo e gli eventuali group-ID supplementari del processo.\footnote{in +\var{st\_gid} accennati in precedenza) e l'\acr{uid} effettivo, il \acr{gid} +effettivo e gli eventuali \acr{gid} supplementari del processo.\footnote{in realtà Linux, per quanto riguarda l'accesso ai file, utilizza gli identificatori del gruppo \textit{filesystem} (si ricordi quanto esposto in sez.~\ref{sec:proc_perms}), ma essendo questi del tutto equivalenti ai primi, @@ -2365,19 +3177,19 @@ effettivo e gli eventuali group-ID supplementari del processo.\footnote{in Per una spiegazione dettagliata degli identificatori associati ai processi si veda sez.~\ref{sec:proc_perms}; normalmente, a parte quanto vedremo in -sez.~\ref{sec:file_special_perm}, l'user-ID effettivo e il group-ID effettivo +sez.~\ref{sec:file_special_perm}, l'\acr{uid} effettivo e il \acr{gid} effettivo corrispondono ai valori dell'\acr{uid} e del \acr{gid} dell'utente che ha -lanciato il processo, mentre i group-ID supplementari sono quelli dei gruppi +lanciato il processo, mentre i \acr{gid} supplementari sono quelli dei gruppi cui l'utente appartiene. I passi attraverso i quali viene stabilito se il processo possiede il diritto di accesso sono i seguenti: \begin{enumerate} -\item Se l'user-ID effettivo del processo è zero (corrispondente +\item Se l'\acr{uid} effettivo del processo è zero (corrispondente all'amministratore) l'accesso è sempre garantito senza nessun ulteriore controllo. Per questo motivo \textsl{root} ha piena libertà di accesso a tutti i file. -\item Se l'user-ID effettivo del processo è uguale all'\acr{uid} del +\item Se l'\acr{uid} effettivo del processo è uguale all'\acr{uid} del proprietario del file (nel qual caso si dice che il processo è proprietario del file) allora: \begin{itemize*} @@ -2387,7 +3199,7 @@ di accesso sono i seguenti: impostato, l'accesso è consentito \item altrimenti l'accesso è negato \end{itemize*} -\item Se il group-ID effettivo del processo o uno dei group-ID supplementari +\item Se il \acr{gid} effettivo del processo o uno dei \acr{gid} supplementari dei processi corrispondono al \acr{gid} del file allora: \begin{itemize*} \item se il bit dei permessi d'accesso del gruppo è impostato, l'accesso è @@ -2429,9 +3241,9 @@ corrispondono a quelli dell'utente con cui si è entrati nel sistema. Se però il file del programma (che ovviamente deve essere eseguibile\footnote{per motivi di sicurezza il kernel ignora i bit \acr{suid} e \acr{sgid} per gli script eseguibili.}) ha il bit \acr{suid} impostato, il -kernel assegnerà come user-ID effettivo al nuovo processo l'\acr{uid} del +kernel assegnerà come \acr{uid} effettivo al nuovo processo l'\acr{uid} del proprietario del file al posto dell'\acr{uid} del processo originario. Avere -il bit \acr{sgid} impostato ha lo stesso effetto sul group-ID effettivo del +il bit \acr{sgid} impostato ha lo stesso effetto sul \acr{gid} effettivo del processo. I bit \acr{suid} e \acr{sgid} vengono usati per permettere agli utenti normali @@ -2528,9 +3340,9 @@ consapevolmente, cancellare i file temporanei creati degli altri utenti. \label{sec:file_perm_management} Come visto in sez.~\ref{sec:file_access_control} il controllo di accesso ad un -file viene fatto utilizzando l'user-ID ed il group-ID effettivo del processo; -ci sono casi però in cui si può voler effettuare il controllo con l'user-ID -reale ed il group-ID reale, vale a dire usando i valori di \acr{uid} e +file viene fatto utilizzando l'\acr{uid} ed il \acr{gid} effettivo del processo; +ci sono casi però in cui si può voler effettuare il controllo con l'\acr{uid} +reale ed il \acr{gid} reale, vale a dire usando i valori di \acr{uid} e \acr{gid} relativi all'utente che ha lanciato il programma, e che, come accennato in sez.~\ref{sec:file_special_perm} e spiegato in dettaglio in sez.~\ref{sec:proc_perms}, non è detto siano uguali a quelli effettivi. @@ -2621,7 +3433,7 @@ filename e su un file descriptor, i loro prototipi sono: \bodydesc{Le funzioni restituiscono zero in caso di successo e -1 per un errore, in caso di errore \var{errno} può assumere i valori: \begin{errlist} - \item[\errcode{EPERM}] l'user-ID effettivo non corrisponde a quello del + \item[\errcode{EPERM}] l'\acr{uid} effettivo non corrisponde a quello del proprietario del file o non è zero. \item[\errcode{EROFS}] il file è su un filesystem in sola lettura. \end{errlist} @@ -2685,7 +3497,7 @@ bit \itindex{suid~bit} \acr{suid} il valore da fornire sarebbe $4755$. Il cambiamento dei permessi di un file eseguito attraverso queste funzioni ha comunque alcune limitazioni, previste per motivi di sicurezza. L'uso delle -funzioni infatti è possibile solo se l'user-ID effettivo del processo +funzioni infatti è possibile solo se l'\acr{uid} effettivo del processo corrisponde a quello del proprietario del file o dell'amministratore, altrimenti esse falliranno con un errore di \errcode{EPERM}. @@ -2695,7 +3507,7 @@ non tutti i valori possibili di \param{mode} sono permessi o hanno effetto; in particolare accade che: \begin{enumerate} \item siccome solo l'amministratore può impostare lo \itindex{sticky~bit} - \textit{sticky bit}, se l'user-ID effettivo del processo non è zero esso + \textit{sticky bit}, se l'\acr{uid} effettivo del processo non è zero esso viene automaticamente cancellato (senza notifica di errore) qualora sia stato indicato in \param{mode}. \item per quanto detto in sez.~\ref{sec:file_ownership_management} riguardo la @@ -2705,7 +3517,7 @@ in particolare accade che: un file appartenente ad un gruppo per cui non si hanno diritti, questo viene automaticamente cancellato da \param{mode} (senza notifica di errore) qualora il gruppo del file non corrisponda a quelli associati al processo - (la cosa non avviene quando l'user-ID effettivo del processo è zero). + (la cosa non avviene quando l'\acr{uid} effettivo del processo è zero). \end{enumerate} Per alcuni filesystem\footnote{i filesystem più comuni (\textsl{ext2}, @@ -2779,10 +3591,10 @@ per la creazione di nuove directory (procedimento descritto in sez.~\ref{sec:file_dir_creat_rem}). Lo standard POSIX prescrive che l'\acr{uid} del nuovo file corrisponda -all'user-ID effettivo del processo che lo crea; per il \acr{gid} invece prevede +all'\acr{uid} effettivo del processo che lo crea; per il \acr{gid} invece prevede due diverse possibilità: \begin{itemize*} -\item il \acr{gid} del file corrisponde al group-ID effettivo del processo. +\item il \acr{gid} del file corrisponde al \acr{gid} effettivo del processo. \item il \acr{gid} del file corrisponde al \acr{gid} della directory in cui esso è creato. \end{itemize*} @@ -2833,7 +3645,7 @@ l'utente che il gruppo a cui un file appartiene; i rispettivi prototipi sono: \bodydesc{Le funzioni restituiscono 0 in caso di successo e -1 per un errore, nel qual caso caso \var{errno} assumerà i valori: \begin{errlist} - \item[\errcode{EPERM}] l'user-ID effettivo non corrisponde a quello del + \item[\errcode{EPERM}] l'\acr{uid} effettivo non corrisponde a quello del proprietario del file o non è zero, o utente e gruppo non sono validi \end{errlist} Oltre a questi entrambe restituiscono gli errori \errval{EROFS} e @@ -3064,7 +3876,7 @@ classi di attributi riportate in tab.~\ref{tab:extended_attribute_class}. sez.~\ref{sec:proc_capabilities}.\\ \texttt{system} & Gli \textit{extended security attributes}: sono usati dal kernel per memorizzare dati di sistema associati ai - file come le \itindex{Access~Control~List} ACL (vedi + file come le \itindex{Access~Control~List~(ACL)} ACL (vedi sez.~\ref{sec:file_ACL}) o le \itindex{capabilities} \textit{capabilities} (vedi sez.~\ref{sec:proc_capabilities}).\\ @@ -3086,13 +3898,13 @@ classi di attributi riportate in tab.~\ref{tab:extended_attribute_class}. Dato che uno degli usi degli \textit{Extended Attributes} è quello che li -impiega per realizzare delle estensioni (come le \itindex{Access~Control~List} -ACL, \index{SELinux} SELinux, ecc.) al tradizionale meccanismo dei controlli -di accesso di Unix, l'accesso ai loro valori viene regolato in maniera diversa -a seconda sia della loro classe sia di quali, fra le estensioni che li -utilizzano, sono poste in uso. In particolare, per ciascuna delle classi -riportate in tab.~\ref{tab:extended_attribute_class}, si hanno i seguenti -casi: +impiega per realizzare delle estensioni (come le +\itindex{Access~Control~List~(ACL)} ACL, \index{SELinux} SELinux, ecc.) al +tradizionale meccanismo dei controlli di accesso di Unix, l'accesso ai loro +valori viene regolato in maniera diversa a seconda sia della loro classe sia +di quali, fra le estensioni che li utilizzano, sono poste in uso. In +particolare, per ciascuna delle classi riportate in +tab.~\ref{tab:extended_attribute_class}, si hanno i seguenti casi: \begin{basedescript}{\desclabelwidth{1.7cm}\desclabelstyle{\nextlinelabel}} \item[\texttt{security}] L'accesso agli \textit{extended security attributes} dipende dalle politiche di sicurezza stabilite da loro stessi tramite @@ -3109,12 +3921,13 @@ casi: \item[\texttt{system}] Anche l'accesso agli \textit{extended system attributes} dipende dalle politiche di accesso che il kernel realizza anche utilizzando gli stessi valori in essi contenuti. Ad esempio nel caso - delle \itindex{Access~Control~List} ACL l'accesso è consentito in lettura ai - processi che hanno la capacità di eseguire una ricerca sul file (cioè hanno - il permesso di lettura sulla directory che contiene il file) ed in scrittura - al proprietario del file o ai processi dotati della \textit{capability} - \index{capabilities} \const{CAP\_FOWNER}.\footnote{vale a dire una politica - di accesso analoga a quella impiegata per gli ordinari permessi dei file.} + delle \itindex{Access~Control~List~(ACL)} ACL l'accesso è consentito in + lettura ai processi che hanno la capacità di eseguire una ricerca sul file + (cioè hanno il permesso di lettura sulla directory che contiene il file) ed + in scrittura al proprietario del file o ai processi dotati della + \textit{capability} \index{capabilities} \const{CAP\_FOWNER}.\footnote{vale + a dire una politica di accesso analoga a quella impiegata per gli ordinari + permessi dei file.} \item[\texttt{trusted}] L'accesso ai \textit{trusted extended attributes}, sia per la lettura che per la scrittura, è consentito soltanto ai processi con @@ -3376,7 +4189,7 @@ illustrate in precedenza per le altre funzioni relative agli attributi estesi. % la documentazione di sistema è nei pacchetti libacl1-dev e acl % vedi anche http://www.suse.de/~agruen/acl/linux-acls/online/ -\itindbeg{Access~Control~List} +\itindbeg{Access~Control~List~(ACL)} Il modello classico dei permessi di Unix, per quanto funzionale ed efficiente, è comunque piuttosto limitato e per quanto possa aver coperto per lunghi anni @@ -3543,15 +4356,15 @@ identificatori del gruppo \textit{effective} del processo, ma in presenza di ACL i passi attraverso i quali viene stabilito se esso ha diritto di accesso sono i seguenti: \begin{enumerate*} -\item Se l'user-ID del processo è nullo l'accesso è sempre garantito senza +\item Se l'\acr{uid} del processo è nullo l'accesso è sempre garantito senza nessun controllo. -\item Se l'user-ID del processo corrisponde al proprietario del file allora: +\item Se l'\acr{uid} del processo corrisponde al proprietario del file allora: \begin{itemize*} \item se la voce \const{ACL\_USER\_OBJ} contiene il permesso richiesto, l'accesso è consentito; \item altrimenti l'accesso è negato. \end{itemize*} -\item Se l'user-ID del processo corrisponde ad un qualunque qualificatore +\item Se l'\acr{uid} del processo corrisponde ad un qualunque qualificatore presente in una voce \const{ACL\_USER} allora: \begin{itemize*} \item se la voce \const{ACL\_USER} corrispondente e la voce @@ -3559,7 +4372,7 @@ sono i seguenti: consentito; \item altrimenti l'accesso è negato. \end{itemize*} -\item Se è il group-ID del processo o uno dei group-ID supplementari +\item Se è il \acr{gid} del processo o uno dei \acr{gid} supplementari corrisponde al gruppo proprietario del file allora: \begin{itemize*} \item se la voce \const{ACL\_GROUP\_OBJ} e una eventuale voce @@ -3568,7 +4381,7 @@ sono i seguenti: l'accesso è consentito; \item altrimenti l'accesso è negato. \end{itemize*} -\item Se è il group-ID del processo o uno dei group-ID supplementari +\item Se è il \acr{gid} del processo o uno dei \acr{gid} supplementari corrisponde ad un qualunque qualificatore presente in una voce \const{ACL\_GROUP} allora: \begin{itemize*} @@ -3605,7 +4418,7 @@ queste funzioni che prendiamo in esame è \funcd{acl\_init}, il cui prototipo Inizializza un'area di lavoro per una ACL di \param{count} voci. \bodydesc{La funzione restituisce un puntatore all'area di lavoro in caso di - successo e \const{NULL} in caso di errore, nel qual caso \var{errno} + successo e \val{NULL} in caso di errore, nel qual caso \var{errno} assumerà uno dei valori: \begin{errlist} \item[\errcode{EINVAL}] il valore di \param{count} è negativo. @@ -3619,11 +4432,12 @@ mantenere i dati di una ACL contenente fino ad un massimo di \param{count} voci. La funzione ritorna un valore di tipo \type{acl\_t}, da usare in tutte le altre funzioni che operano sulla ACL. La funzione si limita alla allocazione iniziale e non inserisce nessun valore nella ACL che resta vuota. -Si tenga presente che pur essendo \type{acl\_t} un tipo opaco che identifica -``\textsl{l'oggetto}'' ACL, il valore restituito dalla funzione non è altro -che un puntatore all'area di memoria allocata per i dati richiesti; pertanto -in caso di fallimento verrà restituito un puntatore nullo e si dovrà -confrontare il valore di ritorno della funzione con ``\code{(acl\_t) NULL}''. +Si tenga presente che pur essendo \type{acl\_t} un \index{tipo!opaco} tipo +opaco che identifica ``\textsl{l'oggetto}'' ACL, il valore restituito dalla +funzione non è altro che un puntatore all'area di memoria allocata per i dati +richiesti; pertanto in caso di fallimento verrà restituito un puntatore nullo +e si dovrà confrontare il valore di ritorno della funzione con +``\code{(acl\_t) NULL}''. Una volta che si siano completate le operazioni sui dati di una ACL la memoria allocata dovrà essere liberata esplicitamente attraverso una chiamata alla @@ -3878,7 +4692,7 @@ rappresentazione testuale della ACL, il suo prototipo è: Produce la rappresentazione testuale di una ACL. \bodydesc{La funzione restituisce il puntatore ad una stringa con la - rappresentazione testuale della ACL in caso di successo e \code{NULL} in + rappresentazione testuale della ACL in caso di successo e \val{NULL} in caso di errore, nel qual caso \var{errno} assumerà uno dei valori: \begin{errlist} \item[\errcode{ENOMEM}] non c'è memoria sufficiente per allocare i dati. @@ -3911,7 +4725,7 @@ tab.~\ref{tab:acl_to_text_options}. \hline \const{TEXT\_ABBREVIATE} & stampa le voci in forma abbreviata.\\ \const{TEXT\_NUMERIC\_IDS} & non effettua la risoluzione numerica di - user-ID e group-ID.\\ + \acr{uid} e \acr{gid}.\\ \const{TEXT\_SOME\_EFFECTIVE}& per ciascuna voce che contiene permessi che vengono eliminati dalla \const{ACL\_MASK} viene generato un commento con i permessi @@ -4144,7 +4958,7 @@ vengono utilizzati tipi di dato ad hoc.\footnote{descritti nelle singole ad un altra con \funcd{acl\_copy\_entry} o eliminare una voce da una ACL con \funcd{acl\_delete\_entry}. -\itindend{Access~Control~List} +\itindend{Access~Control~List~(ACL)} \subsection{La gestione delle quote disco} @@ -4368,7 +5182,7 @@ singolo utente. \begin{figure}[!htb] \footnotesize \centering - \begin{minipage}[c]{15cm} + \begin{minipage}[c]{\textwidth} \includestruct{listati/dqblk.h} \end{minipage} \normalsize @@ -4457,7 +5271,7 @@ fig.~\ref{fig:dqinfo_struct}. \begin{figure}[!htb] \footnotesize \centering - \begin{minipage}[c]{15cm} + \begin{minipage}[c]{\textwidth} \includestruct{listati/dqinfo.h} \end{minipage} \normalsize @@ -4506,9 +5320,9 @@ all'indirizzo \url{http://labs.truelite.it/projects/packages}.\footnote{in visionabile a partire dall'indirizzo indicato nella sezione \textit{Repository}.} -\begin{figure}[!htb] +\begin{figure}[!htbp] \footnotesize \centering - \begin{minipage}[c]{15.6cm} + \begin{minipage}[c]{\codesamplewidth} \includecodesample{listati/get_quota.c} \end{minipage} \caption{Esempio di codice per ottenere i dati delle quote.} @@ -4541,9 +5355,9 @@ relativi a uso corrente e limiti sia per i blocchi che per gli \textit{inode}. In caso di errore (\texttt{\small 13--15}) si usa un'altra funzione dell'interfaccia per passare il valore di \var{errno} come eccezione. -\begin{figure}[!htb] +\begin{figure}[!htbp] \footnotesize \centering - \begin{minipage}[c]{15.6cm} + \begin{minipage}[c]{\codesamplewidth} \includecodesample{listati/set_block_quota.c} \end{minipage} \caption{Esempio di codice per impostare i limiti sullo spazio disco.} @@ -4618,7 +5432,7 @@ 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à \macro{CAP\_SETPCAP} e cambiando le modalità di funzionamento del +capacità \const{CAP\_SETPCAP} e cambiando le modalità di funzionamento del cosiddetto \itindex{capabilities~bounding~set} \textit{capabilities bounding set}. Ulteriori modifiche sono state apportate con il kernel 2.6.26 per consentire la rimozione non ripristinabile dei privilegi di @@ -4674,7 +5488,7 @@ 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à - \macro{CAP\_SYS\_ADMIN}.} Le \textit{file capabilities} hanno effetto + \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 @@ -4687,14 +5501,14 @@ loro significato è diverso: 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è vengono tolte + 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} resta vuoto). + capacità verrà attivata (cioè l'\textit{effective set} resterà vuoto). \end{basedescript} \itindbeg{capabilities~bounding~set} @@ -4709,31 +5523,32 @@ 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 -\procfile{/proc/sys/kernel/cap-bound}. Il suo valore iniziale è definito in +\sysctlfile{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, anche se eseguito con -privilegi di amministratore,\footnote{per essere precisi occorreva la capacità - \const{CAP\_SYS\_MODULE}.} è in grado soltanto di rimuovere una delle -\textit{capabilities} già presenti dell'insieme. - -In questo caso l'effetto 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 si 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.} +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 + occorreva 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 -\procfile{/proc/sys/kernel/cap-bound} non esiste e \texttt{init} non ha nessun +\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}). @@ -4761,7 +5576,7 @@ un limite per le capacità che possono essere aggiunte all'\textit{inheritable 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 non vale 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 @@ -4772,8 +5587,8 @@ 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 -sappessero tener conto,\footnote{si ebbe un grosso problema di sicurezza con - \texttt{sendmail}: riuscendo a rimuovere \const{CAP\_SETGID} +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 @@ -4789,12 +5604,12 @@ ereditate senza modifiche attraverso una \func{fork} mentre, indicati 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 in pseudocodice C) di fig.~\ref{fig:cap_across_exec}; si +formula (espressa in pseudo-codice C) di fig.~\ref{fig:cap_across_exec}; si noti come in particolare il \textit{capabilities bounding set} non viene comunque modificato e resta lo stesso sia attraverso una \func{fork} che attraverso una \func{exec}. -\begin{figure}[!htb] +\begin{figure}[!htbp] \footnotesize \centering \begin{minipage}[c]{12cm} \includecodesnip{listati/cap-results.c} @@ -4807,36 +5622,143 @@ 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 quando viene eseguito un -file senza \textit{capabilities}, se si applicassero sempre così infatti, non -essendo definite delle capacità né nel \textit{permitted set} né -nell'\textit{inheritable set} del file, anche l'amministratore perderebbe -tutti i privilegi eventualmente avuti dal processo. - -Per questo motivo se un programma senza \textit{capabilities} viene eseguito -da un processo con \textit{real user-ID} 0, o se ha attivo il \acr{suid} bit -ed appartiene all'amministratore, esso viene trattato come se tanto il -\textit{permitted set} che l'\textit{inheritable set} fossero con tutte le -\textit{capabilities} abilitate, e con l'\textit{effective set} attivo, col -risultato di fornire comunque al processo tutte le capacità presenti nel -proprio \textit{bounding set}. - - - +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 \acr{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 \acr{uid} +nullo a \acr{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 \acr{uid} effettivo nullo a non nullo + l'\textit{effective set} del processo viene totalmente azzerato, se + viceversa si passa da \acr{uid} effettivo non nullo a nullo il + \textit{permitted set} viene copiato nell'\textit{effective set}; +\item se si passa da \textit{file system} \acr{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 \acr{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}. -Quando un programma viene messo in esecuzione\footnote{cioè quando viene - eseguita la \func{execve} con cui lo si lancia; in corrispondenza di una - \func{fork} le \textit{capabilities} non vengono modificate.} esso eredita -(nel senso che assume negli insiemi \textit{effective} e \textit{permitted}) -le \textit{capabilities} mantenute nell'insieme \textit{inherited}, a meno che -non sia eseguito un programma \acr{suid} di root o la \func{exec} sia stata -eseguita da un programma con \textsl{uid} reale zero; in tal caso il programma -ottiene tutte le \textit{capabilities} presenti nel \textit{capabilities - bounding set}. In questo modo si può far si che ad un processo eseguito in -un secondo tempo possano essere trasmesse solo un insieme limitato di -capacità, impedendogli di recuperare quelle assenti nell'insieme -\textit{inherited}. +\begin{table}[htb] + \centering + \footnotesize + \begin{tabular}{|l|p{10cm}|} + \hline + \textbf{Flag} & \textbf{Descrizione} \\ + \hline + \hline + \const{SECURE\_KEEP\_CAPS}& Il processo non subisce la cancellazione delle + sue \textit{capabilities} quando tutti i suoi + \acr{uid} passano ad un valore non + nullo (regola di compatibilità per il cambio + di \acr{uid} n.~3 del precedente + elenco), sostituisce il precedente uso + dell'operazione \const{PR\_SET\_KEEPCAPS} di + \func{prctl}.\\ + \const{SECURE\_NO\_SETUID\_FIXUP}&Il processo non subisce le modifiche + delle sue \textit{capabilities} nel passaggio + da nullo a non nullo degli \acr{uid} + dei gruppi \textit{effective} e + \textit{file system} (regole di compatibilità + per il cambio di \acr{uid} nn.~1 e 2 del + precedente elenco).\\ + \const{SECURE\_NOROOT} & Il processo non assume nessuna capacità + aggiuntiva quando esegue un programma, anche + se ha \acr{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 \const{SECURE\_KEEP\_CAPS\_LOCKED} si rende +non più modificabile \const{SECURE\_KEEP\_CAPS}, ed analogamente avviene con +\const{SECURE\_NO\_SETUID\_FIXUP\_LOCKED} per +\const{SECURE\_NO\_SETUID\_FIXUP} e con \const{SECURE\_NOROOT\_LOCKED} per +\const{SECURE\_NOROOT}. + +Per l'impostazione di questi flag sono stata 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}. % TODO verificare per process capability bounding set, vedi: % http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=3b7391de67da515c91f48aa371de77cb6cc5c07e @@ -4862,7 +5784,7 @@ che è opportuno dettagliare maggiormente. \begin{table}[!h!btp] \centering \footnotesize - \begin{tabular}{|l|p{11.9cm}|} + \begin{tabular}{|l|p{10.5cm}|} \hline \textbf{Capacità}&\textbf{Descrizione}\\ \hline @@ -4930,7 +5852,7 @@ che è opportuno dettagliare maggiormente. intercomunicazione fra processi (vedi sez.~\ref{sec:ipc_sysv}).\\ \const{CAP\_LEASE} & La capacità di creare dei \textit{file lease} - \index{file!lease} (vedi + \itindex{file~lease} (vedi sez.~\ref{sec:file_asyncronous_lease}) pur non essendo proprietari del file (dal kernel 2.4).\\ @@ -4955,13 +5877,11 @@ che è opportuno dettagliare maggiormente. \const{CAP\_SETPCAP} & La capacità di modifiche privilegiate alle \textit{capabilities}.\\ \const{CAP\_SYS\_ADMIN} & La capacità di eseguire una serie di compiti - amministrativi. \\ + amministrativi.\\ \const{CAP\_SYS\_BOOT} & La capacità di fare eseguire un riavvio del - sistema.\\ -% TODO trattare reboot e kexec + sistema (vedi sez.~\ref{sec:sys_reboot}).\\ \const{CAP\_SYS\_CHROOT}& La capacità di eseguire la funzione - \func{chroot} (vedi - sez.~\ref{sec:file_chroot}).\\ + \func{chroot} (vedi sez.~\ref{sec:file_chroot}).\\ \const{CAP\_MAC\_ADMIN} & La capacità amministrare il \textit{Mandatory Access Control} di Smack (dal kernel 2.6.25).\\ \const{CAP\_MAC\_OVERRIDE}& La capacità evitare il \textit{Mandatory @@ -4969,7 +5889,7 @@ che è opportuno dettagliare maggiormente. \const{CAP\_SYS\_MODULE}& La capacità di caricare e rimuovere moduli del kernel.\\ \const{CAP\_SYS\_NICE} & La capacità di modificare le varie priorità dei - processi.\\ + processi (vedi sez.~\ref{sec:proc_priority}).\\ \const{CAP\_SYS\_PACCT} & La capacità di usare le funzioni di \textit{accounting} dei processi (vedi sez.~\ref{sec:sys_bsd_accounting}).\\ @@ -4991,8 +5911,8 @@ che è opportuno dettagliare maggiormente. introdotta dal kernel 2.6.38 come capacità separata da \const{CAP\_SYS\_ADMIN}.\\ \const{CAP\_WAKE\_ALARM}& La capacità di usare i timer di tipo - \macro{CLOCK\_BOOTTIME\_ALARM} e - \macro{CLOCK\_REALTIME\_ALARM}, vedi + \const{CLOCK\_BOOTTIME\_ALARM} e + \const{CLOCK\_REALTIME\_ALARM}, vedi sez.~\ref{sec:sig_timer_adv} (dal kernel 3.0).\\ \hline \end{tabular} @@ -5032,13 +5952,13 @@ capacità), o di impostare i \textit{securebits} delle \textit{capabilities}. 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'user-ID effettivo del - processo (o meglio il \textit{filesystem user-ID}, vedi +operazioni;\footnote{vale a dire la richiesta che l'\acr{uid} effettivo del + processo (o meglio l'\acr{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 estesi e delle ACL (vedi -sez.~\ref{sec:file_xattr} e \ref{sec:file_ACL}), poter ignorare lo +impostazioni degli attributi dei file (vedi sez.~\ref{sec:file_ioctl}) e delle +ACL (vedi sez.~\ref{sec:file_xattr} e \ref{sec:file_ACL}), poter ignorare lo \itindex{sticky~bit} \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 @@ -5055,17 +5975,20 @@ 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:sys_file_config}), effettuare operazioni di controllo sugli -oggetti dell'IPC di SysV (vedi sez.~\ref{sec:ipc_sysv}), operare sugli -attributi estesi di classe \texttt{security} o \texttt{trusted} (vedi -sez.~\ref{sec:file_xattr}), specificare un user-ID arbitrario nella -trasmissione delle credenziali dei socket (vedi sez.~\ref{sec:socket_xxx}), -assegnare classi privilegiate per lo scheduling dell'I/O (vedi +sez.~\ref{sec:sys_file_config}), 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 \acr{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 \procfile{/proc/sys/fs/file-max}.} +di file aperti,\footnote{quello indicato da \sysctlfile{fs/file-max}.} effettuare operazioni privilegiate sulle chiavi mantenute dal kernel (vedi -sez.~\ref{sec:io_priority}), usare la funzione \func{lookup\_dcookie}, usare -\const{CLONE\_NEWNS} con \func{unshare}, (vedi sez.~\ref{sec:process_clone}). +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}). Originariamente \const{CAP\_SYS\_NICE} riguardava soltanto la capacità di aumentare le priorità di esecuzione dei processi, come la diminuzione del @@ -5083,13 +6006,9 @@ 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 (vedi sez.~\ref{sec:sys_resource_limit}) e sulle dimensioni dei -messaggi delle code del SysV IPC (vedi sez.~\ref{sec:ipc_sysv_mq}). - -Questo modo di intendere ... da fare ... per cui -a partire dal 2.6.24/5 è divenuta quella di impostare una capacità del -\textit{bounding set} nelle proprie \textit{inheritable} o rimuoverla dal -\textit{bounding set} stesso. +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}). Per la gestione delle \textit{capabilities} il kernel mette a disposizione due funzioni che permettono rispettivamente di leggere ed impostare i valori dei @@ -5120,31 +6039,31 @@ loro rispettivi prototipi sono: \end{errlist} ed inoltre \errval{EFAULT} ed \errval{EINVAL}. } - \end{functions} Queste due funzioni prendono come argomenti due tipi di dati dedicati, definiti come puntatori a due strutture specifiche di Linux, illustrate in -fig.~\ref{fig:cap_kernel_struct}. Per poterle utilizzare occorre anche -cancellare la macro \macro{\_POSIX\_SOURCE}.\footnote{per farlo occorre - utilizzare la direttiva di preprocessore \direct{undef}; si dovrà cioè - inserire una istruzione \texttt{\#undef \_POSIX\_SOURCE} prima di includere - \texttt{sys/capability.h}.} Si tenga presente che le strutture di -fig.~\ref{fig:cap_kernel_struct}, come i prototipi delle due funzioni -\func{capget} e \func{capset}, sono soggette ad essere modificate con il -cambiamento del kernel (in particolare i tipi di dati delle strutture) ed -anche se finora l'interfaccia è risultata stabile, non c'è nessuna -assicurazione che questa venga mantenuta.\footnote{anzi, visto lo scarso - utilizzo di questa funzionalità ci sono state varie discussioni fra gli - sviluppatori del kernel relative all'eliminarla o al modificarla - radicalmente.} Pertanto se si vogliono scrivere programmi portabili che -possano essere eseguiti su qualunque versione del kernel è opportuno -utilizzare le interfacce di alto livello. +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 +\texttt{sys/capability.h}) requisito che non risulta più presente.\footnote{e + non è chiaro neanche quanto sia mai stato davvero necessario.} + +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. \begin{figure}[!htb] \footnotesize \centering - \begin{minipage}[c]{15cm} + \begin{minipage}[c]{\textwidth} \includestruct{listati/cap_user_header_t.h} \end{minipage} \normalsize @@ -5155,15 +6074,26 @@ utilizzare le interfacce di alto livello. \end{figure} La struttura a cui deve puntare l'argomento \param{hdrp} serve ad indicare, -tramite il campo \var{pid}, il processo del quale si vogliono leggere o -modificare le \textit{capabilities}. Il campo \var{version} deve essere -impostato al valore della versione delle usata dal kernel (quello indicato -dalla costante \const{\_LINUX\_CAPABILITY\_VERSION} di +tramite il campo \var{pid}, il 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 PID del processo chiamante, +che sono equivalenti. 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 struttura a cui deve puntare l'argomento -\param{datap} invece conterrà i valori letti o da impostare per i tre insiemi -delle capacità del processo. +della versione in uso. La versione due è comunque deprecata e non deve essere +usata (il kernel stamperà un avviso). 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 @@ -5175,17 +6105,18 @@ una libreria a parte,\footnote{la libreria è \texttt{libcap2}, nel caso di programma le utilizza si dovrà indicare esplicitamente l'uso della suddetta libreria attraverso l'opzione \texttt{-lcap} del compilatore. -Le funzioni dell'interfaccia delle bozze di POSIX.1e prevedono l'uso di uno -tipo di dato opaco, \type{cap\_t}, come puntatore ai dati mantenuti nel -cosiddetto \textit{capability state},\footnote{si tratta in sostanza di un - puntatore ad una struttura interna utilizzata dalle librerie, i cui campi - non devono mai essere acceduti direttamente.} in sono memorizzati tutti i -dati delle \textit{capabilities}. In questo modo è possibile mascherare i -dettagli della gestione di basso livello, che potranno essere modificati senza -dover cambiare le funzioni dell'interfaccia, che faranno riferimento soltanto -ad oggetti di questo tipo. L'interfaccia pertanto non soltanto fornisce le -funzioni per modificare e leggere le \textit{capabilities}, ma anche quelle -per gestire i dati attraverso \type{cap\_t}. +Le funzioni dell'interfaccia delle bozze di POSIX.1e prevedono l'uso di un +\index{tipo!opaco} tipo di dato opaco, \type{cap\_t}, come puntatore ai dati +mantenuti nel cosiddetto \textit{capability state},\footnote{si tratta in + sostanza di un puntatore ad una struttura interna utilizzata dalle librerie, + i cui campi non devono mai essere acceduti direttamente.} in sono +memorizzati tutti i dati delle \textit{capabilities}. In questo modo è +possibile mascherare i dettagli della gestione di basso livello, che potranno +essere modificati senza dover cambiare le funzioni dell'interfaccia, che +faranno riferimento soltanto ad oggetti di questo tipo. L'interfaccia +pertanto non soltanto fornisce le funzioni per modificare e leggere le +\textit{capabilities}, ma anche quelle per gestire i dati attraverso +\type{cap\_t}. La prima funzione dell'interfaccia è quella che permette di inizializzare un \textit{capability state}, allocando al contempo la memoria necessaria per i @@ -5197,14 +6128,14 @@ relativi dati. La funzione è \funcd{cap\_init} ed il suo prototipo è: Crea ed inizializza un \textit{capability state}. \bodydesc{La funzione ritorna un valore non nullo in caso di successo e - \macro{NULL} in caso di errore, nel qual caso \var{errno} assumerà il + \val{NULL} in caso di errore, nel qual caso \var{errno} assumerà il valore \errval{ENOMEM}. } \end{functions} La funzione restituisce il puntatore \type{cap\_t} ad uno stato inizializzato con tutte le \textit{capabilities} azzerate. In caso di errore (cioè quando -non c'è memoria sufficiente ad allocare i dati) viene restituito \macro{NULL} +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 @@ -5226,10 +6157,10 @@ della libreria sia per un \textit{capability state}, nel qual caso l'argomento dovrà essere un dato di tipo \type{cap\_t}, che per una descrizione testuale dello stesso,\footnote{cioè quanto ottenuto tramite la funzione \func{cap\_to\_text}.} nel qual caso l'argomento dovrà essere un dato di -tipo \texttt{char *}. Per questo l'argomento \param{obj\_d} è dichiarato come -\texttt{void *} e deve sempre corrispondere ad un puntatore ottenuto tramite -le altre funzioni della libreria, altrimenti la funzione fallirà con un errore -di \errval{EINVAL}. +tipo \texttt{char *}. Per questo motivo l'argomento \param{obj\_d} è +dichiarato come \texttt{void *} e deve sempre 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 è: @@ -5240,7 +6171,7 @@ precedenza tramite la funzione \funcd{cap\_dup}, il cui prototipo è: Duplica un \textit{capability state} restituendone una copia. \bodydesc{La funzione ritorna un valore non nullo in caso di successo e - \macro{NULL} in caso di errore, nel qual caso \var{errno} potrà assumere i + \val{NULL} in caso di errore, nel qual caso \var{errno} potrà assumere i valori \errval{ENOMEM} o \errval{EINVAL}. } \end{functions} @@ -5274,11 +6205,82 @@ La funzione si limita ad azzerare tutte le \textit{capabilities} presenti nel restituendo uno stato \textsl{vuoto}, analogo a quello che si ottiene nella creazione con \func{cap\_init}. -Per la gestione dei valori delle \textit{capabilities} presenti in un -\textit{capability state} l'interfaccia prevede due funzioni, +\begin{table}[htb] + \centering + \footnotesize + \begin{tabular}[c]{|l|l|} + \hline + \textbf{Valore} & \textbf{Significato} \\ + \hline + \hline + \const{CAP\_EFFECTIVE} & Capacità dell'insieme \textsl{effettivo}.\\ + \const{CAP\_PERMITTED} & Capacità dell'insieme \textsl{permesso}.\\ + \const{CAP\_INHERITABLE}& Capacità dell'insieme \textsl{ereditabile}.\\ + \hline + \end{tabular} + \caption{Valori possibili per il tipo di dato \type{cap\_flag\_t} che + identifica gli insiemi delle \textit{capabilities}.} + \label{tab:cap_set_identifier} +\end{table} + +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 di pag.~\pageref{sec:capabilities_set}, il suo prototipo +è: +\begin{functions} + \headdecl{sys/capability.h} + + \funcdecl{int cap\_clear\_flag(cap\_t cap\_p, cap\_flag\_t flag)} + + Cancella dal \textit{capability state} \param{cap\_p} tutte le + \textit{capabilities} dell'insieme \param{flag}. + + \bodydesc{La funzione ritorna 0 in caso di successo e $-1$ in caso di + errore, nel qual caso \var{errno} assumerà il valore \errval{EINVAL}. } +\end{functions} + +La funzione richiede che si indichi quale degli insiemi si intente cancellare +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 \texttt{/usr/include/sys/capability.h}.} uno dei +valori illustrati in tab.~\ref{tab:cap_set_identifier}. + +Si possono inoltre confrontare in maniera diretta due diversi +\textit{capability state} con la funzione \funcd{cap\_compare}; il suo +prototipo è: +\begin{functions} + \headdecl{sys/capability.h} + \funcdecl{int cap\_compare(cap\_t cap\_a, cap\_t cap\_b)} + + Confronta due \textit{capability state}. + + \bodydesc{La funzione ritorna 0 se i \textit{capability state} sono identici + ed un valore positivo se differiscono, non sono previsti errori.} +\end{functions} + +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}: +\begin{functions} + \funcdecl{int CAP\_DIFFERS(value, flag)} Controlla lo stato di eventuali + differenze delle \textit{capabilities} nell'insieme \texttt{flag}. +\end{functions} + +La macro che richiede 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 un flag delle -\textit{capabilities}; i rispettivi prototipi sono: +rispettivamente di leggere o impostare il valore di una capacità all'interno +in uno dei tre insiemi già citati; i rispettivi prototipi sono: \begin{functions} \headdecl{sys/capability.h} @@ -5297,41 +6299,18 @@ rispettivamente di leggere o impostare il valore di un flag delle In entrambe le funzioni l'argomento \param{cap\_p} indica il puntatore al \textit{capability state} su cui operare, mentre l'argomento \param{flag} -indica su quale dei tre insiemi illustrati a -pag.~\pageref{sec:capabilities_set} si intende operare. Questi devono essere -specificati con una variabile di tipo \type{cap\_flag\_t} che può assumere -esclusivamente\footnote{si tratta in effetti di un tipo enumerato, come si può - verificare dalla sua definizione che si trova in - \texttt{/usr/include/sys/capability.h}.} uno dei valori illustrati in +indica su quale dei tre insiemi si intende operare, sempre con i valori di tab.~\ref{tab:cap_set_identifier}. -\begin{table}[htb] - \centering - \footnotesize - \begin{tabular}[c]{|l|l|} - \hline - \textbf{Valore} & \textbf{Significato} \\ - \hline - \hline - \const{CAP\_EFFECTIVE} & Capacità dell'insieme \textsl{effettivo}.\\ - \const{CAP\_PERMITTED} & Capacità dell'insieme \textsl{permesso}.\\ - \const{CAP\_INHERITABLE}& Capacità dell'insieme \textsl{ereditabile}.\\ - \hline - \end{tabular} - \caption{Valori possibili per il tipo di dato \type{cap\_flag\_t} che - identifica gli insiemi delle \textit{capabilities}.} - \label{tab:cap_set_identifier} -\end{table} - La capacità che si intende controllare o impostare invece deve essere specificata attraverso una variabile di tipo \type{cap\_value\_t}, che può prendere come valore uno qualunque di quelli riportati in tab.~\ref{tab:proc_capabilities}, in questo caso però non è possibile combinare diversi valori in una maschera binaria, una variabile di tipo -\type{cap\_value\_t} deve indicare una sola capacità.\footnote{nel file di - header citato nella nota precedente il tipo \type{cap\_value\_t} è definito - come \ctyp{int}, ma i valori validi sono soltanto quelli di - tab.~\ref{tab:proc_capabilities}.} +\type{cap\_value\_t} può indicare una sola capacità.\footnote{in + \texttt{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 @@ -5357,19 +6336,27 @@ tab.~\ref{tab:cap_value_type}. La funzione \func{cap\_get\_flag} legge lo stato della capacità indicata dall'argomento \param{cap} all'interno dell'insieme indicato dall'argomento -\param{flag} e ne restituisce il valore nella variabile posta all'indirizzo -puntato dall'argomento \param{value\_p}; è possibile cioè leggere soltanto uno -stato di una capacità alla volta. +\param{flag} lo restituisce 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. 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 -impostazione) viene indicato dall'argomento \param{value}. - -Per la visualizzazione dello stato delle \textit{capabilities} l'interfaccia -prevede una funzione apposita, \funcd{cap\_to\_text}, il cui prototipo è: +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 impostazione) 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{functions} \headdecl{sys/capability.h} @@ -5385,17 +6372,113 @@ prevede una funzione apposita, \funcd{cap\_to\_text}, il cui prototipo è: \end{functions} La funzione ritorna l'indirizzo di una stringa contente la descrizione -testuale del contenuto del \textit{capabilities state} \param{caps} passato -come argomento, e, qualora l'argomento \param{length\_p} sia diverso da -\val{NULL}, restituisce 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}. +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 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 di 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 passare ottenere un \textit{capability state} dalla sua +rappresentazione testuale si può usare \funcd{cap\_from\_text}, il cui +prototipo è: +\begin{functions} + \headdecl{sys/capability.h} + + \funcdecl{cap\_t cap\_from\_text(const char *string)} + + Crea un \textit{capability state} dalla sua rappresentazione testuale. + + \bodydesc{La funzione ritorna un puntatore valido in caso di successo e + \val{NULL} in caso di errore, nel qual caso \var{errno} può assumere i + valori \errval{EINVAL} o \errval{ENOMEM}.} +\end{functions} + +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, +\func{cap\_to\_name} e \func{cap\_from\_name}, sono estensioni specifiche di +Linux ed i rispettivi prototipi sono: +\begin{functions} + \headdecl{sys/capability.h} + + \funcdecl{char * cap\_to\_name(cap\_value\_t cap)} + \funcdecl{int cap\_from\_name(const char *name, cap\_value\_t *cap\_p)} + Convertono le \textit{capabilities} dalle costanti alla rappresentazione + testuale e viceversa. + + \bodydesc{La funzione \func{cap\_to\_name} ritorna un valore diverso da + \val{NULL} in caso di successo e \val{NULL} in caso di errore, mentre + \func{cap\_to\_name} ritorna rispettivamente 0 e $-1$; per entrambe in + caso di errore \var{errno} può assumere i valori \errval{EINVAL} o + \errval{ENOMEM}. } +\end{functions} + +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} il valore della capacità rappresentata dalla +stringa \param{name}. Fin quei abbiamo trattato solo le funzioni di servizio relative alla -manipolazione dei \textit{capabilities state}; l'interfaccia di gestione -prevede però anche le funzioni per la gestione delle \textit{capabilities} -stesse. La prima di queste è \funcd{cap\_get\_proc} che consente la lettura -delle \textit{capabilities} del processo corrente, il suo prototipo è: +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{functions} \headdecl{sys/capability.h} @@ -5409,7 +6492,7 @@ delle \textit{capabilities} del processo corrente, il suo prototipo è: La funzione legge il valore delle \textit{capabilities} associate al processo da cui viene invocata, restituendo il risultato tramite il puntatore ad un -\textit{capabilities state} contenente tutti i dati che provvede ad allocare +\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. @@ -5433,8 +6516,8 @@ prototipo\footnote{su alcune pagine di manuale la funzione è descritta con un %TODO controllare e correggere i codici di errore!!! La funzione legge il valore delle \textit{capabilities} del processo indicato -con l'argomento \param{pid}, e restituisce il risultato nel -\textit{capabilities state} posto all'indirizzo indicato con l'argomento +con l'argomento \param{pid}, e restituisce il risultato nel \textit{capability + state} posto all'indirizzo indicato con l'argomento \param{cap\_d}; a differenza della precedente in questo caso il \textit{capability state} deve essere stato creato in precedenza. Qualora il processo indicato non esista si avrà un errore di \errval{ESRCH}. Gli stessi @@ -5484,9 +6567,9 @@ si è distribuito il programma \texttt{getcap.c}, che consente di leggere le dalla riga di comando.} o tramite l'opzione \texttt{-p}, quelle di un processo qualunque il cui pid viene passato come parametro dell'opzione. -\begin{figure}[htb] +\begin{figure}[!htbp] \footnotesize \centering - \begin{minipage}[c]{15cm} + \begin{minipage}[c]{\codesamplewidth} \includecodesample{listati/getcap.c} \end{minipage} \normalsize @@ -5537,16 +6620,16 @@ directory di lavoro, ha anche una directory \textsl{radice}\footnote{entrambe sono contenute in due campi (rispettivamente \var{pwd} e \var{root}) di \struct{fs\_struct}; vedi fig.~\ref{fig:proc_task_struct}.} che, pur essendo di norma corrispondente alla radice dell'albero di file e directory come visto -dal kernel (ed illustrato in sez.~\ref{sec:file_organization}), ha per il -processo il significato specifico di directory rispetto alla quale vengono -risolti i \itindsub{pathname}{assoluto}\textit{pathname} -assoluti.\footnote{cioè quando un processo chiede la risoluzione di un - \textit{pathname}, il kernel usa sempre questa directory come punto di - partenza.} Il fatto che questo valore sia specificato per ogni processo apre -allora la possibilità di modificare le modalità di risoluzione dei -\textit{pathname} assoluti da parte di un processo cambiando questa directory, -così come si fa coi \itindsub{pathname}{relativo}\textit{pathname} relativi -cambiando la directory di lavoro. +dal kernel (ed illustrato in sez.~\ref{sec:file_pathname}), ha per il processo +il significato specifico di directory rispetto alla quale vengono risolti i +\itindsub{pathname}{assoluto}\textit{pathname} assoluti.\footnote{cioè quando + un processo chiede la risoluzione di un \textit{pathname}, il kernel usa + sempre questa directory come punto di partenza.} Il fatto che questo valore +sia specificato per ogni processo apre allora la possibilità di modificare le +modalità di risoluzione dei \textit{pathname} assoluti da parte di un processo +cambiando questa directory, così come si fa coi +\itindsub{pathname}{relativo}\textit{pathname} relativi cambiando la directory +di lavoro. Normalmente la directory radice di un processo coincide anche con la radice del filesystem usata dal kernel, e dato che il suo valore viene ereditato dal @@ -5564,7 +6647,7 @@ con la funzione \funcd{chroot}, il cui prototipo è: \bodydesc{La funzione restituisce zero in caso di successo e -1 per un errore, in caso di errore \var{errno} può assumere i valori: \begin{errlist} - \item[\errcode{EPERM}] l'user-ID effettivo del processo non è zero. + \item[\errcode{EPERM}] l'\acr{uid} effettivo del processo non è zero. \end{errlist} ed inoltre \errval{EFAULT}, \errval{ENAMETOOLONG}, \errval{ENOENT}, \errval{ENOMEM}, \errval{ENOTDIR}, \errval{EACCES}, \errval{ELOOP}; @@ -5656,16 +6739,16 @@ programmi e librerie) di cui il server potrebbe avere bisogno. % LocalWords: INDENT major number IDE Documentation makedev proc copy LNK long % LocalWords: euidaccess eaccess delete def tag qualifier permset calendar NOW % LocalWords: mutt noatime relatime strictatime atim nsec mtim ctim atimensec -% LocalWords: mtimensec utimes timeval futimes lutimes ENOSYS futimens OMIT +% LocalWords: mtimensec utimes timeval futimes lutimes ENOSYS futimens OMIT PR % LocalWords: utimensat timespec sec futimesat LIDS DAC OVERRIDE SEARCH chattr % LocalWords: Discrectionary KILL SETGID domain SETUID setuid setreuid SETPCAP % LocalWords: setresuid setfsuid IMMUTABLE immutable append only BIND SERVICE % LocalWords: BROADCAST broadcast multicast multicasting RAW PACKET IPC LOCK % LocalWords: memory mlock mlockall shmctl mmap MODULE RAWIO ioperm iopl PACCT -% LocalWords: ptrace accounting NICE RESOURCE TTY CONFIG hangup vhangup -% LocalWords: LEASE lease SETFCAP AUDIT permitted inherited inheritable AND +% LocalWords: ptrace accounting NICE RESOURCE TTY CONFIG hangup vhangup dell' +% LocalWords: LEASE lease SETFCAP AUDIT permitted inherited inheritable AND nn % LocalWords: bounding execve fork capget capset header hdrp datap ESRCH undef -% LocalWords: version libcap lcap clear ncap caps pag capgetp CapInh CapPrm +% LocalWords: version libcap lcap clear ncap caps pag capgetp CapInh CapPrm RT % LocalWords: fffffeff CapEff getcap scheduling lookup dqinfo SETINFO GETFMT % LocalWords: NEWNS unshare nice NUMA ioctl journaling close XOPEN fdopendir % LocalWords: btrfs mkostemp extN ReiserFS JFS Posix usrquota grpquota EDQUOT @@ -5675,7 +6758,9 @@ programmi e librerie) di cui il server potrebbe avere bisogno. % LocalWords: REALTIME securebits GETSTATS QFMT curspace curinodes btime itime % LocalWords: QIF BLIMITS bhardlimit bsoftlimit ILIMITS ihardlimit isoftlimit % LocalWords: INODES LIMITS USAGE valid dqi IIF BGRACE bgrace IGRACE igrace -% LocalWords: Python Truelite Srl quotamodule Repository who +% LocalWords: Python Truelite Srl quotamodule Repository who nell' dall' KEEP +% LocalWords: SECURE KEEPCAPS prctl FIXUP NOROOT LOCKED dell'IPC dell'I IOPRIO +% LocalWords: CAPBSET CLASS IDLE dcookie overflow DIFFERS %%% Local Variables: %%% mode: latex