From f7285509f37d4563b4976ff4507abb70f390c3b7 Mon Sep 17 00:00:00 2001 From: Simone Piccardi Date: Wed, 25 Jan 2012 00:01:33 +0000 Subject: [PATCH] Inizio revisione permessi dei file. --- filedir.tex | 343 +++++++++++++++++++++++++++++---------------------- fileunix.tex | 5 + 2 files changed, 200 insertions(+), 148 deletions(-) diff --git a/filedir.tex b/filedir.tex index fcc0c59..f2255b1 100644 --- a/filedir.tex +++ b/filedir.tex @@ -2853,10 +2853,11 @@ sez.~\ref{sec:proc_race_cond}). Molti problemi di sicurezza derivano proprio da una creazione non accorta di file temporanei che lascia aperta questa \itindex{race~condition} \textit{race condition}. Un attaccante allora potrà sfruttarla con quello che viene -chiamato ``\textit{symlink attack}'' dove nell'intervallo fra la generazione -di un nome e l'accesso allo stesso, viene creato un collegamento simbolico con -quel nome verso un file diverso, ottenendo, se il programma sotto attacco ne -ha la capacità, un accesso privilegiato. +chiamato \itindex{symlink~attack} ``\textit{symlink attack}'' dove +nell'intervallo fra la generazione di un nome e l'accesso allo stesso, viene +creato un collegamento simbolico con quel nome verso un file diverso, +ottenendo, se il programma sotto attacco ne ha la capacità, un accesso +privilegiato. La \acr{glibc} provvede varie funzioni per generare nomi di file temporanei, di cui si abbia certezza di unicità al momento della generazione; storicamente @@ -2874,10 +2875,10 @@ la prima di queste funzioni create a questo scopo era \end{funcproto} La funzione restituisce il puntatore ad una stringa contente un nome di file -valido e non esistente al momento dell'invocazione; se si è passato come +valido e non esistente al momento dell'invocazione. Se si è passato come argomento \param{string} un puntatore non nullo ad un buffer di caratteri questo deve essere di dimensione \const{L\_tmpnam} ed il nome generato vi -verrà copiato automaticamente; altrimenti il nome sarà generato in un buffer +verrà copiato automaticamente, altrimenti il nome sarà generato in un buffer statico interno che verrà sovrascritto ad una chiamata successiva. Successive invocazioni della funzione continueranno a restituire nomi unici fino ad un massimo di \const{TMP\_MAX} volte, limite oltre il quale il comportamento è @@ -2908,11 +2909,11 @@ 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 \envvar{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}). -\item Il valore della costante \const{P\_tmpdir}. + \itindex{sgid~bit} \acr{sgid}, vedi sez.~\ref{sec:file_special_perm}), +\item il valore dell'argomento \param{dir} (se diverso da \val{NULL}), +\item il valore della costante \const{P\_tmpdir}, \item la directory \file{/tmp}. \end{itemize*} @@ -2923,9 +2924,9 @@ file, un altro file o un collegamento simbolico con lo stesso nome. Per questo motivo quando si usa il nome ottenuto da una di queste funzioni occorre sempre assicurarsi che non si stia usando un collegamento simbolico e aprire il nuovo file in modalità di esclusione (cioè con l'opzione \const{O\_EXCL} per i file -descriptor o con il flag \code{x} per gli \textit{stream}) che fa fallire -l'apertura in caso il file sia già esistente. Essendo disponibili alternative -migliori l'uso di queste funzioni è deprecato. +descriptor o con il flag ``\texttt{x}'' per gli \textit{stream}) che fa +fallire l'apertura in caso il file sia già esistente. Essendo disponibili +alternative migliori l'uso di queste funzioni è deprecato. Per evitare di dovere effettuare a mano tutti questi controlli, lo standard POSIX definisce la funzione \funcd{tmpfile}, che permette di ottenere in @@ -2961,8 +2962,8 @@ Alcune versioni meno recenti di Unix non supportano queste funzioni; in questo caso si possono usare le vecchie funzioni \funcd{mktemp} e \func{mkstemp} che modificano una stringa di input che serve da modello e che deve essere conclusa da 6 caratteri ``\texttt{X}'' che verranno sostituiti da un codice -unico. La prima delle due è analoga a \func{tmpnam} e genera un nome casuale, -il suo prototipo è: +unico. La prima delle due è analoga a \func{tmpnam} e genera soltanto un nome +casuale, il suo prototipo è: \begin{funcproto}{ \fhead{stlib.h} @@ -3058,7 +3059,7 @@ In OpenBSD è stata introdotta un'altra funzione simile alle precedenti, La funzione genera una directory il cui nome è ottenuto sostituendo le \code{XXXXXX} finali di \param{template} con permessi \code{0700} (al solito -si veda cap.~\ref{cha:file_unix_interface} per i dettagli); dato che la +si veda cap.~\ref{cha:file_unix_interface} per i dettagli). Dato che la creazione della directory è sempre esclusiva i precedenti problemi di \itindex{race~condition} \textit{race condition} non si pongono. @@ -3279,7 +3280,7 @@ memorizzati. Per questo sempre in \headfile{sys/stat.h} sono definite le varie costanti numeriche riportate in tab.~\ref{tab:file_mode_flags}, che definiscono le maschere che consentono di selezionare non solo i dati relativi al tipo di file, ma anche le informazioni relative ai permessi su cui -torneremo in sez.~\ref{sec:file_access_control} ed identificare i rispettivi +torneremo in sez.~\ref{sec:file_access_control}, ed identificare i rispettivi valori. Le costanti che servono per la identificazione del tipo di file sono riportate @@ -3309,11 +3310,11 @@ Abbiamo visto in fig.~\ref{fig:file_stat_struct} che campo \var{st\_size} di una struttura \struct{stat} contiene la dimensione del file in byte. Questo però è vero solo se si tratta di un file regolare, mentre nel caso di un collegamento simbolico la dimensione è quella del \textit{pathname} che il -collegamento stesso contiene mentre per le fifo ed i file di dispositivo +collegamento stesso contiene, infine per le fifo ed i file di dispositivo questo campo è sempre nullo. Il campo \var{st\_blocks} invece definisce la lunghezza del file in blocchi di -512 byte. La differenze con \var{st\_size} è che in questo caso si fa +512 byte. La differenza con \var{st\_size} è che in questo caso si fa riferimento alla quantità di spazio disco allocata per il file, e non alla dimensione dello stesso che si otterrebbe leggendolo sequenzialmente. @@ -3480,7 +3481,7 @@ cambiamento, o se è passato più di un giorno dall'ultimo accesso. Così si pu rendere evidente che vi è stato un accesso dopo una modifica e che il file viene comunque osservato regolarmente, conservando tutte le informazioni veramente utili senza dover consumare risorse in scritture continue per -mantenere costantemente aggiornata una informazione che questo punto non ha +mantenere costantemente aggiornata una informazione che a questo punto non ha più nessuna rilevanza pratica.\footnote{qualora ce ne fosse la necessità è comunque possibile, tramite l'opzione di montaggio \texttt{strictatime}, richiedere in ogni caso il comportamento tradizionale.} @@ -3726,10 +3727,10 @@ prototipi sono: \end{errlist}} \end{funcproto} -Le due funzioni anno lo stesso comportamento di \texttt{utimes} e richiedono +Le due funzioni hanno lo stesso comportamento di \texttt{utimes} e richiedono gli stessi privilegi per poter operare, la differenza è che con \func{futimes} si può indicare il file su cui operare se questo è già aperto facendo -riferimento al suo file descriptor mentre con \func{lutimes} nel caso in +riferimento al suo file descriptor, mentre con \func{lutimes} nel caso in cui \param{filename} sia un collegamento simbolico saranno modificati i suoi tempi invece di quelli del file a cui esso punta. @@ -3832,12 +3833,12 @@ in \param{pathname}.\footnote{su Linux solo \func{utimensat} è una Torneremo su questa sintassi e sulla sua motivazione in sez.~\ref{sec:file_openat}, quando tratteremo tutte le altre funzioni (le -cosiddette funzioni \textit{at}) che la utilizzano; essa prevede comunque -anche la presenza dell'argomento \param{flags} con cui attivare flag di -controllo che modificano il comportamento della funzione, nel caso specifico -l'unico valore consentito è \const{AT\_SYMLINK\_NOFOLLOW} che indica alla -funzione di non dereferenziare i collegamenti simbolici, cosa che le permette -di riprodurre le funzionalità di \func{lutimes}. +cosiddette \itindex{at-functions} \textit{at-functions}) che la utilizzano; +essa prevede comunque anche la presenza dell'argomento \param{flags} con cui +attivare flag di controllo che modificano il comportamento della funzione, nel +caso specifico l'unico valore consentito è \const{AT\_SYMLINK\_NOFOLLOW} che +indica alla funzione di non dereferenziare i collegamenti simbolici, cosa che +le permette di riprodurre le funzionalità di \func{lutimes}. @@ -3865,7 +3866,7 @@ sez.~\ref{sec:proc_access_id}.\footnote{questo è vero solo per filesystem di tipo Unix, ad esempio non è vero per il filesystem VFAT di Windows, che non fornisce nessun supporto per l'accesso multiutente, e per il quale queste proprietà vengono assegnate in maniera fissa con opportune opzioni di - montaggio.} Anche questi sono mantenuti \index{itinode} sull'\textit{inode} + montaggio.} Anche questi sono mantenuti \itindex{inode} sull'\textit{inode} insieme alle altre proprietà e sono accessibili da programma tramite la funzione \func{stat} (trattata in sez.~\ref{sec:file_stat}), che restituisce l'utente proprietario nel campo \var{st\_uid} ed il gruppo proprietario nel @@ -3917,10 +3918,10 @@ I restanti tre bit (noti come \itindex{suid~bit} \textit{suid bit}, meccanismo del controllo di accesso su cui torneremo in seguito (in sez.~\ref{sec:file_special_perm}), lo schema di allocazione dei bit è riportato in fig.~\ref{fig:file_perm_bit}. Come tutte le altre proprietà di -una file anche i permessi sono memorizzati \itindex{inode} -nell'\textit{inode}, e come accennato in sez.~\ref{sec:file_types} essi sono -contenuti in una parte del campo \var{st\_mode} della struttura \struct{stat} -(si veda di nuovo fig.~\ref{fig:file_stat_struct}). +un file anche i permessi sono memorizzati \itindex{inode} nell'\textit{inode}, +e come accennato in sez.~\ref{sec:file_types} essi sono vengono restituiti in +una parte del campo \var{st\_mode} della struttura \struct{stat} (si veda di +nuovo fig.~\ref{fig:file_stat_struct}). In genere ci si riferisce ai tre livelli dei privilegi usando le lettere \texttt{u} (per \textit{user}), \texttt{g} (per \textit{group}) e \texttt{o} @@ -3931,8 +3932,8 @@ suo tempo nel VMS, si parla dei permessi base come di permessi per \textit{owner}, \textit{group} ed \textit{all}, le cui iniziali possono dar luogo a confusione. Le costanti che permettono di accedere al valore numerico di questi bit nel campo \var{st\_mode}, già viste in -tab.~\ref{tab:file_mode_flags}, sono riportate per chiarezza in -tab.~\ref{tab:file_bit_perm}. +tab.~\ref{tab:file_mode_flags}, sono riportate per chiarezza una seconda volta +in tab.~\ref{tab:file_bit_perm}. \begin{table}[htb] \centering @@ -3986,25 +3987,35 @@ Avere il permesso di lettura per un file consente di aprirlo con le opzioni (si veda quanto riportato in tab.~\ref{tab:file_open_flags}) di sola lettura o di lettura/scrittura e leggerne il contenuto. Avere il permesso di scrittura consente di aprire un file in sola scrittura o lettura/scrittura e modificarne -il contenuto, lo stesso permesso è necessario per poter troncare il file. +il contenuto, lo stesso permesso è necessario per poter troncare il file o per +aggiornare il suo tempo di ultima modifica al tempo corrente, ma non per +modificare arbitrariamente quest'ultimo, operazione per la quale, come per +buona parte delle modifiche effettuate sui metadati del file, occorre esserne +i proprietari. Non si può creare un file fintanto che non si disponga del permesso di -esecuzione e di quello di scrittura per la directory di destinazione; gli +esecuzione e di quello di scrittura per la directory di destinazione. Gli stessi permessi occorrono per cancellare un file da una directory (si ricordi che questo non implica necessariamente la rimozione del contenuto del file dal disco). Per la cancellazione non è necessario nessun tipo di permesso per il file stesso dato che, come illustrato in sez.~\ref{sec:link_symlink_rename} -esso non viene toccato, nella cancellazione viene solo modificato il contenuto -della directory, rimuovendo la voce che ad esso fa riferimento. - -Per poter eseguire un file (che sia un programma compilato od uno script di -shell, od un altro tipo di file eseguibile riconosciuto dal kernel), occorre, -oltre al permesso di lettura per accedere al contenuto, avere anche il -permesso di esecuzione. Inoltre solo i file regolari possono essere eseguiti. +esso non viene toccato, nella cancellazione infatti viene solo modificato il +contenuto della directory, rimuovendo la voce che ad esso fa riferimento. Lo +stesso vale per poter rinominare o spostare il file in altra directory, in +entrambi i casi occorrerà il permesso di scrittura sulle directory che si +vanno a modificare. + +Per poter eseguire un file, che sia un programma compilato od uno script di +shell, od un altro tipo di file eseguibile riconosciuto dal kernel, occorre +oltre al permesso di lettura per accedere al contenuto avere anche il permesso +di esecuzione. Inoltre solo i file regolari possono essere eseguiti. Per i +file di dispositivo i permessi validi sono solo quelli di lettura e scrittura, +che corrispondono al poter eseguire dette operazioni sulla periferica +sottostante. I permessi per un collegamento simbolico sono ignorati, contano quelli del file a cui fa riferimento; per questo in genere il comando \cmd{ls} riporta -per un collegamento simbolico tutti i permessi come concessi; utente e gruppo +per un collegamento simbolico tutti i permessi come concessi. Utente e gruppo a cui esso appartiene vengono pure ignorati quando il collegamento viene risolto, vengono controllati solo quando viene richiesta la rimozione del collegamento e quest'ultimo è in una directory con lo \itindex{sticky~bit} @@ -4032,9 +4043,8 @@ I passi attraverso i quali viene stabilito se il processo possiede il diritto di accesso sono i seguenti: \begin{enumerate*} \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. + all'amministratore) l'accesso è sempre garantito senza nessun controllo. Per + questo motivo l'amministratore ha piena libertà di accesso a tutti i file. \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: @@ -4046,7 +4056,7 @@ di accesso sono i seguenti: \item altrimenti l'accesso è negato. \end{itemize*} \item Se il \ids{GID} effettivo del processo o uno dei \ids{GID} supplementari - dei processi corrispondono al \ids{GID} del file allora: + del processo corrispondono al \ids{GID} del file allora: \begin{itemize*} \item se il bit dei permessi d'accesso del gruppo è impostato, l'accesso è consentito; @@ -4057,41 +4067,52 @@ di accesso sono i seguenti: \end{enumerate*} Si tenga presente che questi passi vengono eseguiti esattamente in -quest'ordine. Questo vuol dire che se un processo è il proprietario di un file, -l'accesso è consentito o negato solo sulla base dei permessi per l'utente; i -permessi per il gruppo non vengono neanche controllati. Lo stesso vale se il -processo appartiene ad un gruppo appropriato, in questo caso i permessi per -tutti gli altri non vengono controllati. +quest'ordine. Questo vuol dire che se un processo è il proprietario di un +file, l'accesso è consentito o negato solo sulla base dei permessi per +l'utente; i permessi per il gruppo non vengono neanche controllati. Lo stesso +vale se il processo appartiene ad un gruppo appropriato, in questo caso i +permessi per tutti gli altri non vengono controllati. + +Questo significa che se si è proprietari di un file ma non si ha il permesso +di scrittura, non vi si potrà scrivere anche se questo fosse scrivibile per +tutti gli altri. Permessi di questo tipo sono ovviamente poco ortodossi, e +comunque, come vedremo in sez.~\ref{sec:file_perm_management}, il proprietario +di un file può sempre modificarne i permessi, e riassegnarsi un eventuale +permesso di scrittura mancante. + +\itindbeg{file~attributes} -\itindbeg{file~attributes} A questi che sono i permessi ordinari si aggiungono, per i filesystem che supportano questa estensione, due permessi speciali mantenuti nei cosiddetti \textit{file attributes}, che si possono leggere ed impostare con i comandi -\cmd{lsattr} e \cmd{chattr}.\footnote{per l'utilizzo di questo comando e le - spiegazioni riguardo gli altri \textit{file attributes} si rimanda alla - sezione 1.4.4 di \cite{AGL}.} +\cmd{lsattr} e \cmd{chattr}.\footnote{per l'utilizzo di questi comandi e per + le spiegazioni riguardo tutti gli altri \textit{file attributes} si rimanda + alla sezione 1.4.4 di \cite{AGL}.} Il primo è il cosiddetto attributo di immutabilità (\textit{immutable}, identificato dalla lettera \texttt{i}) che impedisce ogni modifica al file, \textit{inode} compreso. Questo significa non solo che non se ne può cambiare -il contenuto, ma neanche nessuno dei metadati, ed in particolare non si può -cancellare, rinominare, modificare nei permessi o nei tempi, o creare -\textit{hard link} verso di esso. +il contenuto, ma neanche nessuna delle sue proprietà, ed in particolare non si +può modificare nei permessi o nei tempi o nel proprietario ed inoltre, visto +che non se può modificare il \textit{link count}, non si può neanche +cancellare, rinominare, o creare \textit{hard link} verso di esso. Il secondo è il cosiddetto attributo di \textit{append-only}, (identificato -dalla lettera \texttt{a}) che consente soltanto la scrittura del file in coda -al file. Il file cioè può essere soltanto esteso, ma i suoi metadati, a parte -i tempi che può però possono essere impostati al valore corrente, non possono -essere modificati, quindi di nuovo non si potrà cancellare, rinominare, o -modificare nei permessi. - -Entrambi questi attributi attivano queste proprietà a livello di filesytem, +dalla lettera \texttt{a}) che consente soltanto la scrittura in coda al +file. Il file cioè può essere soltanto esteso nel contenuto, ma i suoi +metadati, a parte i tempi che però possono essere impostati al valore +corrente, non possono essere modificati in alcun modo, quindi di nuovo non si +potrà cancellare, rinominare, o modificare nei permessi o nelle altre +proprietà. + +Entrambi questi attributi attivano queste restrizioni a livello di filesytem, per cui a differenza dei permessi ordinari esse varranno per qualunque utente compreso l'amministratore. L'amministratore è l'unico che può attivare o disattivare questi attributi,\footnote{più precisamente un processo con la \itindex{capabilities} capacità \const{CAP\_LINUX\_IMMUTABLE}.} e potendo rimuoverli è comunque capace di tornare in grado di eseguire qualunque -operazione. +operazione su un file immutabile o \textit{append-only}. + \itindbeg{file~attributes} @@ -4116,22 +4137,26 @@ identificatori del gruppo \textit{effective} del nuovo processo al valore dei corrispondenti del gruppo \textit{real} del processo corrente, che normalmente 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 \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. +Se però il file del programma, che ovviamente deve essere +eseguibile,\footnote{anzi più precisamente un binario eseguibile: 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 +\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. É +comunque possibile riconoscere questa situazione perché il cambiamento viene +effettuato solo sugli identificativi del gruppo \textit{effective}, mentre +quelli dei gruppi \textit{real} e \textit{saved} restano quelli dell'utente +che ha eseguito il programma. I bit \acr{suid} e \acr{sgid} vengono usati per permettere agli utenti normali -di usare programmi che richiedono privilegi speciali; l'esempio classico è il +di usare programmi che richiedono privilegi speciali. L'esempio classico è il comando \cmd{passwd} che ha la necessità di modificare il file delle password, quest'ultimo ovviamente può essere scritto solo dall'amministratore, ma non è necessario chiamare l'amministratore per cambiare la propria password. Infatti -il comando \cmd{passwd} appartiene a root ma ha il bit \acr{suid} impostato -per cui quando viene lanciato da un utente normale parte con i privilegi di -root. +il comando \cmd{passwd} appartiene in genere all'utente \textit{root} ma ha il +bit \acr{suid} impostato, per cui quando viene lanciato da un utente normale +ottiene comunque i privilegi di amministratore. Chiaramente avere un processo che ha privilegi superiori a quelli che avrebbe normalmente l'utente che lo ha lanciato comporta vari rischi, e questo tipo di @@ -4140,14 +4165,15 @@ usati per guadagnare privilegi non consentiti (l'argomento è affrontato in dettaglio in sez.~\ref{sec:proc_perms}). La presenza dei bit \acr{suid} e \acr{sgid} su un file può essere rilevata con -il comando \cmd{ls -l}, che visualizza una lettera \cmd{s} al posto della -\cmd{x} in corrispondenza dei permessi di utente o gruppo. La stessa lettera -\cmd{s} può essere usata nel comando \cmd{chmod} per impostare questi bit. -Infine questi bit possono essere controllati all'interno di \var{st\_mode} con -l'uso delle due costanti \const{S\_ISUID} e \const{S\_IGID}, i cui valori sono -riportati in tab.~\ref{tab:file_mode_flags}. - -Gli stessi bit vengono ad assumere in significato completamente diverso per le +il comando \cmd{ls -l}, che visualizza una lettera ``\cmd{s}'' al posto della +``\cmd{x}'' in corrispondenza dei permessi di utente o gruppo. La stessa +lettera ``\cmd{s}'' può essere usata nel comando \cmd{chmod} per impostare +questi bit. Infine questi bit possono essere controllati all'interno di +\var{st\_mode} con l'uso delle due costanti \const{S\_ISUID} e +\const{S\_IGID}, i cui valori sono riportati in +tab.~\ref{tab:file_mode_flags}. + +Gli stessi bit vengono ad assumere un significato completamente diverso per le directory, normalmente infatti Linux usa la convenzione di SVr4 per indicare con questi bit l'uso della semantica BSD nella creazione di nuovi file (si veda sez.~\ref{sec:file_ownership_management} per una spiegazione dettagliata @@ -4179,7 +4205,7 @@ fino al riavvio della macchina (da questo il nome di \textsl{sticky bit}); essendo la swap un file continuo o una partizione indicizzata direttamente si poteva risparmiare in tempo di caricamento rispetto alla ricerca attraverso la struttura del filesystem. Lo \textsl{sticky bit} è indicato usando la lettera -\texttt{t} al posto della \texttt{x} nei permessi per gli altri. +``\texttt{t}'' al posto della ``\texttt{x}'' nei permessi per gli altri. Ovviamente per evitare che gli utenti potessero intasare la swap solo l'amministratore era in grado di impostare questo bit, che venne chiamato @@ -4195,25 +4221,31 @@ impostato un file potrà essere rimosso dalla directory soltanto se l'utente ha il permesso di scrittura su di essa ed inoltre è vera una delle seguenti condizioni: \begin{itemize*} -\item l'utente è proprietario del file -\item l'utente è proprietario della directory -\item l'utente è l'amministratore +\item l'utente è proprietario del file, +\item l'utente è proprietario della directory, +\item l'utente è l'amministratore. \end{itemize*} -un classico esempio di directory che ha questo bit impostato è \file{/tmp}, i -permessi infatti di solito sono i seguenti: -\begin{verbatim} + +Un classico esempio di directory che ha questo bit impostato è \file{/tmp}, i +cui permessi infatti di solito sono i seguenti: +\begin{Command} $ ls -ld /tmp +\end{Command} +\begin{Terminal} drwxrwxrwt 6 root root 1024 Aug 10 01:03 /tmp -\end{verbatim}%$ +\end{Terminal} +%$ quindi con lo \textit{sticky bit} bit impostato. In questo modo qualunque -utente nel sistema può creare dei file in questa directory (che, come -suggerisce il nome, è normalmente utilizzata per la creazione di file -temporanei), ma solo l'utente che ha creato un certo file potrà cancellarlo o +utente nel sistema può creare dei file in questa directory, che come +suggerisce il nome è normalmente utilizzata per la creazione di file +temporanei, ma solo l'utente che ha creato un certo file potrà cancellarlo o rinominarlo. In questo modo si evita che un utente possa, più o meno consapevolmente, cancellare i file temporanei creati degli altri utenti. \itindend{sticky~bit} + + \subsection{Le funzioni per la gestione dei permessi dei file} \label{sec:file_perm_management} @@ -4225,7 +4257,8 @@ reale ed il \ids{GID} reale, vale a dire usando i valori di \ids{UID} e 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. -Per far questo si può usare la funzione \funcd{access}, il cui prototipo è: +Per far questo si può usare la funzione di sistema \funcd{access}, il cui +prototipo è: \begin{funcproto}{ \fhead{unistd.h} @@ -4235,16 +4268,18 @@ Per far questo si può usare la funzione \funcd{access}, il cui prototipo è: {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{EINVAL}] il valore di \param{mode} non è valido. + \begin{errlist} \item[\errcode{EACCES}] l'accesso al file non è consentito, o non si ha il permesso di attraversare una delle directory di \param{pathname}. + \item[\errcode{EINVAL}] il valore di \param{mode} non è valido. \item[\errcode{EROFS}] si è richiesto l'accesso in scrittura per un file su un filesystem montato in sola lettura. + \item[\errcode{ETXTBSY}] si è richiesto l'accesso in scrittura per un + eseguibile binario correntemente in esecuzione. \end{errlist} - ed inoltre \errval{EFAULT}, \errval{ENAMETOOLONG}, \errval{ENOENT}, - \errval{ENOTDIR}, \errval{ELOOP}, \errval{EIO} - nel loro significato generico.} + ed inoltre \errval{EFAULT}, \errval{EIO}, \errval{ELOOP}, + \errval{ENAMETOOLONG}, \errval{ENOENT}, \errval{ENOTDIR} nel loro + significato generico.} \end{funcproto} La funzione verifica i permessi di accesso, indicati da \param{mode}, per il @@ -4257,12 +4292,15 @@ o anche direttamente \func{stat}. Nel caso in cui \param{pathname} si riferisca ad un collegamento simbolico, questo viene seguito ed il controllo è fatto sul file a cui esso fa riferimento. -La funzione controlla solo i bit dei permessi di accesso, si ricordi che il -fatto che una directory abbia permesso di scrittura non significa che ci si -possa scrivere come in un file, e il fatto che un file abbia permesso di -esecuzione non comporta che contenga un programma eseguibile. La funzione -ritorna zero solo se tutte i permessi controllati sono disponibili, in caso -contrario (o di errore) ritorna -1. +La funzione controlla solo i bit dei permessi di accesso per \param{pathname}, +ma occorre poter risolvere quest'ultimo, e se non c'è il permesso di +esecuzione per una qualunque delle sue componenti la funzione fallirà +indipendentemente dai permessi del file. Si tenga presente poi che il fatto +che una directory abbia permesso di scrittura non significa che vi si possa +scrivere come fosse un file, e che se un file ha il permesso di esecuzione non +è detto che sia eseguibile. La funzione ha successo solo se tutti i permessi +controllati sono disponibili. + \begin{table}[htb] \centering \footnotesize @@ -4277,7 +4315,7 @@ contrario (o di errore) ritorna -1. \const{F\_OK} & Verifica l'esistenza del file. \\ \hline \end{tabular} - \caption{Valori possibile per l'argomento \param{mode} della funzione + \caption{Valori possibili per l'argomento \param{mode} della funzione \func{access}.} \label{tab:file_access_mode_val} \end{table} @@ -4285,14 +4323,20 @@ contrario (o di errore) ritorna -1. Un esempio tipico per l'uso di questa funzione è quello di un processo che sta eseguendo un programma coi privilegi di un altro utente (ad esempio attraverso l'uso del \itindex{suid~bit} \textit{suid bit}) che vuole controllare se -l'utente originale ha i permessi per accedere ad un certo file. - -Del tutto analoghe a \func{access} sono le due funzioni \funcd{euidaccess} e -\funcd{eaccess} che ripetono lo stesso controllo usando però gli +l'utente originale ha i permessi per accedere ad un certo file, ma eseguire +questo controllo prima di aprire il file espone al rischio di una +\itindex{race~condition} \textit{race condition} che apre ad un possibile +\itindex{symlink~attack} \textit{symlink attack} fra il controllo e l'apertura +del file. In questo caso è sempre opportuno usare invece la funzione +\func{faccessat} che tratteremo insieme alle altre \itindex{at-functions} +\textit{at-functions} in sez.~\ref{sec:file_openat}. + +Del tutto analoghe a \func{access} sono le due funzioni \funcm{euidaccess} e +\funcm{eaccess} che ripetono lo stesso controllo usando però gli identificatori del gruppo effettivo, verificando quindi le effettive capacità di accesso ad un file. Le funzioni hanno entrambe lo stesso -prototipo\footnote{in realtà \func{eaccess} è solo un sinonimo di - \func{euidaccess} fornita per compatibilità con l'uso di questo nome in +prototipo\footnote{in realtà \funcm{eaccess} è solo un sinonimo di + \funcm{euidaccess} fornita per compatibilità con l'uso di questo nome in altri sistemi.} che è del tutto identico a quello di \func{access}. Prendono anche gli stessi valori e restituiscono gli stessi risultati e gli stessi codici di errore. @@ -4317,13 +4361,13 @@ filename e su un file descriptor, i loro prototipi sono: caso \var{errno} assumerà uno dei valori: \begin{errlist} \item[\errcode{EPERM}] l'\ids{UID} effettivo non corrisponde a quello del - proprietario del file o non è zero. + proprietario del file o non si hanno i privilegi di amministratore. \item[\errcode{EROFS}] il file è su un filesystem in sola lettura. \end{errlist} - ed inoltre per entrambe \errval{EIO}, per \func{chmod} \errval{EFAULT}, - \errval{ENAMETOOLONG}, \errval{ENOENT}, \errval{ENOMEM}, \errval{ENOTDIR}, - \errval{EACCES}, \errval{ELOOP}, per \func{fchmod} \errval{EBADF} - nel loro significato generico.} + ed inoltre per entrambe \errval{EIO}, per \func{chmod} \errval{EACCES}, + \errval{EFAULT}, \errval{ELOOP}, \errval{ENAMETOOLONG}, \errval{ENOENT}, + \errval{ENOMEM}, \errval{ENOTDIR}, per \func{fchmod} \errval{EBADF} nel loro + significato generico.} \end{funcproto} @@ -4366,12 +4410,13 @@ file. \end{table} Le costanti con cui specificare i singoli bit di \param{mode} sono riportate -in tab.~\ref{tab:file_permission_const}. Il valore di \param{mode} può essere -ottenuto combinando fra loro con un OR binario le costanti simboliche relative -ai vari bit, o specificato direttamente, come per l'omonimo comando di shell, -con un valore numerico (la shell lo vuole in ottale, dato che i bit dei -permessi sono divisibili in gruppi di tre), che si può calcolare direttamente -usando lo schema si utilizzo dei bit illustrato in +in tab.~\ref{tab:file_permission_const}, e corrispondono agli stessi valori +usati per \var{st\_mode} in tab.~\ref{tab:file_mode_flags}. Il valore +di \param{mode} può essere ottenuto combinando fra loro con un OR binario le +costanti simboliche relative ai vari bit, o specificato direttamente, come per +l'omonimo comando di shell, con un valore numerico (la shell lo vuole in +ottale, dato che i bit dei permessi sono divisibili in gruppi di tre), che si +può calcolare direttamente usando lo schema di utilizzo dei bit illustrato in fig.~\ref{fig:file_perm_bit}. Ad esempio i permessi standard assegnati ai nuovi file (lettura e scrittura @@ -4390,20 +4435,20 @@ Ma oltre a questa regola generale, di immediata comprensione, esistono delle limitazioni ulteriori. Per questo motivo, anche se si è proprietari del file, non tutti i valori possibili di \param{mode} sono permessi o hanno effetto; in particolare accade che: -\begin{enumerate} +\begin{enumerate*} \item siccome solo l'amministratore può impostare lo \itindex{sticky~bit} \textit{sticky bit}, se l'\ids{UID} effettivo del processo non è zero esso - viene automaticamente cancellato (senza notifica di errore) qualora sia + 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 creazione dei nuovi file, si può avere il caso in cui il file creato da un processo è assegnato ad un gruppo per il quale il processo non ha privilegi. Per evitare che si possa assegnare il bit \itindex{sgid~bit} \acr{sgid} ad 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'\ids{UID} effettivo del processo è zero). -\end{enumerate} + 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'\ids{UID} effettivo del processo è zero. +\end{enumerate*} Per alcuni filesystem\footnote{i filesystem più comuni (\textsl{ext2}, \textsl{ext3}, \textsl{ext4}, \textsl{ReiserFS}) supportano questa @@ -4443,8 +4488,8 @@ nuovo file viene creato.\footnote{l'operazione viene fatta sempre: anche creazione che lo consentono, i permessi contenuti nella \textit{umask} verranno tolti.} -La funzione che permette di impostare il valore di questa maschera di -controllo è \funcd{umask}, ed il suo prototipo è: +La funzione di sistema che permette di impostare il valore di questa maschera +di controllo è \funcd{umask}, ed il suo prototipo è: \begin{funcproto}{ \fhead{stat.h} @@ -4456,14 +4501,15 @@ controllo è \funcd{umask}, ed il suo prototipo è: previste condizioni di errore.} \end{funcproto} -La funzione imposta maschera dei permessi dei bit al valore specificato -da \param{mask} (di cui vengono presi solo i 9 bit meno significativi). In +La funzione imposta la maschera dei permessi dei bit al valore specificato +da \param{mask}, di cui vengono presi solo i 9 bit meno significativi. In genere si usa questa maschera per impostare un valore predefinito che escluda -preventivamente alcuni permessi (usualmente quello di scrittura per il gruppo -e gli altri, corrispondente ad un valore per \param{mask} pari a $022$). In -questo modo è possibile cancellare automaticamente i permessi non voluti. Di -norma questo valore viene impostato una volta per tutte al login a $022$, e -gli utenti non hanno motivi per modificarlo. +preventivamente alcuni permessi, il caso più comune è eliminare il permesso di +scrittura per il gruppo e gli altri, corrispondente ad un valore +per \param{mask} pari a $022$. In questo modo è possibile cancellare +automaticamente i permessi non voluti. Di norma questo valore viene impostato +una volta per tutte al login (a $022$ se non indicato altrimenti), e gli +utenti non hanno motivi per modificarlo. \itindend{umask} @@ -4482,9 +4528,10 @@ 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 \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. +\item che il \ids{GID} del file corrisponda al \ids{GID} effettivo del + processo. +\item che il \ids{GID} del file corrisponda 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 @@ -7665,7 +7712,7 @@ programmi e librerie) di cui il server potrebbe avere bisogno. % LocalWords: subtree SILENT log unbindable BUSY EAGAIN EXPIRE DETACH NOFOLLOW % LocalWords: lazy encfs sshfs setfsent getfsent getfsfile getfsspec endfsent % LocalWords: setmntent getmntent addmntent endmntent hasmntopt such offsetof -% LocalWords: member scan attack EOVERFLOW BITS blkcnt rdev +% LocalWords: member scan attack EOVERFLOW BITS blkcnt rdev FDCWD functions %%% Local Variables: %%% mode: latex diff --git a/fileunix.tex b/fileunix.tex index c3e7ba5..a69de77 100644 --- a/fileunix.tex +++ b/fileunix.tex @@ -1126,6 +1126,8 @@ file descriptor libero di valore uguale o maggiore di \param{newfd} (e se \subsection{Le funzioni \func{openat}, \func{mkdirat} e affini} \label{sec:file_openat} +\itindbeg{at-functions} + Un problema che si pone con l'uso della funzione \func{open}, così come per molte altre funzioni che accettano come argomenti dei \itindsub{pathname}{relativo} \textit{pathname} relativi, è che, quando un @@ -1381,6 +1383,9 @@ in cui questo è una directory, se però si imposta \param{flags} al valore di caso \param{pathname} deve essere una directory, che sarà rimossa qualora risulti vuota. +\itindend{at-functions} + + % TODO manca prototipo e motivazione di fexecve, da trattare qui in quanto % inserita nello stesso standard e da usare con openat, vedi % http://pubs.opengroup.org/onlinepubs/9699939699/toc.pdf -- 2.30.2