X-Git-Url: https://gapil.gnulinux.it/gitweb/?p=gapil.git;a=blobdiff_plain;f=filedir.tex;h=757bc13bd60662de3eef6cac44cae2283c1493e0;hp=d1ba1b048063f143d4959670b8de7575f0297d37;hb=dcf2c2df897955ff3503a7c426025457ab456fd7;hpb=889a015512d1a1e864e02b14d281f213cf896914 diff --git a/filedir.tex b/filedir.tex index d1ba1b0..757bc13 100644 --- a/filedir.tex +++ b/filedir.tex @@ -1,6 +1,6 @@ %% filedir.tex %% -%% Copyright (C) 2000-2011 Simone Piccardi. Permission is granted to +%% Copyright (C) 2000-2012 Simone Piccardi. Permission is granted to %% copy, distribute and/or modify this document under the terms of the GNU Free %% Documentation License, Version 1.1 or any later version published by the %% Free Software Foundation; with the Invariant Sections being "Un preambolo", @@ -9,20 +9,1244 @@ %% 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} + +% NOTE 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. + +\itindbeg{inode} + +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 è molto complessa, ne faremo pertanto una trattazione +estremamente semplificata che consenta di comprenderne i principi +di funzionamento. + +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 + valore del parametro dell'opzione \texttt{-t} del comando \texttt{mount} che + indica il tipo di filesystem.} 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 di quel filesystem, ed in particolare si +dovrà creare anche la relativa versione della funzione \code{mount}. + +\itindbeg{pathname} +\itindbeg{pathname~resolution} + +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 e non dell'oggetto file del VFS cui + accennavamo prima.} 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 volta 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'\textit{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. + +\itindend{pathname} +\itindend{pathname~resolution} + +% 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 sono quelle che definiscono le operazioni che il VFS +può compiere su un \textit{inode}. Si sono riportate in +tab.~\ref{tab:file_inode_operations} le più rilevanti. + +\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 +implementazione di queste funzioni per quel filesystem e si allochi una +opportuna istanza di \kstruct{inode\_operation} contenente i puntatori a dette +funzioni. A quel punto le strutture \kstruct{inode} usate per gli oggetti di +quel filesystem otterranno il puntatore alla relativa 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 \var{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 che mette in gioco l'omonimo oggetto del +VFS: 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. + +\itindend{inode} + +\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 +\kstruct{file} contiene, oltre ad alcune informazioni usate dall'interfaccia +dei file descriptor il cui significato emergerà più avanti, il puntatore +\var{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} e +\kstruct{file\_operation}. Ovviamente non è detto che tutte le operazioni +possibili siano poi disponibili in tutti i casi, ad esempio \code{llseek} non +sarà presente per un dispositivo come la porta seriale o per una fifo, mentre +sui file del filesystem \texttt{vfat} non saranno disponibili i permessi, ma +resta il fatto che grazie al VFS le \textit{system call} per le operazioni sui +file possono restare sempre le stesse nonostante le enormi differenze che +possono esserci negli oggetti a cui si applicano. + + +\itindend{Virtual~File~System} + +% NOTE: documentazione interessante: +% * sorgenti del kernel: Documentation/filesystems/vfs.txt +% * http://thecoffeedesk.com/geocities/rkfs.html +% * http://www.linux.it/~rubini/docs/vfs/vfs.html + + + +\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. + +Una possibile strutturazione dell'informazione su un disco è riportata in +fig.~\ref{fig:file_disk_filesys}, dove si hanno tre filesystem su tre +partizioni. In essa per semplicità si è fatto riferimento alla struttura del +filesystem \acr{ext2}, che prevede una suddivisione dei dati in \textit{block + group}. All'interno di ciascun \textit{block group} viene anzitutto +replicato il cosiddetto \itindex{superblock} \textit{superblock}, (la +struttura che contiene l'indice iniziale del filesystem e che consente di +accedere a tutti i dati sottostanti) e creata una opportuna suddivisione dei +dati e delle informazioni per accedere agli stessi. Sulle caratteristiche di +\acr{ext2} e derivati torneremo in sez.~\ref{sec:file_ext2}. + +\itindbeg{inode} + +È comunque caratteristica comune di tutti i filesystem per Unix, +indipendentemente da come poi viene strutturata nei dettagli questa +informazione, prevedere la presenza di due tipi di risorse: gli +\textit{inode}, cui abbiamo già accennato in sez.~\ref{sec:file_vfs_work}, che +sono le strutture che identificano i singoli oggetti sul filesystem, e i +blocchi, che invece attengono allo spazio disco che viene messo a disposizione +per i dati in essi contenuti. + +\begin{figure}[!htb] + \centering + \includegraphics[width=12cm]{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 filesystem \textsl{ext2}, tralasciando i +dettagli relativi al funzionamento del filesystem stesso come la +strutturazione in gruppi dei blocchi, il \itindex{superblock} +\textit{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=12cm]{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, che restano le stesse anche su +filesystem la cui organizzazione dei dati è totalmente diversa da quella +illustrata, e 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 prosieguo del capitolo. In particolare è +opportuno tenere sempre presente che: + + +\begin{enumerate} + +\item L'\textit{inode} contiene i cosiddetti \textsl{metadati}, vale dire le + informazioni riguardanti le proprietà del file come oggetto del filesystem: + 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 dell'\textit{inode} ad esso associato; il nome non è una + proprietà del file e non viene mantenuto nell'\textit{inode}. Da da qui in + poi chiameremo il nome del file contenuto in una directory + ``\textsl{voce}'', come traduzione della nomenclatura inglese + \textit{directory entry} che non useremo per evitare confusione con le + \textit{dentry} del kernel viste in sez.~\ref{sec:file_vfs_work}. + +\item Come mostrato in fig.~\ref{fig:file_filesys_detail} per i file + \texttt{macro.tex} e \texttt{gapil\_macro.tex}, ci possono avere più voci + che fanno riferimento allo stesso \textit{inode}. Fra le proprietà di un + file mantenute nell'\textit{inode} c'è anche il contatore con il numero di + riferimenti che sono stati fatti ad esso, il cosiddetto \textit{link + count}.\footnote{mantenuto anche nel campo \var{i\_nlink} della struttura + \kstruct{inode} di fig.~\ref{fig:kstruct_inode}.} Solo quando questo + contatore si annulla i dati del file possono essere 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 nell'\textit{inode}. + +\item All'interno di ogni filesystem ogni \textit{inode} è identificato da un + numero univoco. Il numero di \textit{inode} associato ad una voce in una + directory si riferisce ad questo numero e non ci può essere una directory + che contiene riferimenti ad \textit{inode} relativi ad altri filesystem. + Questa è la ragione che limita l'uso del comando \cmd{ln}, che crea una + nuova voce per un file esistente con la funzione \func{link} (vedi + sez.~\ref{sec:file_link}) a file nel 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 l'\textit{inode} in questione e rimossa la precedente, 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 sul file 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 esaurire sia lo spazio disco (il 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.\footnote{questo comportamento non è generale, alcuni filesystem + evoluti possono evitare il problema dell'esaurimento degli \textit{inode} + riallocando lo spazio disco libero per i blocchi.} + +\end{enumerate} + +\begin{figure}[!htb] + \centering + \includegraphics[width=12cm]{img/dir_links} + \caption{Organizzazione dei \textit{link} per le directory.} + \label{fig:file_dirs_link} +\end{figure} + +Infine tenga presente che, essendo file pure loro, il numero di riferimenti +esiste anche per le directory. Per questo 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 +illustrata in fig.~\ref{fig:file_dirs_link}. + +La nuova directory avrà 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 interna ``\texttt{.}'' +che è presente in ogni directory. Questo è il valore che si troverà 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}. L'aggiunta di una sottodirectory fa cioè crescere di uno il +\textit{link count} della directory genitrice. + +\itindend{inode} + + +\subsection{Alcuni dettagli sul filesystem \textsl{ext2} e successori} +\label{sec:file_ext2} + + +Benché non esista ``il'' filesystem di Linux, dato che esiste un supporto +nativo di diversi filesystem che sono in uso da anni, quello che gli avvicina +di più è la famiglia di filesystem evolutasi a partire dal \textit{second + extended filesystem}, o \acr{ext2}. Il filesystem \acr{ext2} ha subito un +grande sviluppo e diverse evoluzioni, fra cui l'aggiunta del +\textit{journaling} con \acr{ext3}, probabilmente ancora il filesystem più +diffuso, ed una serie di ulteriori miglioramento con il successivo \acr{ext4}, +che sta iniziando a sostituirlo gradualmente. In futuro è previsto che questo +debba essere sostituito da un filesystem completamente diverso, \acr{btrfs}, +che dovrebbe diventare il filesystem standard di Linux, ma questo al momento è +ancora in fase di sviluppo.\footnote{si fa riferimento al momento dell'ultima + revisione di di questo paragrafo, l'inizio del 2012.} + +Il filesystem \acr{ext2} nasce come filesystem nativo per 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 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 \ids{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'\textit{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. + +Ciascun gruppo di blocchi contiene una copia delle informazioni essenziali del +filesystem (i \itindex{superblock} \textit{superblock} sono quindi ridondati) +per una maggiore affidabilità e possibilità di recupero in caso di corruzione +del \itindex{superblock} \textit{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 extended 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 diverse +modifiche strutturali, la principale di queste è quella che \textit{ext3} è un +filesystem \textit{journaled}, è 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} che abbiamo +illustrato, ottenendo un forte guadagno di prestazioni in caso di directory +contenenti un gran numero di file. + +% TODO (bassa priorità) 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) +% TODO (media priorità) trattare btrfs quando sarà usato come stabile + + +\subsection{La gestione dell'uso 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 si usa la funzione \funcd{mount}, +il cui prototipo è:\footnote{la funzione è una versione specifica di Linux che + usa la omonima \textit{system call} e non è portabile.} + +\begin{funcproto}{ +\fhead{sys/mount.h} +\fdecl{mount(const char *source, const char *target, const char + *filesystemtype, \\ +\phantom{mount(}unsigned long mountflags, const void *data)} +\fdesc{Monta un filesystem.} +} + +{La funzione ritorna $0$ in caso di successo e $-1$ per un errore, nel qual + caso \var{errno} assumerà uno dei valori: + \begin{errlist} + \item[\errcode{EACCES}] non si ha il permesso di accesso su uno dei + componenti del \textit{pathname}, o si è cercato di montare un filesystem + disponibile in sola lettura senza aver specificato \const{MS\_RDONLY} o il + device \param{source} è su un filesystem montato con l'opzione + \const{MS\_NODEV}. + \item[\errcode{EBUSY}] \param{source} è già montato, o non può essere + rimontato in sola lettura perché ci sono ancora file aperti in scrittura, + o non può essere montato su \param{target} perché la directory è ancora in + uso. + \item[\errcode{EINVAL}] il dispositivo \param{source} presenta un + \itindex{superblock} \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 è la radice. + \item[\errcode{ELOOP}] si è cercato di spostare un \itindex{mount~point} + \textit{mount point} su una sottodirectory di \param{source} o si sono + incontrati troppi link simbolici nella risoluzione di un nome. + \item[\errcode{EMFILE}] in caso di filesystem virtuale, la tabella dei + dispositivi fittizi (chiamati \textit{dummy} nella documentazione inglese) + è piena. + \item[\errcode{ENODEV}] il tipo \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{ENXIO}] il \itindex{major~number} \textit{major number} del + dispositivo \param{source} è sbagliato. + \item[\errcode{EPERM}] il processo non ha i privilegi di amministratore. + \end{errlist} + ed inoltre \errval{EFAULT}, \errval{ENOMEM}, \errval{ENAMETOOLONG}, + \errval{ENOENT}, \errval{ENOTDIR} nel loro significato generico.} +\end{funcproto} + +La funzione monta sulla directory indicata da \param{target}, detta +\itindex{mount~point} \textit{mount point}, il filesystem contenuto nel file +di dispositivo indicato da \param{source}. In entrambi i casi, come daremo per +assunto da qui in avanti tutte le volte che si parla di directory o file nel +passaggio di un argomento di una funzione, si intende che questi devono essere +indicati con la stringa contenente il loro \textit{pathname}. + +Normalmente un filesystem è contenuto su un disco o una partizione, ma come +illustrato in sez.~\ref{sec:file_vfs_work} la struttura del +\itindex{Virtual~File~System} \textit{Virtual File System} è estremamente +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 l'immagine di un +filesystem, inoltre alcuni tipi di filesystem, come \texttt{proc} o +\texttt{sysfs} sono virtuali e non hanno un supporto che ne contenga i dati, +che invece sono generati al volo ad ogni lettura, e passati indietro al kernel +ad ogni scrittura.\footnote{costituiscono quindi un meccanismo di + comunicazione, attraverso l'ordinaria interfaccia dei file, con il kernel.} + +Il tipo di filesystem che si vuole montare è specificato +dall'argomento \param{filesystemtype}, che deve essere una delle stringhe +riportate nel file \procfile{/proc/filesystems} che, come accennato in +sez.~\ref{sec:file_vfs_work}, contiene l'elenco dei filesystem supportati dal +kernel. Nel caso si sia indicato un filesystem virtuale, che non è associato a +nessun file di dispositivo, il contenuto di \param{source} viene ignorato. + +L'argomento \param{data} viene usato per passare le impostazioni relative alle +caratteristiche specifiche di ciascun filesystem. Si tratta di una stringa di +parole chiave (separate da virgole e senza spazi) che indicano le cosiddette +``\textsl{opzioni}'' del filesystem che devono essere impostate; in genere +viene usato direttamente il contenuto del parametro dell'opzione \texttt{-o} +del comando \texttt{mount}. I valori utilizzabili dipendono dal tipo di +filesystem e ciascuno ha i suoi, pertanto si rimanda alla documentazione della +pagina di manuale di questo comando e dei singoli filesystem. + +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. Fino +ai kernel della serie 2.2.x non era possibile montare un filesystem se un +\textit{mount point} era già in uso. + +A partire dal kernel 2.4.x inoltre è divenuto possibile sia spostare +atomicamente un \itindex{mount~point} \textit{mount point} da una directory ad +un'altra, sia montare lo stesso filesystem in diversi \itindex{mount~point} +\textit{mount point}, sia montare più filesystem sullo stesso +\itindex{mount~point} \textit{mount point} impilandoli l'uno sull'altro, nel +qual caso vale comunque quanto detto in precedenza, e cioè che solo il +contenuto dell'ultimo filesystem montato sarà visibile. + +Oltre alle opzioni specifiche di ciascun filesystem, che si passano nella +forma della lista di parole chiave indicata con l'argomento \param{data}, +esistono pure alcune opzioni che si possono applicare in generale, anche se +non è detto che tutti i filesystem le supportino, che si specificano tramite +l'argomento \param{mountflags}. L'argomento inoltre può essere utilizzato per +modificare il comportamento della funzione, facendole compiere una operazione +diversa (ad esempio un rimontaggio, invece che un montaggio). + +In Linux \param{mountflags} deve essere un intero a 32 bit; fino ai kernel +della serie 2.2.x i 16 più significativi avevano un valore riservato che +doveva essere specificato obbligatoriamente,\footnote{il valore era il + \itindex{magic~number} \textit{magic number} \code{0xC0ED}, si può usare la + costante \const{MS\_MGC\_MSK} per ottenere la parte di \param{mountflags} + riservata al \textit{magic number}, mentre per specificarlo si può dare un + OR aritmetico con la costante \const{MS\_MGC\_VAL}.} e si potevano usare +solo i 16 meno significativi. Oggi invece, con un numero di opzioni superiore, +sono utilizzati tutti e 32 i bit, ma qualora nei 16 più significativi sia +presente detto valore, che non esprime una combinazione valida, esso viene +ignorato. Il valore dell'argomento deve essere espresso come maschera binaria +e i vari bit devono essere impostati con un OR aritmetico dei rispettivi flag, +identificati dalle costanti riportate nell'elenco seguente: + +\begin{basedescript}{\desclabelwidth{2.cm}\desclabelstyle{\nextlinelabel}} +\itindbeg{bind~mount} +\item[\const{MS\_BIND}] Effettua un cosiddetto \textit{bind mount}, in cui è + possibile montare una directory di un filesystem in un'altra directory, + l'opzione è disponibile a partire dai kernel della serie 2.4. In questo caso + verranno presi in considerazione solo gli argomenti \param{source}, che + stavolta indicherà la directory che si vuole montare (e non un file di + dispositivo) e \param{target} che indicherà la directory su cui verrà + effettuato il \textit{bind mount}. Gli argomenti \param{filesystemtype} + e \param{data} vengono ignorati. + + In sostanza quello che avviene è che in corrispondenza del \textit{pathname} + indicato da \param{target} viene montato l'\textit{inode} di \param{source}, + così che la porzione di albero dei file presente sotto + \param{source} diventi visibile allo stesso modo sotto + \param{target}. Trattandosi esattamente dei dati dello stesso filesystem, + ogni modifica fatta in uno qualunque dei due rami di albero sarà visibile + nell'altro, visto che entrambi faranno riferimento agli stessi + \textit{inode}. + + Dal punto di vista del \itindex{Virtual~File~System} VFS l'operazione è + analoga al montaggio di un filesystem proprio nel fatto che anche in questo + caso si inserisce in corrispondenza della \textit{dentry} di \texttt{target} + un diverso \textit{inode}, che stavolta, invece di essere quello della + radice del filesystem indicato da un file di dispositivo, è quello di una + directory già montata. + + Si tenga presente che proprio per questo sotto \param{target} comparirà il + contenuto che è presente sotto \param{source} all'interno del filesystem in + cui quest'ultima è contenuta. Questo potrebbe non corrispondere alla + porzione di albero che sta sotto \param{source} qualora in una + sottodirectory di quest'ultima si fosse effettuato un altro montaggio. In + tal caso infatti nella porzione di albero sotto \param{source} si troverebbe + il contenuto del nuovo filesystem (o di un altro \textit{bind mount}) mentre + sotto \param{target} ci sarebbe il contenuto presente nel filesystem + originale.\footnote{questo evita anche il problema dei \textit{loop} di + fig.~\ref{fig:file_link_loop}, dato che se anche si montasse su + \param{target} una directory in cui essa è contenuta, il cerchio non + potrebbe chiudersi perché ritornati a \param{target} dentro il + \textit{bind mount} vi si troverebbe solo il contenuto originale e non si + potrebbe tornare indietro.} + + Fino al kernel 2.6.26 questo flag doveva essere usato da solo, in quanto il + \textit{bind mount} continuava ad utilizzare le stesse opzioni del montaggio + originale, dal 2.6.26 è stato introdotto il supporto per il cosiddetto + \textit{read-only bind mount} e viene onorata la presenza del flag + \const{MS\_RDONLY}. In questo modo si ottiene che l'accesso ai file sotto + \param{target} sia effettuabile esclusivamente in sola lettura. + + Il supporto per il \textit{bind mount} consente di superare i limiti + presenti per gli \textit{hard link} (di cui parleremo in + sez.~\ref{sec:file_link}) ottenendo un qualcosa di analogo in cui si può + fare riferimento alla porzione dell'albero dei file di un filesystem + presente a partire da una certa directory utilizzando una qualunque altra + directory, anche se questa sta su un filesystem diverso. Si può così fornire + una alternativa all'uso dei link simbolici (di cui parleremo in + sez.~\ref{sec:file_symlink}) che funziona correttamente anche all'intero di + un \textit{chroot} (argomento su cui torneremo in + sez.~\ref{sec:file_chroot}. +\itindend{bind~mount} + +\item[\const{MS\_DIRSYNC}] Richiede che ogni modifica al contenuto di una + directory venga immediatamente registrata su disco in maniera sincrona + (introdotta a partire dai kernel della serie 2.6). L'opzione si applica a + tutte le directory del filesystem, ma su alcuni filesystem è possibile + impostarla a livello di singole directory o per i sottorami di una directory + con il comando \cmd{lsattr}.\footnote{questo avviene tramite delle opportune + \texttt{ioctl} (vedi sez.~\ref{sec:file_ioctl}).} + + Questo consente di ridurre al minimo il rischio di perdita dei dati delle + directory in caso di crollo improvviso del sistema, al costo di una certa + perdita di prestazioni dato che le funzioni di scrittura relative ad + operazioni sulle directory non saranno più bufferizzate e si bloccheranno + fino all'arrivo dei dati sul disco prima che un programma possa proseguire. + +\item[\const{MS\_MANDLOCK}] Consente l'uso del \textit{mandatory locking} + \itindex{mandatory~locking} (vedi sez.~\ref{sec:file_mand_locking}) sui file + del filesystem. Per poterlo utilizzare effettivamente però esso dovrà essere + comunque attivato esplicitamente per i singoli file impostando i permessi + come illustrato in sez.~\ref{sec:file_mand_locking}. + +\item[\const{MS\_MOVE}] Effettua uno del spostamento del \itindex{mount~point} + \textit{mount point} di un filesystem. La directory del + \itindex{mount~point} \textit{mount point} originale deve essere indicata + nell'argomento \param{source}, e la sua nuova posizione + nell'argomento \param{target}. Tutti gli altri argomenti della funzione + vengono ignorati. + + Lo spostamento avviene atomicamente, ed il ramo di albero presente + sotto \param{source} sarà immediatamente visibile sotto \param{target}. Non + esiste cioè nessun momento in cui il filesystem non risulti montato in una o + nell'altra directory e pertanto è garantito che la risoluzione di + \itindsub{pathname}{relativo} \textit{pathname} relativi all'interno del + filesystem non possa fallire. + +\item[\const{MS\_NOATIME}] Viene disabilitato sul filesystem l'aggiornamento + degli \textit{access time} (vedi sez.~\ref{sec:file_file_times}) per + qualunque tipo di file. Dato che l'aggiornamento degli \textit{access time} + è una funzionalità la cui utilità è spesso irrilevante ma comporta un costo + elevato visto che una qualunque lettura comporta comunque una scrittura su + disco,\footnote{e questo ad esempio ha conseguenze molto pesanti nell'uso + della batteria sui portatili.} questa opzione consente di disabilitarla + completamente. La soluzione può risultare troppo drastica dato che + l'informazione viene comunque utilizzata da alcuni programmi, per cui nello + sviluppo del kernel sono state introdotte altre opzioni che forniscono + soluzioni più appropriate e meno radicali. + +\item[\const{MS\_NODEV}] Viene disabilitato sul filesystem l'accesso ai file + di dispositivo eventualmente presenti su di esso. L'opzione viene usata come + misura di precauzione per rendere inutile la presenza di eventuali file di + dispositivo su filesystem che non dovrebbero contenerne.\footnote{si ricordi + che le convenzioni del \itindex{Filesystem~Hierarchy~Standard~(FHS)} + \textit{Linux Filesystem Hierarchy Standard} richiedono che questi siano + mantenuti esclusivamente sotto \texttt{/dev}.} + + Viene utilizzata, assieme a \const{MS\_NOEXEC} e \const{MS\_NOSUID}, per + fornire un accesso più controllato a quei filesystem di cui gli utenti hanno + il controllo dei contenuti, in particolar modo quelli posti su dispositivi + rimuovibili. In questo modo si evitano alla radice possibili situazioni in + cui un utente malizioso inserisce su uno di questi filesystem dei file di + dispositivo con permessi ``opportunamente'' ampliati che gli consentano di + accedere anche a risorse cui non dovrebbe. + +\item[\const{MS\_NODIRATIME}] Viene disabilitato sul filesystem + l'aggiornamento degli \textit{access time} (vedi + sez.~\ref{sec:file_file_times}), ma soltanto per le directory. Costituisce + una alternativa per \const{MS\_NOATIME}, che elimina l'informazione per le + directory, che in pratica che non viene mai utilizzata, mantenendola per i + file in cui invece ha un impiego, sia pur limitato. + +\item[\const{MS\_NOEXEC}] Viene disabilitata sul filesystem l'esecuzione di un + qualunque file eseguibile eventualmente presente su di esso. L'opzione viene + usata come misura di precauzione per rendere impossibile l'uso di programmi + posti su filesystem che non dovrebbero contenerne. + + Anche in questo caso viene utilizzata per fornire un accesso più controllato + a quei filesystem di cui gli utenti hanno il controllo dei contenuti. Da + questo punto di vista l'opzione è meno importante delle analoghe + \const{MS\_NODEV} e \const{MS\_NOSUID} in quanto l'esecuzione di un + programma creato dall'utente pone un livello di rischio nettamente + inferiore, ed è in genere consentita per i file contenuti nella sua home + directory.\footnote{cosa che renderebbe superfluo l'attivazione di questa + opzione, il cui uso ha senso solo per ambienti molto controllati in cui si + vuole che gli utenti eseguano solo i programmi forniti + dall'amministratore.} + +\item[\const{MS\_NOSUID}] Viene disabilitato sul filesystem l'effetto dei bit + dei permessi \itindex{suid~bit} \acr{suid} e \itindex{sgid~bit} \acr{sgid} + (vedi sez.~\ref{sec:file_special_perm}) eventualmente presenti sui file in + esso contenuti. L'opzione viene usata come misura di precauzione per rendere + inefficace l'effetto di questi bit per filesystem in cui non ci dovrebbero + essere file dotati di questi permessi. + + Di nuovo viene utilizzata, analogamente a \const{MS\_NOEXEC} e + \const{MS\_NODEV}, per fornire un accesso più controllato a quei filesystem + di cui gli utenti hanno il controllo dei contenuti. In questo caso si evita + che un utente malizioso possa inserire su uno di questi filesystem un + eseguibile con il bit \itindex{suid~bit} \acr{suid} attivo e di proprietà + dell'amministratore o di un altro utente, che gli consentirebbe di eseguirlo + per conto di quest'ultimo. + +\item[\const{MS\_PRIVATE}] Marca un \itindex{mount~point} \textit{mount point} + come privato. Si tratta di una delle nuove opzioni (insieme a + \const{MS\_SHARED}, \const{MS\_SLAVE} e \const{MS\_UNBINDABLE}) facenti + parte dell'infrastruttura degli \itindex{shared~subtree} \textit{shared + subtree} introdotta a partire dal kernel 2.6.15, che estendono le + funzionalità dei \itindex{bind~mount} \textit{bind mount}. In questo caso + \param{target} dovrà fare riferimento al \textit{mount point} che si intende + marcare, e tutti gli altri argomenti verranno ignorati. + + Di default, finché non lo si marca altrimenti con una delle altre opzioni + dell'interfaccia \itindex{shared~subtree} \textit{shared subtree}, ogni + \textit{mount point} è privato. Ogni \textit{bind mount} ottenuto da un + \itindex{mount~point} \textit{mount point} di tipo \textit{private} si + comporta come descritto nella trattazione di \const{MS\_BIND}. Si usa questo + flag principalmente per revocare gli effetti delle altre opzioni e riportare + il comportamento a quello ordinario. + +\item[\const{MS\_RDONLY}] Esegue il montaggio del filesystem in sola lettura, + non sarà possibile nessuna modifica ai suoi contenuti. Viene usato tutte le + volte che si deve accedere ai contenuti di un filesystem con la certezza che + questo non venga modificato (ad esempio per ispezionare un filesystem + corrotto). All'avvio di default il kernel monta la radice in questa + modalità. + +\item[\const{MS\_REC}] Applica ricorsivamente a tutti i \itindex{mount~point} + \textit{mount point} presenti al di sotto del \textit{mount point} indicato + gli effetti della opzione degli \itindex{shared~subtree} \textit{shared + subtree} associata. Anche questo caso l'argomento \param{target} deve fare + riferimento ad un \itindex{mount~point} \textit{mount point} e tutti gli + altri argomenti sono ignorati, ed il flag deve essere indicato assieme ad + una fra \const{MS\_PRIVATE}, \const{MS\_SHARED}, \const{MS\_SLAVE} e + \const{MS\_UNBINDABLE}. + +\item[\const{MS\_RELATIME}] Indica di effettuare l'aggiornamento degli + \textit{access time} sul filesystem soltanto quando questo risulti + antecedente il valore corrente del \textit{modification time} o del + \textit{change time} (per i tempi dei file si veda + sez.~\ref{sec:file_file_times}). L'opzione è disponibile a partire dal + kernel 2.6.20, mentre dal 2.6.30 questo è diventato il comportamento di + default del sistema, che può essere riportato a quello tradizionale con + l'uso di \const{MS\_STRICTATIME}. Sempre dal 2.6.30 il comportamento è stato + anche modificato e l'\textit{access time} viene comunque aggiornato se è più + vecchio di un giorno. + + L'opzione consente di evitare i problemi di prestazioni relativi + all'aggiornamento dell'\textit{access time} senza avere impatti negativi + riguardo le funzionalità, il comportamento adottato infatti consente di + rendere evidente che vi è stato un accesso dopo la scrittura, ed evitando al + contempo ulteriori operazioni su disco negli accessi successivi. In questo + modo l'informazione relativa al fatto che un file sia stato letto resta + disponibile, ed i programmi che ne fanno uso continuano a funzionare. Con + l'introduzione di questo comportamento l'uso delle alternative + \const{MS\_NOATIME} e \const{MS\_NODIRATIME} è sostanzialmente inutile. + +\item[\const{MS\_REMOUNT}] Consente di rimontare un filesystem già montato + cambiandone le opzioni di montaggio in maniera atomica. In questo modo si + possono modificare le opzioni del filesystem anche se questo è in uso. Gli + argomenti \param{source} e \param{target} devono essere gli stessi usati per + il montaggio originale, mentre \param{data} che \param{mountflags} + conterranno le nuove opzioni, \param{filesystemtype} viene ignorato. + + Qualunque opzione specifica del filesystem indicata con \param{data} può + essere modificata, mentre con \param{mountflags} possono essere modificate + solo alcune opzioni generiche. Con i kernel più recenti queste sono soltanto + \const{MS\_MANDLOCK}, \const{MS\_RDONLY} e \const{MS\_SYNCHRONOUS}, prima + del kernel 2.6.16 potevano essere modificate anche le ulteriori + \const{MS\_NOATIME} e \const{MS\_NODIRATIME}, ed infine prima del kernel + 2.4.10 anche \const{MS\_NODEV}, \const{MS\_NOEXEC} e \const{MS\_NOSUID}. + +\item[\const{MS\_SHARED}] Marca un \itindex{mount~point} \textit{mount point} + come \textit{shared mount}. Si tratta di una delle nuove opzioni (insieme a + \const{MS\_PRIVATE}, \const{MS\_SLAVE} e \const{MS\_UNBINDABLE}) facenti + parte dell'infrastruttura degli \itindex{shared~subtree} \textit{shared + subtree} introdotta a partire dal kernel 2.6.15, che estendono le + funzionalità dei \itindex{bind~mount} \textit{bind mount}. In questo caso + \param{target} dovrà fare riferimento al \itindex{mount~point} \textit{mount + point} che si intende marcare, e tutti gli altri argomenti verranno + ignorati. + + Lo scopo dell'opzione è ottenere che tutti i successivi \textit{bind mount} + effettuati da un \textit{mount point} marcato da essa siano di tipo + \textit{shared}, cioè ``\textsl{condividano}'' con l'originale e fra di loro + ogni ulteriore operazione di montaggio o smontaggio che avviene su una + directory al di sotto di uno qualunque di essi. Le operazioni di montaggio e + smontaggio cioè vengono ``\textsl{propagate}'' a tutti i \textit{mount + point} della stessa condivisione, e la sezione di albero di file vista al + di sotto di ciascuno di essi sarà sempre identica. + +\item[\const{MS\_SILENT}] Richiede la soppressione di alcuni messaggi di + avvertimento nei log del kernel (vedi sez.~\ref{sec:sess_daemon}). L'opzione + è presente a partire dal kernel 2.6.17 e sostituisce, utilizzando un nome + non fuorviante, la precedente \const{MS\_VERBOSE}, introdotta nel kernel + 2.6.12, che aveva lo stesso effetto. + +\item[\const{MS\_SLAVE}] Marca un \itindex{mount~point} \textit{mount point} + come \textit{slave mount}. Si tratta di una delle nuove opzioni (insieme a + \const{MS\_PRIVATE}, \const{MS\_SHARED} e \const{MS\_UNBINDABLE}) facenti + parte dell'infrastruttura degli \itindex{shared~subtree} \textit{shared + subtree} introdotta a partire dal kernel 2.6.15, che estendono le + funzionalità dei \itindex{bind~mount} \textit{bind mount}. In questo caso + \param{target} dovrà fare riferimento al \textit{mount point} che si intende + marcare, e tutti gli altri argomenti verranno ignorati. + + Lo scopo dell'opzione è ottenere che tutti i successivi \textit{bind mount} + effettuati da un \textit{mount point} marcato da essa siano di tipo + \textit{slave}, cioè ``\textsl{condividano}'' ogni ulteriore operazione di + montaggio o smontaggio che avviene su una directory al di sotto del + \textit{mount point} originale. Le operazioni di montaggio e smontaggio in + questo caso vengono ``\textsl{propagate}'' soltanto dal \textit{mount point} + originale (detto anche \textit{master}) verso gli \textit{slave}, mentre + essi potranno eseguire al loro interno ulteriori montaggi che non saranno + propagati né negli altri né nel \itindex{mount~point} \textit{mount point} + originale. + +\item[\const{MS\_STRICTATIME}] Ripristina il comportamento tradizionale per + cui l'\textit{access time} viene aggiornato ad ogni accesso al + file. L'opzione è disponibile solo a partire dal kernel 2.6.30 quando il + comportamento di default del kernel è diventato quello fornito da + \const{MS\_RELATIME}. + +\item[\const{MS\_SYNCHRONOUS}] Abilita la scrittura sincrona richiedendo che + ogni modifica al contenuto del filesystem venga immediatamente registrata su + disco. Lo stesso comportamento può essere ottenuto con il flag + \const{O\_SYNC} di \func{open} (vedi sez.~\ref{sec:file_open}). + + Questa opzione consente di ridurre al minimo il rischio di perdita dei dati + in caso di crollo improvviso del sistema, al costo di una pesante perdita di + prestazioni dato che tutte le funzioni di scrittura non saranno più + bufferizzate e si bloccheranno fino all'arrivo dei dati sul disco. Per un + compromesso in cui questo comportamento avviene solo per le directory, ed ha + quindi una incidenza nettamente minore, si può usare \const{MS\_DIRSYNC}. + +\item[\const{MS\_UNBINDABLE}] Marca un \itindex{mount~point} \textit{mount + point} come \textit{unbindable mount}. Si tratta di una delle nuove + opzioni (insieme a \const{MS\_PRIVATE}, \const{MS\_SHARED} e + \const{MS\_SLAVE}) facenti parte dell'infrastruttura degli + \itindex{shared~subtree} \textit{shared subtree} introdotta a partire dal + kernel 2.6.15, che estendono le funzionalità dei \itindex{bind~mount} + \textit{bind mount}. In questo caso + \param{target} dovrà fare riferimento al \textit{mount point} che si intende + marcare, e tutti gli altri argomenti verranno ignorati. + + Un \textit{mount point} marcato in questo modo disabilità la capacità di + eseguire dei \itindex{bind~mount} \textit{bind mount}. Si comporta cioè come + allo stesso modo di un \itindex{mount~point} \textit{mount point} ordinario + di tipo \textit{private} con in più la restrizione che nessuna sua + sottodirectory (anche se relativa ad un ulteriore montaggio) possa essere + utilizzata per un come sorgente di un \itindex{bind~mount} \textit{bind + mount}. + +\end{basedescript} + +% NOTE per \const{MS\_SLAVE},\const{MS\_SHARE}, \const{MS\_PRIVATE} e +% \const{MS\_UNBINDABLE} dal 2.6.15 vedi shared subtrees, in particolare +% * http://lwn.net/Articles/159077/ e +% * Documentation/filesystems/sharedsubtree.txt + +% TODO: (bassa priorità) non documentati ma presenti in sys/mount.h: +% * MS_POSIXACL +% * MS_KERNMOUNT +% * MS_I_VERSION +% * MS_ACTIVE +% * MS_NOUSER + + +Una volta che non si voglia più utilizzare un certo filesystem è possibile +``\textsl{smontarlo}'' usando la funzione \funcd{umount}, il cui prototipo è: + +\begin{funcproto}{ +\fhead{sys/mount.h} +\fdecl{umount(const char *target)} +\fdesc{Smonta un filesystem.} +} +{La funzione ritorna $0$ in caso di successo e $-1$ per un errore, + nel qual caso \var{errno} assumerà uno dei valori: + \begin{errlist} + \item[\errcode{EBUSY}] il filesystem è occupato. + \item[\errcode{EINVAL}] \param{target} non è un \textit{mount point}. + \item[\errcode{EPERM}] il processo non ha i privilegi di + amministratore.\footnotemark + \end{errlist} + ed inoltre \errval{EFAULT}, \errval{ELOOP}, \errval{ENAMETOOLONG}, + \errval{ENOENT}, \errval{ENOMEM} nel loro significato generico. } +\end{funcproto} + +\footnotetext{più precisamente la \itindex{capabilities} capacità + \texttt{CAP\_SYS\_ADMIN}.} + +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 a partire dai kernel della serie 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 se +il filesystem è ``\textsl{occupato}'', cioè quando ci sono ancora dei file +aperti sul filesystem, se questo contiene la \index{directory~di~lavoro} +directory di lavoro di un qualunque processo o il \itindex{mount~point} +\textit{mount point} di un altro filesystem. + +Linux provvede inoltre una seconda funzione, \funcd{umount2}, che consente un +maggior controllo delle operazioni, come forzare lo smontaggio di un +filesystem anche quando questo risulti occupato; il suo prototipo è: + +\begin{funcproto}{ +\fhead{sys/mount.h} +\fdecl{umount2(const char *target, int flags)} +\fdesc{Smonta un filesystem.} +} +{La funzione ritorna $0$ in caso di successo e $-1$ per un errore, + nel qual caso \var{errno} assumerà uno dei valori: + \begin{errlist} + \item[\errcode{BUSY}] \param{target} è la \index{directory~di~lavoro} + directory di lavoro di qualche processo, o contiene dei file aperti, o un + altro mount point. + \item[\errcode{EAGAIN}] si è chiamata la funzione con \const{MNT\_EXPIRE} + ed il filesystem non era occupato. + \item[\errcode{EINVAL}] \param{target} non è un \itindex{mount~point} + \textit{mount point} o si è usato \const{MNT\_EXPIRE} con + \const{MNT\_FORCE} o \const{MNT\_DETACH} o si è specificato un flag non + esistente. + \end{errlist} + e tutti gli altri valori visti per \func{umount} con lo stesso significato.} +\end{funcproto} + +Il valore di \param{flags} è una maschera binaria dei flag che controllano le +modalità di smontaggio, che deve essere specificato con un OR aritmetico delle +costanti illustrate in tab.~\ref{tab:umount2_flags}. 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. + +\begin{table}[!htb] + \centering + \footnotesize + \begin{tabular}[c]{|l|p{8cm}|} + \hline + \textbf{Costante} & \textbf{Descrizione}\\ + \hline + \hline + \const{MNT\_FORCE} & forza lo smontaggio del filesystem anche se questo è + occupato (presente dai kernel della serie 2.2).\\ + \const{MNT\_DETACH} & esegue uno smontaggio ``\textsl{pigro}'', in cui si + blocca l'accesso ma si aspetta che il filesystem si + liberi (presente dal kernel 2.4.11 e dalla + \acr{glibc} 2.11).\\ + \const{MNT\_EXPIRE} & se non occupato marca un \itindex{mount~point} + \textit{mount point} come ``\textsl{in scadenza}'' in + modo che ad una successiva chiamata senza utilizzo + del filesystem questo venga smontato (presente dal + kernel 2.6.8 e dalla \acr{glibc} 2.11).\\ + \const{UMOUNT\_NOFOLLOW}& non dereferenzia \param{target} se questo è un + link simbolico (vedi sez.~\ref{sec:file_symlink}) + evitando problemi di sicurezza (presente dal kernel + 2.6.34).\\ + \hline + \end{tabular} + \caption{Costanti che identificano i bit dell'argomento \param{flags} + della funzione \func{umount2}.} + \label{tab:umount2_flags} +\end{table} + +Con l'opzione \const{MNT\_DETACH} si richiede invece uno smontaggio +``\textsl{pigro}'' (o \textit{lazy umount}) in cui il filesystem diventa +inaccessibile per i nuovi processi subito dopo la chiamata della funzione, ma +resta accessibile per quelli che lo hanno ancora in uso e non viene smontato +fintanto che resta occupato. + +Con \const{MNT\_EXPIRE}, che non può essere specificato insieme agli altri +due, si marca il \itindex{mount~point} \textit{mount point} di un filesystem +non occupato come ``\textsl{in scadenza}'', in tal caso \func{umount2} ritorna +con un errore di \errcode{EAGAIN}, mentre in caso di filesystem occupato si +sarebbe ricevuto \errcode{BUSY}. Una volta marcato, se nel frattempo non +viene fatto nessun uso del filesystem, ad una successiva chiamata con +\const{MNT\_EXPIRE} questo verrà smontato. Questo flag consente di realizzare +un meccanismo che smonti automaticamente i filesystem che restano inutilizzato +per un certo periodo di tempo. + +% Infine il flag \const{UMOUNT\_NOFOLLOW} impedisce l'uso di un link simbolico +% per \param{target} evitando così che si possano passare ai programmi che +% effettuano lo smontaggio dei filesystem per i quali è previsto la possibilità +% di gestione da parte degli utenti con uno programma \acr{sgid} + +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{funcproto}{ +\fhead{sys/vfs.h} +\fdecl{int statfs(const char *path, struct statfs *buf)} +\fdecl{int fstatfs(int fd, struct statfs *buf)} +\fdesc{Restituiscono informazioni relative ad un filesystem.} +} +{Le funzioni ritornano $0$ in caso di successo e $-1$ per un errore, + nel qual caso \var{errno} assumerà uno dei valori: + \begin{errlist} + \item[\errcode{ENOSYS}] il filesystem su cui si trova il file specificato + non supporta la funzione. + \end{errlist} ed inoltre \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} nel loro + significato generico.} +\end{funcproto} + +Queste funzioni permettono di ottenere una serie di informazioni generali +riguardo al filesystem su cui si trova il file specificato con un ; 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 (bassa priorità) scrivere delle funzioni (getfsent e getmntent &C) +% TODO (bassa priorità) documentare ? swapon e swapoff (man 2 ...) \section{La gestione di file e directory} \label{sec:file_dir} @@ -48,9 +1272,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} @@ -70,17 +1293,20 @@ fanno comunque riferimento allo stesso \itindex{inode} \textit{inode}. Per aggiungere ad una directory una voce che faccia riferimento ad un \itindex{inode} \textit{inode} già esistente si utilizza la funzione -\func{link}; si suole chiamare questo tipo di associazione un collegamento +\funcd{link}; si suole chiamare questo tipo di associazione un collegamento diretto, o \textit{hard link}. Il prototipo della funzione è il seguente: -\begin{prototype}{unistd.h} -{int link(const char *oldpath, const char *newpath)} - Crea un nuovo collegamento diretto. - - \bodydesc{La funzione restituisce 0 in caso di successo e -1 in caso di - errore nel qual caso \var{errno} viene impostata ai valori: + +\begin{funcproto}{ +\fhead{unistd.h} +\fdecl{int link(const char *oldpath, const char *newpath)} +\fdesc{Crea un nuovo collegamento diretto (\textit{hard link}).} +} +{La funzione ritorna $0$ in caso di successo e $-1$ per un errore, + nel qual caso \var{errno} assumerà uno dei 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} @@ -88,29 +1314,30 @@ diretto, o \textit{hard link}. Il prototipo della funzione è il seguente: \item[\errcode{EMLINK}] ci sono troppi link al file \param{oldpath} (il numero massimo è specificato dalla variabile \const{LINK\_MAX}, vedi sez.~\ref{sec:sys_limits}). - \end{errlist} - ed inoltre \errval{EACCES}, \errval{ENAMETOOLONG}, \errval{ENOTDIR}, - \errval{EFAULT}, \errval{ENOMEM}, \errval{EROFS}, \errval{ELOOP}, - \errval{ENOSPC}, \errval{EIO}.} -\end{prototype} - -La funzione crea sul \itindex{pathname} \textit{pathname} \param{newpath} un -collegamento diretto al file indicato da \param{oldpath}. Per quanto detto la -creazione di un nuovo collegamento diretto non copia il contenuto del file, ma -si limita a creare una voce nella directory specificata da \param{newpath} e -ad aumentare di uno il numero di riferimenti al file (riportato nel campo -\var{st\_nlink} della struttura \struct{stat}, vedi sez.~\ref{sec:file_stat}) -aggiungendo il nuovo nome ai precedenti. Si noti che uno stesso file può -essere così chiamato con vari nomi in diverse directory. + \end{errlist} ed inoltre \errval{EACCES}, \errval{ENAMETOOLONG}, + \errval{ENOTDIR}, \errval{EFAULT}, \errval{ENOMEM}, \errval{EROFS}, + \errval{ELOOP}, \errval{ENOSPC}, \errval{EIO} nel loro significato + generico.} +\end{funcproto} + + +La funzione crea sul \textit{pathname} \param{newpath} un collegamento diretto +al file indicato da \param{oldpath}. Per quanto detto la creazione di un +nuovo collegamento diretto non copia il contenuto del file, ma si limita a +creare una voce nella directory specificata da \param{newpath} e ad aumentare +di uno il numero di riferimenti al file (riportato nel campo \var{st\_nlink} +della struttura \struct{stat}, vedi sez.~\ref{sec:file_stat}) aggiungendo il +nuovo nome ai precedenti. Si noti che uno stesso file può essere così chiamato +con vari nomi in diverse directory. Per quanto dicevamo in sez.~\ref{sec:file_filesystem} la creazione di un -collegamento diretto è possibile solo se entrambi i \itindex{pathname} -\textit{pathname} sono nello stesso filesystem; inoltre il filesystem deve -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 +collegamento diretto è possibile solo se entrambi i \textit{pathname} sono +nello stesso filesystem; inoltre il filesystem deve 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 \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.} @@ -125,10 +1352,12 @@ complicata (in genere per questo tipo di errori occorre far girare il programma \cmd{fsck} per riparare il filesystem). Data la pericolosità di questa operazione e la disponibilità dei link -simbolici che possono fornire la stessa funzionalità senza questi problemi, -nel caso di Linux questa capacità è stata completamente disabilitata, e al -tentativo di creare un link diretto ad una directory la funzione \func{link} -restituisce l'errore \errcode{EPERM}. +simbolici (che vedremo in sez.~\ref{sec:file_symlink}) e dei +\itindex{bind~mount} \textit{bind mount} (già visti in +sez.~\ref{sec:sys_file_config}) che possono fornire la stessa funzionalità +senza questi problemi, nel caso di Linux questa capacità è stata completamente +disabilitata, e al tentativo di creare un link diretto ad una directory la +funzione \func{link} restituisce l'errore \errcode{EPERM}. Un ulteriore comportamento peculiare di Linux è quello in cui si crea un \textit{hard link} ad un link simbolico. In questo caso lo standard POSIX @@ -140,10 +1369,9 @@ iniziale di Linux ma a partire dai kernel della serie 2.0.x\footnote{per la kernel di sviluppo 1.3.56, ed è stato temporaneamente ripristinato anche durante lo sviluppo della serie 2.1.x, per poi tornare al comportamento attuale fino ad oggi (per riferimento si veda - \href{http://lwn.net/Articles/293902} - {\texttt{http://lwn.net/Articles/293902}}).} è stato adottato un -comportamento che non segue più lo standard per cui l'\textit{hard link} viene -creato rispetto al link simbolico, e non al file cui questo punta. + \url{http://lwn.net/Articles/293902}).} è stato adottato un comportamento +che non segue più lo standard per cui l'\textit{hard link} viene creato +rispetto al link simbolico, e non al file cui questo punta. La ragione di questa differenza rispetto allo standard, presente anche in altri sistemi unix-like, sono dovute al fatto che un link simbolico può fare @@ -165,24 +1393,24 @@ farlo direttamente.\footnote{ciò non toglie che questo comportamento fuori La rimozione di un file (o più precisamente della voce che lo referenzia all'interno di una directory) si effettua con la funzione \funcd{unlink}; il suo prototipo è il seguente: -\begin{prototype}{unistd.h}{int unlink(const char *pathname)} - Cancella un file. - - \bodydesc{La funzione restituisce zero in caso di successo e -1 per un - errore, nel qual caso il file non viene toccato. La variabile - \var{errno} viene impostata secondo i seguenti codici di errore: +\begin{funcproto}{ +\fhead{unistd.h} +\fdecl{int unlink(const char *pathname)} +\fdesc{Cancella un file.} +} +{La funzione ritorna $0$ in caso di successo e $-1$ per un errore, + nel qual caso \var{errno} assumerà uno dei valori: \begin{errlist} - \item[\errcode{EISDIR}] \param{pathname} si riferisce ad una directory. - \footnotemark + \item[\errcode{EISDIR}] \param{pathname} si riferisce ad una + directory.\footnotemark \item[\errcode{EROFS}] \param{pathname} è su un filesystem montato in sola lettura. \item[\errcode{EISDIR}] \param{pathname} fa riferimento a una directory. - \end{errlist} - ed inoltre: \errval{EACCES}, \errval{EFAULT}, \errval{ENOENT}, + \end{errlist} ed inoltre \errval{EACCES}, \errval{EFAULT}, \errval{ENOENT}, \errval{ENOTDIR}, \errval{ENOMEM}, \errval{EROFS}, \errval{ELOOP}, - \errval{EIO}.} -\end{prototype} + \errval{EIO} nel loro significato generico.} +\end{funcproto} \footnotetext{questo è un valore specifico ritornato da Linux che non consente l'uso di \func{unlink} con le directory (vedi sez.~\ref{sec:file_remove}). @@ -248,16 +1476,17 @@ Questa è la funzione prevista dallo standard ANSI C per cancellare un file o una directory (e funziona anche per i sistemi che non supportano i link diretti). Per i file è identica a \func{unlink} e per le directory è identica a \func{rmdir}; il suo prototipo è: -\begin{prototype}{stdio.h}{int remove(const char *pathname)} - Cancella un nome dal filesystem. - - \bodydesc{La funzione restituisce zero in caso di successo e -1 per un - errore, nel qual caso il file non viene toccato. - - I codici di errore riportati in \var{errno} sono quelli della chiamata - utilizzata, pertanto si può fare riferimento a quanto illustrato nelle - descrizioni di \func{unlink} e \func{rmdir}.} -\end{prototype} + +\begin{funcproto}{ +\fhead{stdio.h} +\fdecl{int remove(const char *pathname)} +\fdesc{Cancella un nome dal filesystem.} +} +{La funzione ritorna $0$ in caso di successo e $-1$ per un errore, nel qual + caso \var{errno} assumerà uno dei valori relativi alla chiamata utilizzata, + pertanto si può fare riferimento a quanto illustrato nelle descrizioni di + \func{unlink} e \func{rmdir}.} +\end{funcproto} La funzione utilizza la funzione \func{unlink}\footnote{questo vale usando le \acr{glibc}; nelle libc4 e nelle libc5 la funzione \func{remove} è un @@ -272,15 +1501,15 @@ nello stesso filesystem) si usa invece la funzione \funcd{rename},\footnote{la funzione è definita dallo standard ANSI C, ma si applica solo per i file, lo standard POSIX estende la funzione anche alle directory.} il cui prototipo è: -\begin{prototype}{stdio.h} - {int rename(const char *oldpath, const char *newpath)} - - Rinomina un file. - - \bodydesc{La funzione restituisce zero in caso di successo e -1 per un - errore, nel qual caso il file non viene toccato. La variabile - \var{errno} viene impostata secondo i seguenti codici di errore: - \begin{errlist} + +\begin{funcproto}{ +\fhead{stdio.h} +\fdecl{int rename(const char *oldpath, const char *newpath)} +\fdesc{Rinomina un file.} +} +{La funzione ritorna $0$ in caso di successo e $-1$ per un errore, + nel qual caso \var{errno} assumerà uno dei valori: + \begin{errlist} \item[\errcode{EISDIR}] \param{newpath} è una directory mentre \param{oldpath} non è una directory. \item[\errcode{EXDEV}] \param{oldpath} e \param{newpath} non sono sullo @@ -288,19 +1517,19 @@ nello stesso filesystem) si usa invece la funzione \funcd{rename},\footnote{la \item[\errcode{ENOTEMPTY}] \param{newpath} è una directory già esistente e 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). + parte di qualche processo (come \index{directory~di~lavoro} directory di + lavoro o come radice) o del 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. - \item[\errcode{ENOTDIR}] uno dei componenti dei \itindex{pathname} - \textit{pathname} non è una directory o \param{oldpath} è una directory e + \item[\errcode{ENOTDIR}] uno dei componenti dei \textit{pathname} non è una + directory o \param{oldpath} è una directory e \param{newpath} esiste e non è una directory. - \end{errlist} - ed inoltre \errval{EACCES}, \errval{EPERM}, \errval{EMLINK}, + \end{errlist} ed inoltre \errval{EACCES}, \errval{EPERM}, \errval{EMLINK}, \errval{ENOENT}, \errval{ENOMEM}, \errval{EROFS}, \errval{ELOOP} e - \errval{ENOSPC}.} -\end{prototype} + \errval{ENOSPC} nel loro significato generico.} +\end{funcproto} La funzione rinomina il file \param{oldpath} in \param{newpath}, eseguendo se necessario lo spostamento di un file fra directory diverse. Eventuali altri @@ -366,13 +1595,15 @@ alcune funzioni di libreria (come \func{open} o \func{stat}) quando ricevono come argomento un link simbolico vengono automaticamente applicate al file da esso specificato. La funzione che permette di creare un nuovo link simbolico è \funcd{symlink}, ed il suo prototipo è: -\begin{prototype}{unistd.h} - {int symlink(const char *oldpath, const char *newpath)} - Crea un nuovo link simbolico di nome \param{newpath} il cui contenuto è - \param{oldpath}. - - \bodydesc{La funzione restituisce zero in caso di successo e -1 per un - errore, nel qual caso la variabile \var{errno} assumerà i valori: + + +\begin{funcproto}{ +\fhead{unistd.h} +\fdecl{int symlink(const char *oldpath, const char *newpath)} +\fdesc{Crea un nuovo link simbolico.} +} +{La funzione ritorna $0$ in caso di successo e $-1$ per un errore, + nel qual caso \var{errno} assumerà uno dei valori: \begin{errlist} \item[\errcode{EPERM}] il filesystem che contiene \param{newpath} non supporta i link simbolici. @@ -381,17 +1612,18 @@ esso specificato. La funzione che permette di creare un nuovo link simbolico \item[\errcode{EEXIST}] esiste già un file \param{newpath}. \item[\errcode{EROFS}] \param{newpath} è su un filesystem montato in sola lettura. - \end{errlist} - ed inoltre \errval{EFAULT}, \errval{EACCES}, \errval{ENAMETOOLONG}, - \errval{ENOTDIR}, \errval{ENOMEM}, \errval{ELOOP}, \errval{ENOSPC} e - \errval{EIO}.} -\end{prototype} - -Si tenga presente che la funzione non effettua nessun controllo sull'esistenza -di un file di nome \param{oldpath}, ma si limita ad inserire quella stringa -nel link simbolico. Pertanto un link simbolico può anche riferirsi ad un file -che non esiste: in questo caso si ha quello che viene chiamato un -\textit{dangling link}, letteralmente un \textsl{link ciondolante}. + \end{errlist} ed inoltre \errval{EFAULT}, \errval{EACCES}, + \errval{ENAMETOOLONG}, \errval{ENOTDIR}, \errval{ENOMEM}, \errval{ELOOP}, + \errval{ENOSPC} e \errval{EIO} nel loro significato generico.} +\end{funcproto} + +La funzione crea un nuovo link simbolico con \textit{pathname} \param{newpath} +che fa riferimento ad \param{oldpath}. Si tenga presente che la funzione non +effettua nessun controllo sull'esistenza di un file di nome \param{oldpath}, +ma si limita ad inserire il \textit{pathname} nel link simbolico. Pertanto un +link simbolico può anche riferirsi ad un file che non esiste: in questo caso +si ha quello che viene chiamato un \textit{dangling link}, letteralmente un +\textsl{link ciondolante}. Come accennato i link simbolici sono risolti automaticamente dal kernel all'invocazione delle varie system call; in tab.~\ref{tab:file_symb_effect} si @@ -496,8 +1728,8 @@ directory porterebbe il comando ad esaminare \file{/boot}, \file{/boot/boot}, \file{/boot/boot/boot} e così via. Per questo motivo il kernel e le librerie prevedono che nella risoluzione di -un \itindex{pathname} \textit{pathname} possano essere seguiti un numero -limitato di link simbolici, il cui valore limite è specificato dalla costante +un \textit{pathname} possano essere seguiti un numero limitato di link +simbolici, il cui valore limite è specificato dalla costante \const{MAXSYMLINKS}. Qualora questo limite venga superato viene generato un errore ed \var{errno} viene impostata al valore \errcode{ELOOP}. @@ -563,8 +1795,8 @@ una opportuna system call.\footnote{questo è quello che permette anche, La funzione crea una nuova directory vuota, che contiene cioè solo le due voci standard presenti in ogni directory (cioè ``\file{.}'' e ``\file{..}''), con il nome indicato dall'argomento \param{dirname}. Il nome può essere indicato -sia come \itindex{pathname} \textit{pathname} assoluto che come -\itindex{pathname} \textit{pathname} relativo. +sia come \itindsub{pathname}{assoluto} \textit{pathname} assoluto che come +\itindsub{pathname}{relativo} \textit{pathname} relativo. I permessi di accesso (vedi sez.~\ref{sec:file_access_control}) con cui la directory viene creata sono specificati dall'argomento \param{mode}, i cui @@ -584,14 +1816,15 @@ 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'\ids{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 di attraversare (esecuzione) una delle directory specificate in \param{dirname}. - \item[\errcode{EBUSY}] la directory specificata è la directory di lavoro o la - radice di qualche processo. + \item[\errcode{EBUSY}] la directory specificata è la + \index{directory~di~lavoro} directory di lavoro o la radice di qualche + processo. \item[\errcode{ENOTEMPTY}] la directory non è vuota. \end{errlist} ed inoltre anche \errval{EFAULT}, \errval{ENAMETOOLONG}, \errval{ENOENT}, @@ -600,8 +1833,8 @@ La funzione che permette la cancellazione di una directory è invece La funzione cancella la directory \param{dirname}, che deve essere vuota (la directory deve cioè contenere soltanto le due voci standard ``\file{.}'' e -``\file{..}''). Il nome può essere indicato con il \itindex{pathname} -\textit{pathname} assoluto o relativo. +``\file{..}''). Il nome può essere indicato con il \textit{pathname} assoluto +o relativo. La modalità con cui avviene la cancellazione è analoga a quella di \func{unlink}: fintanto che il numero di link \itindex{inode} @@ -722,12 +1955,12 @@ 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 +Le macro sono definite nel file \headfile{sys/sysmacros.h}, che viene +automaticamente incluso quando si include \headfile{sys/types.h}; si possono pertanto ottenere i valori del \itindex{major~number} \textit{major number} e \itindex{minor~number} \textit{minor number} di un dispositivo rispettivamente con le macro \macro{major} e \macro{minor}: @@ -855,7 +2088,7 @@ La funzione restituisce il file descriptor associato al \textit{directory stream} \param{dir}. Di solito si utilizza questa funzione in abbinamento a funzioni che operano sui file descriptor, ad esempio si potrà usare \func{fstat} per ottenere le proprietà della directory, o \func{fchdir} per -spostare su di essa la directory di lavoro (vedi +spostare su di essa la \index{directory~di~lavoro} directory di lavoro (vedi sez.~\ref{sec:file_work_dir}). Viceversa se si è aperto un file descriptor corrispondente ad una directory è @@ -918,7 +2151,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 @@ -938,7 +2171,7 @@ volte che si ripete la lettura di una voce sullo stesso \textit{directory stream}. Di questa funzione esiste anche una versione \index{funzioni!rientranti} -rientrante, \func{readdir\_r},\footnote{per usarla è necessario definire una +rientrante, \funcd{readdir\_r},\footnote{per usarla è necessario definire una qualunque delle macro \texttt{\macro{\_POSIX\_C\_SOURCE} >= 1}, \macro{\_XOPEN\_SOURCE}, \macro{\_BSD\_SOURCE}, \macro{\_SVID\_SOURCE}, \macro{\_POSIX\_SOURCE}.} che non usa una struttura allocata staticamente, e @@ -1110,12 +2343,12 @@ La funzione legge tutte le voci della directory indicata dall'argomento \struct{dirent}) come argomento della funzione di selezione specificata da \param{filter}; se questa ritorna un valore diverso da zero il puntatore viene inserito in un vettore che viene allocato dinamicamente con \func{malloc}. -Qualora si specifichi un valore \val{NULL} per l'argomento \func{filter} non +Qualora si specifichi un valore \val{NULL} per l'argomento \param{filter} non viene fatta nessuna selezione e si ottengono tutte le voci presenti. -Le voci selezionate possono essere riordinate tramite \func{qsort}, le modalità -del riordinamento possono essere personalizzate usando la funzione -\param{compar} come criterio di ordinamento di \func{qsort}, la funzione +Le voci selezionate possono essere riordinate tramite \funcm{qsort}, le +modalità del riordinamento possono essere personalizzate usando la funzione +\param{compar} come criterio di ordinamento di \funcm{qsort}, la funzione prende come argomenti le due strutture \struct{dirent} da confrontare restituendo un valore positivo, nullo o negativo per indicarne l'ordinamento; alla fine l'indirizzo della lista ordinata dei puntatori alle strutture @@ -1152,13 +2385,13 @@ La funzione \func{alphasort} deriva da BSD ed è presente in Linux fin dalle campo \var{d\_name} delle varie voci). Le \acr{glibc} prevedono come estensione\footnote{le glibc, a partire dalla versione 2.1, effettuano anche l'ordinamento alfabetico tenendo conto delle varie localizzazioni, usando - \func{strcoll} al posto di \func{strcmp}.} anche \func{versionsort}, che + \funcm{strcoll} al posto di \funcm{strcmp}.} anche \func{versionsort}, che 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 +2428,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 @@ -1212,17 +2445,18 @@ una directory. La funzione inizia con l'aprire (\texttt{\small 18--22}) uno stream sulla directory passata come primo argomento, stampando un messaggio in caso di errore. -Il passo successivo (\texttt{\small 23--24}) è cambiare directory di lavoro -(vedi sez.~\ref{sec:file_work_dir}), usando in sequenza le funzioni -\func{dirfd} e \func{fchdir} (in realtà si sarebbe potuto usare direttamente -\func{chdir} su \var{dirname}), in modo che durante il successivo ciclo -(\texttt{\small 26--30}) sulle singole voci dello stream ci si trovi -all'interno della directory.\footnote{questo è essenziale al funzionamento - della funzione \code{do\_ls}, e ad ogni funzione che debba usare il campo - \var{d\_name}, in quanto i nomi dei file memorizzati all'interno di una - struttura \struct{dirent} sono sempre relativi alla directory in questione, - e senza questo posizionamento non si sarebbe potuto usare \func{stat} per - ottenere le dimensioni.} +Il passo successivo (\texttt{\small 23--24}) è cambiare +\index{directory~di~lavoro} directory di lavoro (vedi +sez.~\ref{sec:file_work_dir}), usando in sequenza le funzioni \func{dirfd} e +\func{fchdir} (in realtà si sarebbe potuto usare direttamente \func{chdir} su +\var{dirname}), in modo che durante il successivo ciclo (\texttt{\small + 26--30}) sulle singole voci dello stream ci si trovi all'interno della +directory.\footnote{questo è essenziale al funzionamento della funzione + \code{do\_ls}, e ad ogni funzione che debba usare il campo \var{d\_name}, in + quanto i nomi dei file memorizzati all'interno di una struttura + \struct{dirent} sono sempre relativi alla directory in questione, e senza + questo posizionamento non si sarebbe potuto usare \func{stat} per ottenere + le dimensioni.} Avendo usato lo stratagemma di fare eseguire tutte le manipolazioni necessarie alla funzione passata come secondo argomento, il ciclo di scansione della @@ -1245,13 +2479,13 @@ chiusura (\texttt{\small 32}) dello stream\footnote{nel nostro caso, uscendo \subsection{La directory di lavoro} \label{sec:file_work_dir} -\itindbeg{pathname} +\index{directory~di~lavoro|(} Come accennato in sez.~\ref{sec:proc_fork} a ciascun processo è associata una directory nel filesystem,\footnote{questa viene mantenuta all'interno dei dati - della sua \struct{task\_struct} (vedi fig.~\ref{fig:proc_task_struct}), più + della sua \kstruct{task\_struct} (vedi fig.~\ref{fig:proc_task_struct}), più precisamente nel campo \texttt{pwd} della sotto-struttura - \struct{fs\_struct}.} che è chiamata \textsl{directory corrente} o + \kstruct{fs\_struct}.} che è chiamata \textsl{directory corrente} o \textsl{directory di lavoro} (in inglese \textit{current working directory}). La directory di lavoro è quella da cui si parte quando un \itindsub{pathname}{relativo} \textit{pathname} è espresso in forma relativa, @@ -1324,11 +2558,11 @@ la directory corrente (vale a dire ``\texttt{.}'') e tornarvi in seguito con Una seconda usata per ottenere la directory di lavoro è \code{char *get\_current\_dir\_name(void)} che è sostanzialmente equivalente ad una \code{getcwd(NULL, 0)}, con la sola differenza che essa ritorna il valore -della variabile di ambiente \val{PWD}, che essendo costruita dalla shell può -contenere un \textit{pathname} comprendente anche dei link simbolici. Usando -\func{getcwd} infatti, essendo il \textit{pathname} ricavato risalendo -all'indietro l'albero della directory, si perderebbe traccia di ogni passaggio -attraverso eventuali link simbolici. +della variabile di ambiente \envvar{PWD}, che essendo costruita dalla shell +può contenere un \textit{pathname} comprendente anche dei link +simbolici. Usando \func{getcwd} infatti, essendo il \textit{pathname} ricavato +risalendo all'indietro l'albero della directory, si perderebbe traccia di ogni +passaggio attraverso eventuali link simbolici. Per cambiare la directory di lavoro si può usare la funzione \funcd{chdir} (equivalente del comando di shell \cmd{cd}) il cui nome sta appunto per @@ -1366,8 +2600,7 @@ possibile (tutti gli altri sarebbero occorsi all'apertura di \param{fd}), è quello in cui il processo non ha il permesso di accesso alla directory specificata da \param{fd}. -\itindend{pathname} - +\index{directory~di~lavoro|)} \subsection{I file temporanei} @@ -1404,10 +2637,10 @@ massimo di \const{TMP\_MAX} volte, limite oltre il quale il comportamento è indefinito. Al nome viene automaticamente aggiunto come prefisso la directory specificata dalla costante \const{P\_tmpdir}.\footnote{le costanti \const{L\_tmpnam}, \const{P\_tmpdir} e \const{TMP\_MAX} sono definite in - \file{stdio.h}.} + \headfile{stdio.h}.} Di questa funzione esiste una versione \index{funzioni!rientranti} rientrante, -\func{tmpnam\_r}, che non fa nulla quando si passa \val{NULL} come argomento. +\funcm{tmpnam\_r}, che non fa nulla quando si passa \val{NULL} come argomento. Una funzione simile, \funcd{tempnam}, permette di specificare un prefisso per il file esplicitamente, il suo prototipo è: \begin{prototype}{stdio.h}{char *tempnam(const char *dir, const char *pfx)} @@ -1425,7 +2658,7 @@ L'argomento \param{pfx} specifica un prefisso di massimo 5 caratteri per il nome provvisorio. La funzione assegna come directory per il file temporaneo, verificando che esista e sia accessibile, la prima valida fra le seguenti: \begin{itemize*} -\item La variabile di ambiente \const{TMPDIR} (non ha effetto se non è +\item La variabile di ambiente \envvar{TMPDIR} (non ha effetto se non è definita o se il programma chiamante è \itindex{suid~bit} \acr{suid} o \itindex{sgid~bit} \acr{sgid}, vedi sez.~\ref{sec:file_special_perm}). \item il valore dell'argomento \param{dir} (se diverso da \val{NULL}). @@ -1489,7 +2722,7 @@ La funzionane genera un nome univoco sostituendo le \code{XXXXXX} finali di funzione non si può usare una stringa costante. Tutte le avvertenze riguardo alle possibili \itindex{race~condition} \textit{race condition} date per \func{tmpnam} continuano a valere; inoltre in alcune vecchie implementazioni -il valore usato per sostituire le \code{XXXXXX} viene formato con il \acr{pid} +il valore usato per sostituire le \code{XXXXXX} viene formato con il \ids{PID} del processo più una lettera, il che mette a disposizione solo 26 possibilità diverse per il nome del file, e rende il nome temporaneo facile da indovinare. Per tutti questi motivi la funzione è deprecata e non dovrebbe mai essere @@ -1523,7 +2756,7 @@ sez.~\ref{sec:file_perm_overview}) sono impostati al valore \code{0600} questa funzione esiste una variante \funcd{mkostemp}, introdotta specificamente dalla \acr{glibc},\footnote{la funzione è stata introdotta nella versione 2.7 delle librerie e richiede che sia definita la macro - \const{\_GNU\_SOURCE}.} il cui prototipo è: + \macro{\_GNU\_SOURCE}.} il cui prototipo è: \begin{prototype}{stlib.h}{int mkostemp(char *template, int flags)} Genera un file temporaneo. @@ -1597,16 +2830,16 @@ funzioni \funcd{stat}, \funcd{fstat} e \funcd{lstat}, i cui prototipi sono: \errval{EACCES}, \errval{ENOMEM}, \errval{ENAMETOOLONG}.} \end{functions} -La funzione \func{stat} legge le informazioni del file il cui pathname è -specificato dalla stringa puntata da \param{file\_name} e le inserisce nel -buffer puntato dall'argomento \param{buf}; la funzione \func{lstat} è identica -a \func{stat} eccetto che se \param{file\_name} è un link simbolico vengono -lette le informazioni relative ad esso e non al file a cui fa -riferimento. Infine \func{fstat} esegue la stessa operazione su un file già -aperto, specificato tramite il suo file descriptor \param{filedes}. +La funzione \func{stat} legge le informazioni del file il cui +\textit{pathname} è specificato dalla stringa puntata da \param{file\_name} e +le inserisce nel buffer puntato dall'argomento \param{buf}; la funzione +\func{lstat} è identica a \func{stat} eccetto che se \param{file\_name} è un +link simbolico vengono lette le informazioni relative ad esso e non al file a +cui fa riferimento. Infine \func{fstat} esegue la stessa operazione su un file +già aperto, specificato tramite il suo file descriptor \param{filedes}. La struttura \struct{stat} usata da queste funzioni è definita nell'header -\file{sys/stat.h} e in generale dipende dall'implementazione; la versione +\headfile{sys/stat.h} e in generale dipende dall'implementazione; la versione usata da Linux è mostrata in fig.~\ref{fig:file_stat_struct}, così come riportata dalla pagina di manuale di \func{stat}; in realtà la definizione effettivamente usata nel kernel dipende dall'architettura e ha altri campi @@ -1616,7 +2849,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 @@ -1627,7 +2860,7 @@ sez.~\ref{sec:file_file_times}), o per il padding dei campi. Si noti come i vari membri della struttura siano specificati come tipi primitivi del sistema (di quelli definiti in -tab.~\ref{tab:intro_primitive_types}, e dichiarati in \file{sys/types.h}). +tab.~\ref{tab:intro_primitive_types}, e dichiarati in \headfile{sys/types.h}). \subsection{I tipi di file} \label{sec:file_types} @@ -1652,23 +2885,23 @@ 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}).} + \caption{Macro per i tipi di file (definite in \headfile{sys/stat.h}).} \label{tab:file_type_macro} \end{table} Oltre alle macro di tab.~\ref{tab:file_type_macro} è possibile usare direttamente il valore di \var{st\_mode} per ricavare il tipo di file controllando direttamente i vari bit in esso memorizzati. Per questo sempre in -\file{sys/stat.h} sono definite le costanti numeriche riportate in +\headfile{sys/stat.h} sono definite le costanti numeriche riportate in tab.~\ref{tab:file_mode_flags}. Il primo valore dell'elenco di tab.~\ref{tab:file_mode_flags} è la maschera @@ -1715,7 +2948,7 @@ un'opportuna combinazione. \hline \end{tabular} \caption{Costanti per l'identificazione dei vari bit che compongono il campo - \var{st\_mode} (definite in \file{sys/stat.h}).} + \var{st\_mode} (definite in \headfile{sys/stat.h}).} \label{tab:file_mode_flags} \end{table} @@ -1732,8 +2965,8 @@ poi si effettua il confronto con la combinazione di tipi scelta. Il campo \var{st\_size} di una struttura \struct{stat} contiene la dimensione del file in byte, se si tratta di un file regolare. Nel caso di un link -simbolico la dimensione è quella del \itindex{pathname} \textit{pathname} che -il link stesso contiene; per le fifo questo campo è sempre nullo. +simbolico la dimensione è quella del \textit{pathname} che il link stesso +contiene; per le fifo questo campo è sempre nullo. Il campo \var{st\_blocks} definisce la lunghezza del file in blocchi di 512 byte. Il campo \var{st\_blksize} infine definisce la dimensione preferita per @@ -1785,8 +3018,7 @@ dimensione si possono usare le due funzioni \funcd{truncate} e per \func{truncate} si hanno: \begin{errlist} \item[\errcode{EACCES}] il file non ha permesso di scrittura o non si ha il - permesso di esecuzione una delle directory del \itindex{pathname} - \textit{pathname}. + permesso di esecuzione una delle directory del \textit{pathname}. \item[\errcode{ETXTBSY}] il file è un programma in esecuzione. \end{errlist} ed anche \errval{ENOTDIR}, \errval{ENAMETOOLONG}, \errval{ENOENT}, @@ -1795,9 +3027,9 @@ dimensione si possono usare le due funzioni \funcd{truncate} e Entrambe le funzioni fan sì che la dimensione del file sia troncata ad un valore massimo specificato da \param{length}, e si distinguono solo per il -fatto che il file viene indicato con il pathname \param{file\_name} per -\func{truncate} e con il file descriptor \param{fd} per \funcd{ftruncate}; se -il file è più lungo della lunghezza specificata i dati in eccesso saranno +fatto che il file viene indicato con il \textit{pathname} \param{file\_name} +per \func{truncate} e con il file descriptor \param{fd} per \funcd{ftruncate}; +se il file è più lungo della lunghezza specificata i dati in eccesso saranno perduti. Il comportamento in caso di lunghezza inferiore non è specificato e dipende @@ -1874,6 +3106,8 @@ accesso in lettura sui dati bufferizzati. Questo comporta un ovvio costo sia in termini di prestazioni, che di consumo di risorse come la batteria per i portatili, o cicli di riscrittura per i dischi su memorie riscrivibili. +% TODO aggiustare per il contenuto duplicato con le analoghe MS_* + Per questo motivo, onde evitare di mantenere una informazione che nella maggior parte dei casi non interessa, è sempre stato possibile disabilitare l'aggiornamento del tempo di ultimo accesso con l'opzione di montaggio @@ -2016,7 +3250,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 +3313,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 +3385,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 +3396,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 @@ -2175,7 +3409,7 @@ Queste due funzioni sono una estensione definita in una recente revisione dello standard POSIX (la POSIX.1-2008); sono state introdotte a partire dal kernel 2.6.22, e supportate dalle \acr{glibc} a partire dalla versione 2.6.\footnote{in precedenza, a partire dal kernel 2.6.16, era stata introdotta - la funzione \func{futimesat} seguendo una bozza della revisione dello + la funzione \funcm{futimesat} seguendo una bozza della revisione dello standard poi modificata, questa funzione, sostituita da \func{utimensat}, è stata dichiarata obsoleta, non è supportata da nessuno standard e non deve essere più utilizzata: pertanto non la tratteremo.} La prima è @@ -2183,12 +3417,12 @@ sostanzialmente una estensione di \func{futimes} che consente di specificare i tempi con precisione maggiore, la seconda supporta invece, rispetto ad \func{utimes}, una sintassi più complessa che, come vedremo in sez.~\ref{sec:file_openat} consente una indicazione sicura dei -\textit{pathname relativi} specificando la directory da usare come riferimento -in \param{dirfd} e la possibilità di usare \param{flags} per indicare alla -funzione di dereferenziare o meno i link simbolici; si rimanda pertanto la -spiegazione del significato degli argomenti aggiuntivi alla trattazione -generica delle varie funzioni che usano la stessa sintassi, effettuata in -sez.~\ref{sec:file_openat}. +\itindsub{pathname}{relativo} \textit{pathname relativi} specificando la +directory da usare come riferimento in \param{dirfd} e la possibilità di +usare \param{flags} per indicare alla funzione di dereferenziare o meno i link +simbolici; si rimanda pertanto la spiegazione del significato degli argomenti +aggiuntivi alla trattazione generica delle varie funzioni che usano la stessa +sintassi, effettuata in sez.~\ref{sec:file_openat}. \section{Il controllo di accesso ai file} @@ -2208,7 +3442,7 @@ concetti essenziali e le funzioni usate per gestirne i vari aspetti. Ad ogni file Linux associa sempre l'utente che ne è proprietario (il cosiddetto \textit{owner}) ed un gruppo di appartenenza, secondo il meccanismo -degli identificatori di utente e gruppo (\acr{uid} e \acr{gid}). Questi valori +degli identificatori di utente e gruppo (\ids{UID} e \ids{GID}). Questi valori sono accessibili da programma tramite la funzione \func{stat}, e sono mantenuti nei campi \var{st\_uid} e \var{st\_gid} della struttura \struct{stat} (si veda sez.~\ref{sec:file_stat}).\footnote{questo è vero solo @@ -2309,15 +3543,15 @@ limiteremo ad un riassunto delle regole generali, entrando nei dettagli più avanti. La prima regola è che per poter accedere ad un file attraverso il suo -\itindex{pathname} \textit{pathname} occorre il permesso di esecuzione in -ciascuna delle directory che compongono il \textit{pathname}; lo stesso vale -per aprire un file nella directory corrente (per la quale appunto serve il -diritto di esecuzione). +\textit{pathname} occorre il permesso di esecuzione in ciascuna delle +directory che compongono il \textit{pathname}; lo stesso vale per aprire un +file nella directory corrente (per la quale appunto serve il diritto di +esecuzione). Per una directory infatti il permesso di esecuzione significa che essa può -essere attraversata nella risoluzione del \itindex{pathname} -\textit{pathname}, ed è distinto dal permesso di lettura che invece implica -che si può leggere il contenuto della directory. +essere attraversata nella risoluzione del \textit{pathname}, ed è distinto dal +permesso di lettura che invece implica che si può leggere il contenuto della +directory. Questo significa che se si ha il permesso di esecuzione senza permesso di lettura si potrà lo stesso aprire un file in una directory (se si hanno i @@ -2355,8 +3589,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'\ids{UID} effettivo, il \ids{GID} +effettivo e gli eventuali \ids{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 +3599,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 -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 +sez.~\ref{sec:file_special_perm}, l'\ids{UID} effettivo e il \ids{GID} effettivo +corrispondono ai valori dell'\ids{UID} e del \ids{GID} dell'utente che ha +lanciato il processo, mentre i \ids{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'\ids{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'\ids{UID} effettivo del processo è uguale all'\ids{UID} del proprietario del file (nel qual caso si dice che il processo è proprietario del file) allora: \begin{itemize*} @@ -2387,8 +3621,8 @@ 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 - dei processi corrispondono al \acr{gid} del file allora: +\item Se il \ids{GID} effettivo del processo o uno dei \ids{GID} supplementari + dei processi corrispondono al \ids{GID} del file allora: \begin{itemize*} \item se il bit dei permessi d'accesso del gruppo è impostato, l'accesso è consentito, @@ -2429,9 +3663,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 -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 +kernel assegnerà come \ids{UID} effettivo al nuovo processo l'\ids{UID} del +proprietario del file al posto dell'\ids{UID} del processo originario. Avere +il bit \acr{sgid} impostato ha lo stesso effetto sul \ids{GID} effettivo del processo. I bit \acr{suid} e \acr{sgid} vengono usati per permettere agli utenti normali @@ -2528,10 +3762,10 @@ 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 -\acr{gid} relativi all'utente che ha lanciato il programma, e che, come +file viene fatto utilizzando l'\ids{UID} ed il \ids{GID} effettivo del processo; +ci sono casi però in cui si può voler effettuare il controllo con l'\ids{UID} +reale ed il \ids{GID} reale, vale a dire usando i valori di \ids{UID} e +\ids{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 +3855,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'\ids{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 +3919,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'\ids{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 +3929,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'\ids{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 +3939,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'\ids{UID} effettivo del processo è zero). \end{enumerate} Per alcuni filesystem\footnote{i filesystem più comuni (\textsl{ext2}, @@ -2737,8 +3971,8 @@ lettura), che però può fornire un valore che è lo stesso per tutti e tre i permessi di sez.~\ref{sec:file_perm_overview} (cioè $666$ nel primo caso e $222$ nel secondo). Per questo motivo il sistema associa ad ogni processo\footnote{è infatti contenuta nel campo \var{umask} della struttura - \struct{fs\_struct}, vedi fig.~\ref{fig:proc_task_struct}.} una maschera di -bit, la cosiddetta \textit{umask}, che viene utilizzata per impedire che + \kstruct{fs\_struct}, vedi fig.~\ref{fig:proc_task_struct}.} una maschera +di bit, la cosiddetta \textit{umask}, che viene utilizzata per impedire che alcuni permessi possano essere assegnati ai nuovi file in sede di creazione. I bit indicati nella maschera vengono infatti cancellati dai permessi quando un nuovo file viene creato.\footnote{l'operazione viene fatta sempre: anche @@ -2778,21 +4012,21 @@ quale utente e gruppo esso deve appartenere. Lo stesso problema si presenta 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 -due diverse possibilità: +Lo standard POSIX prescrive che l'\ids{UID} del nuovo file corrisponda +all'\ids{UID} effettivo del processo che lo crea; per il \ids{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} della directory in cui +\item il \ids{GID} del file corrisponde al \ids{GID} effettivo del processo. +\item il \ids{GID} del file corrisponde al \ids{GID} della directory in cui esso è creato. \end{itemize*} in genere BSD usa sempre la seconda possibilità, che viene per questo chiamata semantica BSD. Linux invece segue quella che viene chiamata semantica SVr4; di norma cioè il nuovo file viene creato, seguendo la prima opzione, con il -\acr{gid} del processo, se però la directory in cui viene creato il file ha il +\ids{GID} del processo, se però la directory in cui viene creato il file ha il bit \acr{sgid} impostato allora viene usata la seconda opzione. -Usare la semantica BSD ha il vantaggio che il \acr{gid} viene sempre +Usare la semantica BSD ha il vantaggio che il \ids{GID} viene sempre automaticamente propagato, restando coerente a quello della directory di partenza, in tutte le sotto-directory. @@ -2801,7 +4035,7 @@ risultato di coerenza che si ha con BSD necessita che quando si creano nuove directory venga anche propagato anche il bit \acr{sgid}. Questo è il comportamento predefinito del comando \cmd{mkdir}, ed è in questo modo ad esempio che le varie distribuzioni assicurano che le sotto-directory create -nella home di un utente restino sempre con il \acr{gid} del gruppo primario +nella home di un utente restino sempre con il \ids{GID} del gruppo primario dello stesso. La presenza del bit \acr{sgid} è inoltre molto comoda quando si hanno @@ -2833,7 +4067,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'\ids{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 +4298,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 +4320,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 @@ -3103,22 +4337,23 @@ casi: sicurezza che si sta utilizzando al momento (ciascuno avrà le sue). Se non è stato caricato nessun modulo di sicurezza l'accesso in lettura sarà consentito a tutti i processi, mentre quello in scrittura solo ai processi - con privilegi amministrativi dotati della \index{capabilities} + con privilegi amministrativi dotati della \itindex{capabilities} \textit{capability} \const{CAP\_SYS\_ADMIN}. \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} \itindex{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 - privilegi amministrativi dotati della \index{capabilities} + privilegi amministrativi dotati della \itindex{capabilities} \textit{capability} \const{CAP\_SYS\_ADMIN}. In questo modo si possono utilizzare questi attributi per realizzare in user space dei meccanismi di controllo che accedono ad informazioni non disponibili ai processi ordinari. @@ -3160,7 +4395,7 @@ casi: per evitare eventuali abusi, se una directory ha lo \itindex{sticky~bit} \textit{sticky bit} attivo sarà consentito scrivere i suoi \textit{extended user attributes} soltanto se si è proprietari della stessa, o si hanno i - privilegi amministrativi della capability \index{capabilities} + privilegi amministrativi della capability \itindex{capabilities} \const{CAP\_FOWNER}. \end{basedescript} @@ -3206,12 +4441,12 @@ simbolico e ad un file descriptor; i rispettivi prototipi sono: \end{functions} Le funzioni \func{getxattr} e \func{lgetxattr} prendono come primo argomento -un pathname che indica il file di cui si vuole richiedere un attributo, la -sola differenza è che la seconda, se il pathname indica un link simbolico, -restituisce gli attributi di quest'ultimo e non quelli del file a cui esso fa -riferimento. La funzione \func{fgetxattr} prende invece come primo argomento -un numero di file descriptor, e richiede gli attributi del file ad esso -associato. +un \textit{pathname} che indica il file di cui si vuole richiedere un +attributo, la sola differenza è che la seconda, se il \textit{pathname} indica +un link simbolico, restituisce gli attributi di quest'ultimo e non quelli del +file a cui esso fa riferimento. La funzione \func{fgetxattr} prende invece +come primo argomento un numero di file descriptor, e richiede gli attributi +del file ad esso associato. Tutte e tre le funzioni richiedono di specificare nell'argomento \param{name} il nome dell'attributo di cui si vuole ottenere il valore. Il nome deve essere @@ -3376,7 +4611,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 @@ -3434,7 +4669,7 @@ può impostare una ACL aggiuntiva, detta \textit{default ACL}, che serve ad indicare quale dovrà essere la ACL assegnata di default nella creazione di un file all'interno della directory stessa. Come avviene per i permessi le ACL possono essere impostate solo del proprietario del file, o da un processo con -la capability \index{capabilities} \const{CAP\_FOWNER}. +la capability \itindex{capabilities} \const{CAP\_FOWNER}. \begin{table}[htb] \centering @@ -3543,15 +4778,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'\ids{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'\ids{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'\ids{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 +4794,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 \ids{GID} del processo o uno dei \ids{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 +4803,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 \ids{GID} del processo o uno dei \ids{GID} supplementari corrisponde ad un qualunque qualificatore presente in una voce \const{ACL\_GROUP} allora: \begin{itemize*} @@ -3605,7 +4840,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 +4854,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 @@ -3741,12 +4977,13 @@ sono: Le due funzioni ritornano, con un oggetto di tipo \type{acl\_t}, il valore della ACL correntemente associata ad un file, che può essere identificato -tramite un file descriptor usando \func{acl\_get\_fd} o con un pathname usando -\func{acl\_get\_file}. Nel caso di quest'ultima funzione, che può richiedere -anche la ACL relativa ad una directory, il secondo argomento \param{type} -consente di specificare se si vuole ottenere la ACL di default o quella di -accesso. Questo argomento deve essere di tipo \type{acl\_type\_t} e può -assumere solo i due valori riportati in tab.~\ref{tab:acl_type}. +tramite un file descriptor usando \func{acl\_get\_fd} o con un +\textit{pathname} usando \func{acl\_get\_file}. Nel caso di quest'ultima +funzione, che può richiedere anche la ACL relativa ad una directory, il +secondo argomento \param{type} consente di specificare se si vuole ottenere la +ACL di default o quella di accesso. Questo argomento deve essere di tipo +\type{acl\_type\_t} e può assumere solo i due valori riportati in +tab.~\ref{tab:acl_type}. \begin{table}[htb] \centering @@ -3878,7 +5115,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 +5148,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.\\ + \ids{UID} e \ids{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 @@ -4073,19 +5310,20 @@ directory, ed il cui prototipo è: \end{functions} La funzione consente di assegnare la ACL contenuta in \param{acl} al file o -alla directory indicate dal pathname \param{path}, mentre con \param{type} si -indica il tipo di ACL utilizzando le costanti di tab.~\ref{tab:acl_type}, ma -si tenga presente che le ACL di default possono essere solo impostate -qualora \param{path} indichi una directory. Inoltre perché la funzione abbia -successo la ACL dovrà essere valida, e contenere tutti le voci necessarie, -unica eccezione è quella in cui si specifica una ACL vuota per cancellare la -ACL di default associata a \func{path}.\footnote{questo però è una estensione - della implementazione delle ACL di Linux, la bozza di standard POSIX.1e - prevedeva l'uso della apposita funzione \funcd{acl\_delete\_def\_file}, che - prende come unico argomento il pathname della directory di cui si vuole - cancellare l'ACL di default, per i dettagli si ricorra alla pagina di - manuale.} La seconda funzione che consente di impostare una ACL è -\funcd{acl\_set\_fd}, ed il suo prototipo è: +alla directory indicate dal \textit{pathname} \param{path}, mentre +con \param{type} si indica il tipo di ACL utilizzando le costanti di +tab.~\ref{tab:acl_type}, ma si tenga presente che le ACL di default possono +essere solo impostate qualora \param{path} indichi una directory. Inoltre +perché la funzione abbia successo la ACL dovrà essere valida, e contenere +tutti le voci necessarie, unica eccezione è quella in cui si specifica una ACL +vuota per cancellare la ACL di default associata a +\param{path}.\footnote{questo però è una estensione della implementazione delle + ACL di Linux, la bozza di standard POSIX.1e prevedeva l'uso della apposita + funzione \funcd{acl\_delete\_def\_file}, che prende come unico argomento il + \textit{pathname} della directory di cui si vuole cancellare l'ACL di + default, per i dettagli si ricorra alla pagina di manuale.} La seconda +funzione che consente di impostare una ACL è \funcd{acl\_set\_fd}, ed il suo +prototipo è: \begin{functions} \headdecl{sys/types.h} \headdecl{sys/acl.h} @@ -4144,7 +5382,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} @@ -4237,7 +5475,7 @@ La funzione richiede che il filesystem sul quale si vuole operare sia montato con il supporto delle quote abilitato; esso deve essere specificato con il nome del file di dispositivo nell'argomento \param{dev}. Per le operazioni che lo richiedono inoltre si dovrà indicare con l'argomento \param{id} l'utente o -il gruppo (specificati rispettivamente per \acr{uid} e \acr{gid}) su cui si +il gruppo (specificati rispettivamente per \ids{UID} e \ids{GID}) su cui si vuole operare. Alcune operazioni usano l'argomento \param{addr} per indicare un indirizzo ad un area di memoria il cui utilizzo dipende dall'operazione stessa. @@ -4254,67 +5492,122 @@ deve applicarsi alle quote utente o alle quote gruppo, nel qual caso \param{type} deve essere rispettivamente \const{USRQUOTA} o \const{GRPQUOTA}. -Le diverse operazioni supportate da \func{quotactl}, da indicare con -l'argomento \param{subcmd} di \macro{QCMD}, sono riportate in tab. \begin{table}[htb] \centering \footnotesize \begin{tabular}{|l|p{10cm}|} \hline - \textbf{Tipo} & \textbf{Descrizione} \\ + \textbf{Comando} & \textbf{Descrizione} \\ \hline \hline - \const{Q\_QUOTAON} & attiva l'applicazione delle quote disco per il - filesystem \param{dev}, si deve passare - in \param{addr} il pathname al file che mantiene le - quote, che deve esistere; l'operazione richiede i - privilegi di amministratore,\footnotemark \param{id} - viene ignorato.\\ - \const{Q\_QUOTAOFF} & disattiva l'applicazione delle quote disco per il - filesystem \param{dev}; l'operazione richiede i - privilegi di amministratore, \param{id} - e \param{addr} vengono ignorati.\\ - \const{Q\_GETQUOTA} & legge i limiti ed i valori correnti delle quote nel - filesystem \param{dev} per l'utente o il gruppo - specificato da \param{id}; si devono avere i - privilegi di amministratore per leggere i dati + \const{Q\_QUOTAON} & Attiva l'applicazione delle quote disco per il + filesystem indicato da \param{dev}, si deve passare + in \param{addr} il \textit{pathname} al file che + mantiene le quote, che deve esistere, e \param{id} + deve indicare la versione del formato con uno dei + valori di tab.~\ref{tab:quotactl_id_format}; + l'operazione richiede i privilegi di + amministratore.\\ + \const{Q\_QUOTAOFF} & Disattiva l'applicazione delle quote disco per il + filesystem indicato da \param{dev}, \param{id} + e \param{addr} vengono ignorati; l'operazione + richiede i privilegi di amministratore.\\ + \const{Q\_GETQUOTA} & Legge i limiti ed i valori correnti delle quote nel + filesystem indicato da \param{dev} per l'utente o + il gruppo specificato da \param{id}; si devono avere + i privilegi di amministratore per leggere i dati relativi ad altri utenti o a gruppi di cui non si fa parte, il risultato viene restituito in una struttura \struct{dqblk} all'indirizzo indicato da \param{addr}.\\ - \const{Q\_SETQUOTA} & imposta le quote nel filesystem \param{dev} per - l'utente o il gruppo specificato da \param{id} come - ottenuti dalla struttura \struct{dqblk} puntata - da \param{addr}; l'operazione richiede i - privilegi di amministratore.\\ - \const{Q\_GETINFO} & .\\ - \const{Q\_SETINFO} & .\\ - \const{Q\_GETFMT} & .\\ + \const{Q\_SETQUOTA} & Imposta i limiti per le quote nel filesystem + indicato da \param{dev} per l'utente o il gruppo + specificato da \param{id} secondo i valori ottenuti + dalla struttura \struct{dqblk} puntata + da \param{addr}; l'operazione richiede i privilegi + di amministratore.\\ + \const{Q\_GETINFO} & Legge le informazioni (in sostanza i \textit{grace + time}) delle quote del filesystem indicato + da \param{dev} sulla struttura \struct{dqinfo} + puntata da \param{addr}, \param{id} viene ignorato.\\ + \const{Q\_SETINFO} & Imposta le informazioni delle quote del filesystem + indicato da \param{dev} come ottenuti dalla + struttura \struct{dqinfo} puntata + da \param{addr}, \param{id} viene ignorato; + l'operazione richiede i privilegi di amministratore.\\ + \const{Q\_GETFMT} & Richiede il valore identificativo (quello di + tab.~\ref{tab:quotactl_id_format}) per il formato + delle quote attualmente in uso sul filesystem + indicato da \param{dev}, che sarà memorizzato + sul buffer di 4 byte puntato da \param{addr}.\\ \const{Q\_SYNC} & Aggiorna la copia su disco dei dati delle quote del - filesystem; in questo caso \param{dev} può anche - essere \val{NULL} nel qual caso vengono aggiornate - i dati per tutti i filesystem con quote - attive, \param{id} e \param{addr} vengono comunque - ignorati.\\ - \const{Q\_GETSTATS} & .\\ + filesystem indicato da \param{dev}; in questo + caso \param{dev} può anche essere \val{NULL} nel + qual caso verranno aggiornati i dati per tutti i + filesystem con quote attive, \param{id} + e \param{addr} vengono comunque ignorati.\\ + \const{Q\_GETSTATS} & Ottiene statistiche ed altre informazioni generali + relative al sistema delle quote per il filesystem + indicato da \param{dev}, richiede che si + passi come argomento \param{addr} l'indirizzo di una + struttura \struct{dqstats}, mentre i valori + di \param{id} e \param{dev} vengono ignorati; + l'operazione è obsoleta e non supportata nei kernel + più recenti, che espongono la stessa informazione + nei file sotto \procfile{/proc/self/fs/quota/}.\\ % \const{} & .\\ \hline \end{tabular} - \caption{Possibili valori per l'argomento \param{subcommand} di + \caption{Possibili valori per l'argomento \param{subcmd} di \macro{QCMD}.} \label{tab:quotactl_commands} \end{table} -\footnotetext{per tutte le operazioni privilegiate con le quote è richiesta la - \textit{capability} \const{CAP\_SYS\_ADMIN}.} +Le diverse operazioni supportate da \func{quotactl}, da indicare con +l'argomento \param{subcmd} di \macro{QCMD}, sono riportate in +tab.~\ref{tab:quotactl_commands}. In generale le operazione di attivazione, +disattivazione e di modifica dei limiti delle quote sono riservate e +richiedono i privilegi di amministratore.\footnote{per essere precisi tutte le + operazioni indicate come privilegiate in tab.~\ref{tab:quotactl_commands} + richiedono la \textit{capability} \const{CAP\_SYS\_ADMIN}.} Inoltre gli +utenti possono soltanto richiedere i dati relativi alle proprie quote, solo +l'amministratore può ottenere i dati di tutti. +\begin{table}[htb] + \centering + \footnotesize + \begin{tabular}{|l|p{10cm}|} + \hline + \textbf{Identificatore} & \textbf{Descrizione} \\ + \hline + \hline + \const{QFMT\_VFS\_OLD}& il vecchio (ed obsoleto) formato delle quote.\\ + \const{QFMT\_VFS\_V0} & la versione 0 usata dal VFS di Linux (supporta + \ids{UID} e \ids{GID} a 32 bit e limiti fino a + $2^{42}$ byte e $2^{32}$ file.\\ + \const{QFMT\_VFS\_V1} & la versione 1 usata dal VFS di Linux (supporta + \ids{UID} e \ids{GID} a 32 bit e limiti fino a + $2^{64}$ byte e $2^{64}$ file.\\ + \hline + \end{tabular} + \caption{Valori di identificazione del formato delle quote.} + \label{tab:quotactl_id_format} +\end{table} +Alcuni dei comandi di tab.~\ref{tab:quotactl_commands} sono alquanto complessi +e richiedono un approfondimento maggiore, in particolare \const{Q\_GETQUOTA} e +\const{Q\_SETQUOTA} fanno riferimento ad una specifica struttura +\struct{dqblk}, la cui definizione è riportata in +fig.~\ref{fig:dqblk_struct},\footnote{la definizione mostrata è quella usata + fino dal kernel 2.4.22, non prenderemo in considerazione le versioni + obsolete.} nella quale vengono inseriti i dati relativi alle quote di un +singolo utente. \begin{figure}[!htb] \footnotesize \centering - \begin{minipage}[c]{15cm} + \begin{minipage}[c]{\textwidth} \includestruct{listati/dqblk.h} \end{minipage} \normalsize @@ -4322,9 +5615,196 @@ l'argomento \param{subcmd} di \macro{QCMD}, sono riportate in tab. \label{fig:dqblk_struct} \end{figure} +La struttura viene usata sia con \const{Q\_GETQUOTA} per ottenere i valori +correnti dei limiti e dell'occupazione delle risorse, che con +\const{Q\_SETQUOTA} per effettuare modifiche ai limiti; come si può notare ci +sono alcuni campi (in sostanza \val{dqb\_curspace}, \val{dqb\_curinodes}, +\val{dqb\_btime}, \val{dqb\_itime}) che hanno senso solo in lettura in quanto +riportano uno stato non modificabile da \func{quotactl}, come l'uso corrente +di spazio e \textit{inode} o il tempo che resta nel caso si sia superato un +\textit{soft limit}. + +\begin{table}[htb] + \centering + \footnotesize + \begin{tabular}{|l|p{10cm}|} + \hline + \textbf{Costante} & \textbf{Descrizione} \\ + \hline + \hline + \const{QIF\_BLIMITS}& Limiti sui blocchi di + spazio disco (\val{dqb\_bhardlimit} e + \val{dqb\_bsoftlimit}).\\ + \const{QIF\_SPACE} & Uso corrente + dello spazio disco (\val{dqb\_curspace}).\\ + \const{QIF\_ILIMITS}& Limiti sugli \textit{inode} + (\val{dqb\_ihardlimit} e \val{dqb\_isoftlimit}).\\ + \const{QIF\_INODES} & Uso corrente + degli \textit{inode} (\val{dqb\_curinodes}).\\ + \const{QIF\_BTIME} & Tempo di + sforamento del \textit{soft limit} sul numero di + blocchi (\val{dqb\_btime}).\\ + \const{QIF\_ITIME} & Tempo di + sforamento del \textit{soft limit} sul numero di + \textit{inode} (\val{dqb\_itime}).\\ + \const{QIF\_LIMITS} & L'insieme di \const{QIF\_BLIMITS} e + \const{QIF\_ILIMITS}.\\ + \const{QIF\_USAGE} & L'insieme di \const{QIF\_SPACE} e + \const{QIF\_INODES}.\\ + \const{QIF\_TIMES} & L'insieme di \const{QIF\_BTIME} e + \const{QIF\_ITIME}.\\ + \const{QIF\_ALL} & Tutti i precedenti.\\ + \hline + \end{tabular} + \caption{Costanti per il campo \val{dqb\_valid} di \struct{dqblk}.} + \label{tab:quotactl_qif_const} +\end{table} + + +Inoltre in caso di modifica di un limite si può voler operare solo su una +delle risorse (blocchi o \textit{inode});\footnote{non è possibile modificare + soltanto uno dei limiti (\textit{hard} o \textit{soft}) occorre sempre + rispecificarli entrambi.} per questo la struttura prevede un campo apposito, +\val{dqb\_valid}, il cui scopo è quello di indicare quali sono gli altri campi +che devono essere considerati validi. Questo campo è una maschera binaria che +deve essere espressa nei termini di OR aritmetico delle apposite costanti di +tab.~\ref{tab:quotactl_qif_const}, dove si è riportato il significato di +ciascuna di esse ed i campi a cui fanno riferimento. + +In lettura con \const{Q\_SETQUOTA} eventuali valori presenti in \struct{dqblk} +vengono comunque ignorati, al momento la funzione sovrascrive tutti i campi e +li marca come validi in \val{dqb\_valid}. Si possono invece usare +\const{QIF\_BLIMITS} o \const{QIF\_ILIMITS} per richiedere di impostare solo +la rispettiva tipologia di limiti con \const{Q\_SETQUOTA}. Si tenga presente +che il sistema delle quote richiede che l'occupazione di spazio disco sia +indicata in termini di blocchi e non di byte; dato che questo dipende da come +si è creato il filesystem potrà essere necessario effettuare qualche +controllo.\footnote{in genere viene usato un default di 1024 byte per blocco, + ma quando si hanno file di dimensioni medie maggiori può convenire usare + valori più alti per ottenere prestazioni migliori in conseguenza di un + minore frazionamento dei dati e di indici più corti.} + +Altre due operazioni che necessitano di un approfondimento sono +\const{Q\_GETINFO} e \const{Q\_SETINFO}, che sostanzialmente consentono di +ottenere i dati relativi alle impostazioni delle altre proprietà delle quote, +che si riducono poi alla durata del \textit{grace time} per i due tipi di +limiti. In questo caso queste si proprietà generali sono identiche per tutti +gli utenti, per cui viene usata una operazione distinta dalle +precedenti. Anche in questo caso le due operazioni richiedono l'uso di una +apposita struttura \struct{dqinfo}, la cui definizione è riportata in +fig.~\ref{fig:dqinfo_struct}. + +\begin{figure}[!htb] + \footnotesize \centering + \begin{minipage}[c]{\textwidth} + \includestruct{listati/dqinfo.h} + \end{minipage} + \normalsize + \caption{La struttura \structd{dqinfo} per i dati delle quote disco.} + \label{fig:dqinfo_struct} +\end{figure} + +Come per \struct{dqblk} anche in questo caso viene usato un campo della +struttura, \val{dqi\_valid} come maschera binaria per dichiarare quale degli +altri campi sono validi; le costanti usate per comporre questo valore sono +riportate in tab.~\ref{tab:quotactl_iif_const} dove si è riportato il +significato di ciascuna di esse ed i campi a cui fanno riferimento. + +\begin{table}[htb] + \centering + \footnotesize + \begin{tabular}{|l|l|} + \hline + \textbf{Costante} & \textbf{Descrizione} \\ + \hline + \hline + \const{IIF\_BGRACE}& Il \textit{grace period} per i blocchi + (\val{dqi\_bgrace}).\\ + \const{IIF\_IGRACE}& Il \textit{grace period} per gli \textit{inode} + (\val{dqi\_igrace}).\\ + \const{IIF\_FLAGS} & I flag delle quote (\val{dqi\_flags}) (inusato ?).\\ + \const{IIF\_ALL} & Tutti i precedenti.\\ + \hline + \end{tabular} + \caption{Costanti per il campo \val{dqi\_valid} di \struct{dqinfo}.} + \label{tab:quotactl_iif_const} +\end{table} + +Come in precedenza con \const{Q\_GETINFO} tutti i valori vengono letti +sovrascrivendo il contenuto di \struct{dqinfo} e marcati come validi in +\val{dqi\_valid}. In scrittura con \const{Q\_SETINFO} si può scegliere quali +impostare, si tenga presente che i tempi dei campi \val{dqi\_bgrace} e +\val{dqi\_igrace} devono essere specificati in secondi. + +Come esempi dell'uso di \func{quotactl} utilizzeremo estratti del codice di un +modulo Python usato per fornire una interfaccia diretta a \func{quotactl} +senza dover passare dalla scansione dei risultati di un comando. Il modulo si +trova fra i pacchetti Debian messi a disposizione da Truelite Srl, +all'indirizzo \url{http://labs.truelite.it/projects/packages}.\footnote{in + particolare il codice C del modulo è nel file \texttt{quotamodule.c} + visionabile a partire dall'indirizzo indicato nella sezione + \textit{Repository}.} + +\begin{figure}[!htbp] + \footnotesize \centering + \begin{minipage}[c]{\codesamplewidth} + \includecodesample{listati/get_quota.c} + \end{minipage} + \caption{Esempio di codice per ottenere i dati delle quote.} + \label{fig:get_quota} +\end{figure} + +Il primo esempio, riportato in fig.~\ref{fig:get_quota}, riporta il codice +della funzione che consente di leggere le quote. La funzione fa uso +dell'interfaccia dal C verso Python, che definisce i vari simboli \texttt{Py*} +(tipi di dato e funzioni). Non staremo ad approfondire i dettagli di questa +interfaccia, per la quale esistono numerose trattazioni dettagliate, ci +interessa solo esaminare l'uso di \func{quotactl}. + +In questo caso la funzione prende come argomenti (\texttt{\small 1}) l'intero +\texttt{who} che indica se si vuole operare sulle quote utente o gruppo, +l'identificatore \texttt{id} dell'utente o del gruppo scelto, ed il nome del +file di dispositivo del filesystem su cui si sono attivate le +quote.\footnote{questi vengono passati come argomenti dalle funzioni mappate + come interfaccia pubblica del modulo (una per gruppi ed una per gli utenti) + che si incaricano di decodificare i dati passati da una chiamata nel codice + Python.} Questi argomenti vengono passati direttamente alla chiamata a +\func{quotactl} (\texttt{\small 5}), a parte \texttt{who} che viene abbinato +con \macro{QCMD} al comando \const{Q\_GETQUOTA} per ottenere i dati. + +La funzione viene eseguita all'interno di un condizionale (\texttt{\small + 5--16}) che in caso di successo provvede a costruire (\texttt{\small 6--12}) +opportunamente una risposta restituendo tramite la opportuna funzione di +interfaccia un oggetto Python contenente i dati della struttura \struct{dqblk} +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}[!htbp] + \footnotesize \centering + \begin{minipage}[c]{\codesamplewidth} + \includecodesample{listati/set_block_quota.c} + \end{minipage} + \caption{Esempio di codice per impostare i limiti sullo spazio disco.} + \label{fig:set_block_quota} +\end{figure} + +Per impostare i limiti sullo spazio disco si potrà usare una seconda funzione, +riportata in fig.~\ref{fig:set_block_quota}, che prende gli stessi argomenti +della precedente, con lo stesso significato, a cui si aggiungono i valori per +il \textit{soft limit} e l'\textit{hard limit}. In questo caso occorrerà, +prima di chiamare \func{quotactl}, inizializzare opportunamente +(\texttt{\small 5--7}) i campi della struttura \struct{dqblk} che si vogliono +utilizzare (quelli relativi ai limiti sui blocchi) e specificare gli stessi +con \const{QIF\_BLIMITS} in \var{dq.dqb\_valid}. + +Fatto questo la chiamata a \func{quotactl}, stavolta con il comando +\const{Q\_SETQUOTA}, viene eseguita come in precedenza all'interno di un +condizionale (\texttt{\small 9--14}). In questo caso non essendovi da +restituire nessun dato in caso di successo si usa (\texttt{\small 10}) una +apposita funzione di uscita, mentre si restituisce come prima una eccezione +con il valore di \var{errno} in caso di errore (\texttt{\small 12--13}). -% TODO trattare quote disco -% vedi man quotactl \subsection{La gestione delle \textit{capabilities}} \label{sec:proc_capabilities} @@ -4364,21 +5844,21 @@ Il meccanismo completo delle \textit{capabilities}\footnote{l'implementazione si rifà ad una bozza di quello che doveva diventare lo standard POSIX.1e, poi abbandonato.} prevede inoltre la possibilità di associare le stesse ai singoli file eseguibili, in modo da poter stabilire quali capacità possono -essere utilizzate quando viene messo in esecuzione uno specifico programma -(una sorta di \acr{suid} anch'esso parcellizzato); ma il supporto per questa -funzionalità, chiamata \textit{file capabilities}, è stato introdotto soltanto -a partire dal kernel 2.6.24. Fino ad allora doveva essere il programma stesso -ad eseguire una riduzione esplicita delle sue capacità, cosa che ha reso l'uso -di questa funzionalità poco diffuso, vista la presenza di meccanismi -alternativi per ottenere limitazioni delle capacità dell'amministratore a -livello di sistema operativo, come \index{SELinux} SELinux. +essere utilizzate quando viene messo in esecuzione uno specifico programma; ma +il supporto per questa funzionalità, chiamata \textit{file capabilities}, è +stato introdotto soltanto a partire dal kernel 2.6.24. Fino ad allora doveva +essere il programma stesso ad eseguire una riduzione esplicita delle sue +capacità, cosa che ha reso l'uso di questa funzionalità poco diffuso, vista la +presenza di meccanismi alternativi per ottenere limitazioni delle capacità +dell'amministratore a livello di sistema operativo, come \index{SELinux} +SELinux. Con questo supporto e con le ulteriori modifiche introdotte con il kernel 2.6.25 il meccanismo delle \textit{capabilities} è stato totalmente -rivoluzionato, rendendolo più aderente alle intenzioni originali dello standard -POSIX, rimuovendo il significato che fino ad allora aveva avuto la capacità -\macro{CAP\_SETPCAP} e le modalità di funzionamento del cosiddetto -\itindex{capabilities~bounding~set} \textit{capabilities bounding +rivoluzionato, rendendolo più aderente alle intenzioni originali dello +standard POSIX, rimuovendo il significato che fino ad allora aveva avuto la +capacità \const{CAP\_SETPCAP} e cambiando le modalità di funzionamento del +cosiddetto \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 amministratore. Questo fa sì che il significato ed il comportamento del kernel @@ -4433,26 +5913,27 @@ 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 dell'uso del -\acr{suid} di root. Anche questi tre insiemi sono identificati con gli stessi -nomi, ma il loro significato è diverso: +con maggiori privilegi; in sostanza sono una sorta di estensione del +\acr{suid} bit limitato ai privilegi di amministratore. Anche questi tre +insiemi sono identificati con gli stessi nomi di quello dei processi, ma il +loro significato è diverso: \begin{basedescript}{\desclabelwidth{2.1cm}\desclabelstyle{\nextlinelabel}} \item[\textit{permitted}] (chiamato originariamente \textit{forced}) l'insieme delle capacità che con l'esecuzione del programma verranno aggiunte alle capacità \textsl{permesse} del processo. \item[\textit{inheritable}] (chiamato originariamente \textit{allowed}) l'insieme delle capacità che con l'esecuzione del programma possono essere - ereditate dal processo originario (che cioè 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} @@ -4467,31 +5948,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}). @@ -4500,14 +5982,14 @@ ruolo analogo al precedente nel passaggio attraverso una \func{exec}, come limite alle capacità che possono essere aggiunte al processo in quanto presenti nel \textit{permitted set} del programma messo in esecuzione, in sostanza il nuovo programma eseguito potrà ricevere una capacità presente nel -suo \textit{permitted set} solo se questa è anche nel \textit{bounding - set}. In questo modo si possono rimuovere definitivamente certe capacità da -un processo, anche qualora questo dovesse eseguire un programma -privilegiato. +suo \textit{permitted set} (quello del file) solo se questa è anche nel +\textit{bounding set} (del processo). In questo modo si possono rimuovere +definitivamente certe capacità da un processo, anche qualora questo dovesse +eseguire un programma privilegiato che prevede di riassegnarle. Si tenga presente però che in questo caso il \textit{bounding set} blocca esclusivamente le capacità indicate nel \textit{permitted set} del programma -che verrebbero attivate in caso di esecuzione, non quelle eventualmente già +che verrebbero attivate in caso di esecuzione, e non quelle eventualmente già presenti nell'\textit{inheritable set} del processo (ad esempio perché presenti prima di averle rimosse dal \textit{bounding set}). In questo caso eseguendo un programma che abbia anche lui dette capacità nel suo @@ -4515,43 +5997,193 @@ eseguendo un programma che abbia anche lui dette capacità nel suo In questa seconda versione inoltre il \textit{bounding set} costituisce anche un limite per le capacità che possono essere aggiunte all'\textit{inheritable - set} del processo con \func{capset}, sempre nel senso che queste devono -essere presenti nel \textit{bounding set} oltre che nel \textit{permitted set} -del processo. - -\itindend{capabilities~bounding~set} - + set} del processo stesso con \func{capset}, sempre nel senso che queste +devono essere presenti nel \textit{bounding set} oltre che nel +\textit{permitted set} del processo. Questo limite vale anche per processi con +i privilegi di amministratore,\footnote{si tratta sempre di avere la + \textit{capability} \const{CAP\_SETPCAP}.} per i quali invece non vale la +condizione che le \textit{capabilities} da aggiungere nell'\textit{inheritable + set} debbano essere presenti nel proprio \textit{permitted set}.\footnote{lo + scopo anche in questo caso è ottenere una rimozione definitiva della + possibilità di passare una capacità rimossa dal \textit{bounding set}.} + Come si può notare per fare ricorso alle \textit{capabilities} occorre comunque farsi carico di una notevole complessità di gestione, aggravata dalla presenza di una radicale modifica del loro funzionamento con l'introduzione delle \textit{file capabilities}. Considerato che il meccanismo originale era incompleto e decisamente problematico nel caso di programmi che non ne -sappiano tener conto,\footnote{si ebbe un grosso problema di sicurezza con +sapessero tener conto,\footnote{c'è stato un grosso problema di sicurezza con \texttt{sendmail}, riuscendo a rimuovere \const{CAP\_SETGID} - dall'\textit{inheritable set} si ottenne di far fallire una \func{setuid}, - in maniera inaspettata per il programma (che aspettandosi il successo della - funzione non ne controllava lo stato di uscita) con la conseguenza di - effettuare come amministratore operazioni che altrimenti sarebbero state - eseguite, senza poter apportare danni, da utente normale.} ci soffermeremo -solo sulla implementazione completa presente a partire dal kernel 2.6.25, -tralasciando ulteriori dettagli riguardo la versione precedente. - - - -Quando un programma viene messo in esecuzione\footnote{cioè quando viene - eseguita la \func{execve} con cui lo si lancia; in corrispondenza di una - \func{fork} le \textit{capabilities} non vengono modificate.} esso eredita -(nel senso che assume negli insiemi \textit{effective} e \textit{permitted}) -le \textit{capabilities} mantenute nell'insieme \textit{inherited}, a meno che -non sia eseguito un programma \acr{suid} di root o la \func{exec} sia stata -eseguita da un programma con \textsl{uid} reale zero; in tal caso il programma -ottiene tutte le \textit{capabilities} presenti nel \textit{capabilities - bounding set}. In questo modo si può far si che ad un processo eseguito in -un secondo tempo possano essere trasmesse solo un insieme limitato di -capacità, impedendogli di recuperare quelle assenti nell'insieme -\textit{inherited}. Si tenga presente invece che attraverso una \func{fork} -vengono mantenute le stesse capacità del processo padre. + dall'\textit{inheritable set} di un processo si ottenne di far fallire + \func{setuid} in maniera inaspettata per il programma (che aspettandosi + sempre il successo della funzione non ne controllava lo stato di uscita) con + la conseguenza di effettuare come amministratore operazioni che altrimenti + sarebbero state eseguite, senza poter apportare danni, da utente normale.} +ci soffermeremo solo sulla implementazione completa presente a partire dal +kernel 2.6.25, tralasciando ulteriori dettagli riguardo la versione +precedente. + +Riassumendo le regole finora illustrate tutte le \textit{capabilities} vengono +ereditate senza modifiche attraverso una \func{fork} mentre, indicati con +\texttt{orig\_*} i valori degli insiemi del processo chiamante, con +\texttt{file\_*} quelli del file eseguito e con \texttt{bound\_set} il +\textit{capabilities bounding set}, dopo l'invocazione di \func{exec} il +processo otterrà dei nuovi insiemi di capacità \texttt{new\_*} secondo la +formula (espressa 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}[!htbp] + \footnotesize \centering + \begin{minipage}[c]{12cm} + \includecodesnip{listati/cap-results.c} + \end{minipage} + \caption{Espressione della modifica delle \textit{capabilities} attraverso + una \func{exec}.} + \label{fig:cap_across_exec} +\end{figure} + +\itindend{capabilities~bounding~set} + +A queste regole se ne aggiungono delle altre che servono a riprodurre il +comportamento tradizionale di un sistema unix-like in tutta una serie di +circostanze. La prima di queste è relativa a quello che avviene quando si +esegue un file senza \textit{capabilities}; se infatti si considerasse questo +equivalente al non averne assegnata alcuna, non essendo presenti capacità né +nel \textit{permitted set} né nell'\textit{inheritable set} del file, +nell'esecuzione di un qualunque programma l'amministratore perderebbe tutti i +privilegi originali dal processo. + +Per questo motivo se un programma senza \textit{capabilities} assegnate viene +eseguito da un processo con \ids{UID} reale 0, esso verrà trattato come +se tanto il \textit{permitted set} che l'\textit{inheritable set} fossero con +tutte le \textit{capabilities} abilitate, con l'\textit{effective set} attivo, +col risultato di fornire comunque al processo tutte le capacità presenti nel +proprio \textit{bounding set}. Lo stesso avviene quando l'eseguibile ha attivo +il \acr{suid} bit ed appartiene all'amministratore, in entrambi i casi si +riesce così a riottenere il comportamento classico di un sistema unix-like. + +Una seconda circostanza è quella relativa a cosa succede alle +\textit{capabilities} di un processo nelle possibili transizioni da \ids{UID} +nullo a \ids{UID} non nullo o viceversa (corrispondenti rispettivamente a +cedere o riottenere i i privilegi di amministratore) che si possono effettuare +con le varie funzioni viste in sez.~\ref{sec:proc_setuid}. In questo caso la +casistica è di nuovo alquanto complessa, considerata anche la presenza dei +diversi gruppi di identificatori illustrati in tab.~\ref{tab:proc_uid_gid}, si +avrà allora che: +\begin{enumerate*} +\item se si passa da \ids{UID} effettivo nullo a non nullo + l'\textit{effective set} del processo viene totalmente azzerato, se + viceversa si passa da \ids{UID} effettivo non nullo a nullo il + \textit{permitted set} viene copiato nell'\textit{effective set}; +\item se si passa da \textit{file system} \ids{UID} nullo a non nullo verranno + cancellate dall'\textit{effective set} del processo tutte le capacità + attinenti i file, e cioè \const{CAP\_LINUX\_IMMUTABLE}, \const{CAP\_MKNOD}, + \const{CAP\_DAC\_OVERRIDE}, \const{CAP\_DAC\_READ\_SEARCH}, + \const{CAP\_MAC\_OVERRIDE}, \const{CAP\_CHOWN}, \const{CAP\_FSETID} e + \const{CAP\_FOWNER} (le prime due a partire dal kernel 2.2.30), nella + transizione inversa verranno invece inserite nell'\textit{effective set} + quelle capacità della precedente lista che sono presenti nel suo + \textit{permitted set}. +\item se come risultato di una transizione riguardante gli identificativi dei + gruppi \textit{real}, \textit{saved} ed \textit{effective} in cui si passa + da una situazione in cui uno di questi era nullo ad una in cui sono tutti + non nulli,\footnote{in sostanza questo è il caso di quando si chiama + \func{setuid} per rimuovere definitivamente i privilegi di amministratore + da un processo.} verranno azzerati completamente sia il \textit{permitted + set} che l'\textit{effective set}. +\end{enumerate*} +\label{sec:capability-uid-transition} + +La combinazione di tutte queste regole consente di riprodurre il comportamento +ordinario di un sistema di tipo Unix tradizionale, ma può risultare +problematica qualora si voglia passare ad una configurazione di sistema +totalmente basata sull'applicazione delle \textit{capabilities}; in tal caso +infatti basta ad esempio eseguire un programma con \acr{suid} bit di proprietà +dell'amministratore per far riottenere ad un processo tutte le capacità +presenti nel suo \textit{bounding set}, anche se si era avuta la cura di +cancellarle dal \textit{permitted set}. + +\itindbeg{securebits} + +Per questo motivo a partire dal kernel 2.6.26, se le \textit{file + capabilities} sono abilitate, ad ogni processo viene stata associata una +ulteriore maschera binaria, chiamata \textit{securebits flags}, su cui sono +mantenuti una serie di flag (vedi tab.~\ref{tab:securebits_values}) il cui +valore consente di modificare queste regole speciali che si applicano ai +processi con \ids{UID} nullo. La maschera viene sempre mantenuta +attraverso una \func{fork}, mentre attraverso una \func{exec} viene sempre +cancellato il flag \const{SECURE\_KEEP\_CAPS}. + +\begin{table}[htb] + \centering + \footnotesize + \begin{tabular}{|l|p{10cm}|} + \hline + \textbf{Flag} & \textbf{Descrizione} \\ + \hline + \hline + \const{SECURE\_KEEP\_CAPS}& Il processo non subisce la cancellazione delle + sue \textit{capabilities} quando tutti i suoi + \ids{UID} passano ad un valore non + nullo (regola di compatibilità per il cambio + di \ids{UID} n.~3 del precedente + elenco), sostituisce il precedente uso + dell'operazione \const{PR\_SET\_KEEPCAPS} di + \func{prctl}.\\ + \const{SECURE\_NO\_SETUID\_FIXUP}&Il processo non subisce le modifiche + delle sue \textit{capabilities} nel passaggio + da nullo a non nullo degli \ids{UID} + dei gruppi \textit{effective} e + \textit{file system} (regole di compatibilità + per il cambio di \ids{UID} nn.~1 e 2 del + precedente elenco).\\ + \const{SECURE\_NOROOT} & Il processo non assume nessuna capacità + aggiuntiva quando esegue un programma, anche + se ha \ids{UID} nullo o il programma ha + il \acr{suid} bit attivo ed appartiene + all'amministratore (regola di compatibilità + per l'esecuzione di programmi senza + \textit{capabilities}).\\ + \hline + \end{tabular} + \caption{Costanti identificative dei flag che compongono la maschera dei + \textit{securebits}.} + \label{tab:securebits_values} +\end{table} +A ciascuno dei flag di tab.~\ref{tab:securebits_values} è inoltre abbinato un +corrispondente flag di blocco, identificato da una costante omonima con +l'estensione \texttt{\_LOCKED}, la cui attivazione è irreversibile ed ha +l'effetto di rendere permanente l'impostazione corrente del corrispondente +flag ordinario; in sostanza con \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 @@ -4566,18 +6198,19 @@ Un elenco delle delle \textit{capabilities} disponibili su Linux, con una breve descrizione ed il nome delle costanti che le identificano, è riportato in tab.~\ref{tab:proc_capabilities};\footnote{l'elenco presentato questa tabella, ripreso dalla pagina di manuale (accessibile con \texttt{man - capabilities}) e dalle definizioni in \texttt{linux/capabilities.h}, è - aggiornato al kernel 2.6.26.} la tabella è divisa in due parti, la prima -riporta le \textit{capabilities} previste anche nella bozza dello standard -POSIX1.e, la seconda quelle specifiche di Linux. Come si può notare dalla -tabella alcune \textit{capabilities} attengono a singole funzionalità e sono -molto specializzate, mentre altre hanno un campo di applicazione molto vasto, -che è opportuno dettagliare maggiormente. + capabilities}) e dalle definizioni in + \texttt{include/linux/capabilities.h}, è aggiornato al kernel 2.6.26.} la +tabella è divisa in due parti, la prima riporta le \textit{capabilities} +previste anche nella bozza dello standard POSIX1.e, la seconda quelle +specifiche di Linux. Come si può notare dalla tabella alcune +\textit{capabilities} attengono a singole funzionalità e sono molto +specializzate, mentre altre hanno un campo di applicazione molto vasto, che è +opportuno dettagliare maggiormente. \begin{table}[!h!btp] \centering \footnotesize - \begin{tabular}{|l|p{11.9cm}|} + \begin{tabular}{|l|p{10.5cm}|} \hline \textbf{Capacità}&\textbf{Descrizione}\\ \hline @@ -4645,7 +6278,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).\\ @@ -4670,13 +6303,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 @@ -4684,16 +6315,16 @@ 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}).\\ \const{CAP\_SYS\_PTRACE}& La capacità di tracciare qualunque processo con \func{ptrace} (vedi - sez.~\ref{sec:xxx_ptrace}).\\ + sez.~\ref{sec:process_ptrace}).\\ \const{CAP\_SYS\_RAWIO} & La capacità di operare sulle porte di I/O con \func{ioperm} e \func{iopl} (vedi - sez.~\ref{sec:file_io_port}).\\ + sez.~\ref{sec:process_io_port}).\\ \const{CAP\_SYS\_RESOURCE}& La capacità di superare le varie limitazioni sulle risorse.\\ \const{CAP\_SYS\_TIME} & La capacità di modificare il tempo di sistema @@ -4706,8 +6337,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} @@ -4747,13 +6378,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'\ids{UID} effettivo del + processo (o meglio l'\ids{UID} di filesystem, vedi sez.~\ref{sec:proc_setuid}) coincida con quello del proprietario.} queste comprendono i cambiamenti dei permessi e dei tempi del file (vedi sez.~\ref{sec:file_perm_management} e sez.~\ref{sec:file_file_times}), le -impostazioni degli attributi 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 @@ -4770,18 +6401,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 \ids{UID} arbitrario +nella trasmissione delle credenziali dei socket (vedi +sez.~\ref{sec:socket_credential_xxx}), assegnare classi privilegiate +(\const{IOPRIO\_CLASS\_RT} e prima del kernel 2.6.25 anche +\const{IOPRIO\_CLASS\_IDLE}) per lo scheduling dell'I/O (vedi sez.~\ref{sec:io_priority}), superare il limite di sistema sul numero massimo -di file aperti,\footnote{quello indicato da \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} (vedi -sez.~\ref{sec:xxx_profiling}), 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 @@ -4799,13 +6432,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 @@ -4836,31 +6465,32 @@ 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 +\headfile{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 @@ -4871,15 +6501,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 @@ -4891,17 +6532,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 @@ -4913,14 +6555,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 @@ -4942,10 +6584,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 è: @@ -4956,7 +6598,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} @@ -4990,11 +6632,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 \headfile{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} @@ -5013,41 +6726,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 + \headfile{sys/capability.h} il tipo \type{cap\_value\_t} è definito come + \ctyp{int}, ma i valori validi sono soltanto quelli di + tab.~\ref{tab:proc_capabilities}.} Infine lo stato di una capacità è descritto ad una variabile di tipo \type{cap\_flag\_value\_t}, che a sua volta può assumere soltanto @@ -5073,19 +6763,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} @@ -5101,17 +6799,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, +\funcd{cap\_to\_name} e \funcd{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} @@ -5125,7 +6919,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. @@ -5134,7 +6928,7 @@ specifico occorre usare la funzione \funcd{capgetp}, il cui prototipo\footnote{su alcune pagine di manuale la funzione è descritta con un prototipo sbagliato, che prevede un valore di ritorno di tipo \type{cap\_t}, ma il valore di ritorno è intero, come si può verificare anche dalla - dichiarazione della stessa in \texttt{sys/capability.h}.} è: + dichiarazione della stessa in \headfile{sys/capability.h}.} è: \begin{functions} \headdecl{sys/capability.h} @@ -5149,8 +6943,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 @@ -5200,9 +6994,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 @@ -5231,35 +7025,41 @@ funzione. % TODO vedi http://lwn.net/Articles/198557/ e % http://www.madore.org/~david/linux/newcaps/ -% TODO documentare prctl ... -\subsection{La funzione \func{chroot}} + +\subsection{La gestione dei {chroot}} \label{sec:file_chroot} % TODO introdurre nuova sezione sulle funzionalità di sicurezza avanzate, con -% dentro chroot SELinux e AppArmor ??? +% dentro chroot SELinux e AppArmor, Tomoyo, Smack, cgroup o che altro ??? + +% inserire setns (introdotta con il 3.0, vedi http://lwn.net/Articles/407495/) +% e le funzionalità di isolamento dei container Benché non abbia niente a che fare con permessi, utenti e gruppi, la funzione \func{chroot} viene usata spesso per restringere le capacità di accesso di un programma ad una sezione limitata del filesystem, per cui ne parleremo in questa sezione. +% TODO riferimenti ai bind mount, link simbolici ecc. + Come accennato in sez.~\ref{sec:proc_fork} ogni processo oltre ad una -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. +\index{directory~di~lavoro} directory di lavoro, ha anche una directory +\textsl{radice}\footnote{entrambe sono contenute in due campi (rispettivamente + \var{pwd} e \var{root}) di \kstruct{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_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 +\index{directory~di~lavoro} 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 @@ -5277,7 +7077,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'\ids{UID} effettivo del processo non è zero. \end{errlist} ed inoltre \errval{EFAULT}, \errval{ENAMETOOLONG}, \errval{ENOENT}, \errval{ENOMEM}, \errval{ENOTDIR}, \errval{EACCES}, \errval{ELOOP}; @@ -5300,19 +7100,20 @@ cambia la directory di lavoro, che potrebbe restare fuori dalla \textit{chroot Questo è il motivo per cui la funzione è efficace solo se dopo averla eseguita si cedono i privilegi di root. Infatti se per un qualche motivo il processo -resta con la directory di lavoro fuori dalla \textit{chroot jail}, potrà -comunque accedere a tutto il resto del filesystem usando -\itindsub{pathname}{relativo}\textit{pathname} relativi, i quali, partendo -dalla directory di lavoro che è fuori della \textit{chroot jail}, potranno -(con l'uso di ``\texttt{..}'') risalire fino alla radice effettiva del -filesystem. +resta con \index{directory~di~lavoro} la directory di lavoro fuori dalla +\textit{chroot jail}, potrà comunque accedere a tutto il resto del filesystem +usando \itindsub{pathname}{relativo}\textit{pathname} relativi, i quali, +partendo dalla directory di lavoro che è fuori della \textit{chroot jail}, +potranno (con l'uso di ``\texttt{..}'') risalire fino alla radice effettiva +del filesystem. Ma se ad un processo restano i privilegi di amministratore esso potrà comunque -portare la sua directory di lavoro fuori dalla \textit{chroot jail} in cui si -trova. Basta infatti creare una nuova \textit{chroot jail} con l'uso di -\func{chroot} su una qualunque directory contenuta nell'attuale directory di -lavoro. Per questo motivo l'uso di questa funzione non ha molto senso quando -un processo necessita dei privilegi di root per le sue normali operazioni. +portare la sua \index{directory~di~lavoro} directory di lavoro fuori dalla +\textit{chroot jail} in cui si trova. Basta infatti creare una nuova +\textit{chroot jail} con l'uso di \func{chroot} su una qualunque directory +contenuta nell'attuale directory di lavoro. Per questo motivo l'uso di questa +funzione non ha molto senso quando un processo necessita dei privilegi di root +per le sue normali operazioni. Un caso tipico di uso di \func{chroot} è quello di un server FTP anonimo, in questo caso infatti si vuole che il server veda solo i file che deve @@ -5339,10 +7140,10 @@ programmi e librerie) di cui il server potrebbe avere bisogno. % LocalWords: ENOTEMPTY EBUSY mount point EINVAL soft symbolic tab symlink fig % LocalWords: dangling access chdir chmod chown creat exec lchown lstat mkdir % LocalWords: mkfifo mknod opendir pathconf readlink truncate path buff size -% LocalWords: grub bootloader grep MAXSYMLINKS cat VFS sys dirname fcntl +% LocalWords: grub bootloader grep MAXSYMLINKS cat VFS sys dirname fcntl tv Py % LocalWords: dev umask IFREG IFBLK IFCHR IFIFO SVr sgid BSD SVID NULL from to % LocalWords: stream dirent EMFILE ENFILE dirfd SOURCE fchdir readdir struct -% LocalWords: EBADF namlen HAVE thread entry result value argument fileno +% LocalWords: EBADF namlen HAVE thread entry result value argument fileno ext % LocalWords: name TYPE OFF RECLEN UNKNOWN REG SOCK CHR BLK type IFTODT DTTOIF % LocalWords: DTYPE off reclen seekdir telldir void rewinddir closedir select % LocalWords: namelist compar malloc qsort alphasort versionsort strcoll myls @@ -5352,42 +7153,56 @@ programmi e librerie) di cui il server potrebbe avere bisogno. % LocalWords: EINTR mktemp mkstemp stlib template filename XXXXXX OpenBSD buf % LocalWords: mkdtemp fstat filedes nell'header padding ISREG ISDIR ISCHR IFMT % LocalWords: ISBLK ISFIFO ISLNK ISSOCK IFSOCK IFLNK IFDIR ISUID UID ISGID GID -% LocalWords: ISVTX IRUSR IWUSR IXUSR IRGRP IWGRP IXGRP IROTH IWOTH IXOTH -% LocalWords: blocks blksize holes lseek TRUNC ftruncate ETXTBSY length +% LocalWords: ISVTX IRUSR IWUSR IXUSR IRGRP IWGRP IXGRP IROTH IWOTH IXOTH OLD +% LocalWords: blocks blksize holes lseek TRUNC ftruncate ETXTBSY length QCMD % LocalWords: hole atime read utime mtime write ctime modification leafnode cp % LocalWords: make fchmod fchown utimbuf times actime modtime Mac owner uid fs % LocalWords: gid Control List patch mandatory control execute group other all -% LocalWords: effective passwd IGID locking swap saved text IRWXU IRWXG -% LocalWords: IRWXO capability FSETID mask capabilities chroot jail -% LocalWords: FTP filter Attributes Solaris FreeBSD libacl hash at +% LocalWords: effective passwd IGID locking swap saved text IRWXU IRWXG subcmd +% LocalWords: IRWXO capability FSETID mask capabilities chroot jail QUOTAOFF +% LocalWords: FTP filter Attributes Solaris FreeBSD libacl hash at dqblk SYNC % LocalWords: XFS SELinux namespace attribute security trusted Draft Modules % LocalWords: attributes mime ADMIN FOWNER libattr lattr getxattr lgetxattr of % LocalWords: fgetxattr attr ssize ENOATTR ENOTSUP NUL setxattr lsetxattr list % LocalWords: fsetxattr flags XATTR REPLACE listxattr llistxattr flistxattr by -% LocalWords: removexattr lremovexattr fremovexattr attributename acl +% LocalWords: removexattr lremovexattr fremovexattr attributename acl GETINFO % LocalWords: OBJ setfacl len any prefix separator options NUMERIC IDS SMART % 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 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: fffffeff CapEff getcap scheduling lookup +% 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 -% LocalWords: aquota quotacheck limit grace period quotactl cmd caddr addr +% LocalWords: aquota quotacheck limit grace period quotactl cmd caddr addr dqb % LocalWords: QUOTAON ENODEV ENOPKG ENOTBLK GETQUOTA SETQUOTA SETUSE SETQLIM -% LocalWords: forced allowed sendmail SYSLOG WAKE ALARM CLOCK BOOTTIME -% LocalWords: REALTIME securebits +% LocalWords: forced allowed sendmail SYSLOG WAKE ALARM CLOCK BOOTTIME dqstats +% 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 is +% 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 Virtual everything +% LocalWords: dentry register resolution cache dcache operation llseek poll ln +% LocalWords: multiplexing fsync fasync seek block superblock gapil tex img du +% LocalWords: second linked journaled source filesystemtype unsigned device +% LocalWords: mountflags NODEV ENXIO dummy devfs magic MGC RDONLY NOSUID MOVE +% LocalWords: NOEXEC SYNCHRONOUS REMOUNT MANDLOCK NODIRATIME umount MNT statfs +% LocalWords: fstatfs fstab mntent ino bound orig new setpcap metadati sysfs %%% Local Variables: %%% mode: latex %%% TeX-master: "gapil" %%% End: +% LocalWords: bind DIRSYNC lsattr Hierarchy FHS SHARED UNBINDABLE shared REC +% LocalWords: subtree SILENT log unbindable BUSY EAGAIN EXPIRE DETACH NOFOLLOW +% LocalWords: lazy