invalidare, cosa che per i processori moderni, che hanno linee di cache
interne molto profonde, avrebbe un forte impatto sulle prestazioni.
-Allora anche se quanto detto in precedenza vale come comportamento effettivo
-dei programmi soltanto per i kernel fino alla serie 2.4, per mantenere la
-portabilità con altri kernel unix-like, e con i diversi comportamenti adottati
-dalle Linux nella sua evoluzione, è comunque opportuno non fare affidamento su
-nessun tipo di comportamento predefinito e non fare assunzioni sull'ordine di
-esecuzione di padre e figlio.
+Allora anche se quanto detto in precedenza si verifica nel comportamento
+effettivo dei programmi soltanto per i kernel fino alla serie 2.4, per
+mantenere la portabilità con altri kernel unix-like e con i diversi
+comportamenti adottati dalle Linux nella sua evoluzione, è comunque opportuno
+non fare nessuna assunzione sull'ordine di esecuzione di padre e figlio dopo
+la chiamata a \func{fork}.
Si noti infine come dopo la \func{fork}, essendo i segmenti di memoria
utilizzati dai singoli processi completamente indipendenti, le modifiche delle
Quando un processo scrive su un file la posizione corrente viene aggiornata
sulla \textit{file table}, e tutti gli altri processi, che vedono la stessa
\textit{file table}, vedranno il nuovo valore. In questo modo si evita, in
-casi come quello appena mostrato in cui diversi processi scrivono sullo stesso
-file, che l'output di un processo successivo vada a sovrapporsi a quello dei
-precedenti: l'output potrà risultare mescolato, ma non ci saranno parti
-perdute per via di una sovrascrittura.
+casi come quello appena mostrato in cui diversi figli scrivono sullo stesso
+file usato dal padre, che una scrittura eseguita in un secondo tempo da un
+processo vada a sovrapporsi a quelle precedenti: l'output potrà risultare
+mescolato, ma non ci saranno parti perdute per via di una sovrascrittura.
Questo tipo di comportamento è essenziale in tutti quei casi in cui il padre
crea un figlio e attende la sua conclusione per proseguire, ed entrambi
quando lancia un programma. In questo modo, anche se lo standard output viene
rediretto, il padre potrà sempre continuare a scrivere in coda a quanto
scritto dal figlio in maniera automatica; se così non fosse ottenere questo
-comportamento sarebbe estremamente complesso necessitando di una qualche forma
-di comunicazione fra i due processi per far riprendere al padre la scrittura
-al punto giusto.
+comportamento sarebbe estremamente complesso, necessitando di una qualche
+forma di comunicazione fra i due processi per far riprendere al padre la
+scrittura al punto giusto.
In generale comunque non è buona norma far scrivere più processi sullo stesso
file senza una qualche forma di sincronizzazione in quanto, come visto anche
\textsl{orfano}.
Questa complicazione viene superata facendo in modo che il processo orfano
-venga \textsl{adottato} da \cmd{init}, o meglio dal processo con \ids{PID} 1,
-cioè quello lanciato direttamente dal kernel all'avvio, che sta alla base
-dell'albero dei processi visto in sez.~\ref{sec:proc_hierarchy} e che anche
-per questo motivo ha un ruolo essenziale nel sistema e non può mai
+venga \textsl{adottato} da \cmd{init}, o meglio dal processo con \ids{PID}
+1,\footnote{anche se, come vedremo in sez.~\ref{sec:process_prctl}, a partire
+ dal kernel 3.4 è diventato possibile delegare questo compito anche ad un
+ altro processo.} cioè quello lanciato direttamente dal kernel all'avvio, che
+sta alla base dell'albero dei processi visto in sez.~\ref{sec:proc_hierarchy}
+e che anche per questo motivo ha un ruolo essenziale nel sistema e non può mai
terminare.\footnote{almeno non senza un blocco completo del sistema, in caso
di terminazione o di non esecuzione di \cmd{init} infatti il kernel si
blocca con un cosiddetto \textit{kernel panic}, dato che questo è un errore
in precedenza, essi riportano 1 come \ids{PPID}.
Altrettanto rilevante è il caso in cui il figlio termina prima del padre,
-perché non è detto che il padre possa ricevere immediatamente lo stato di
-terminazione, quindi il kernel deve comunque conservare una certa quantità di
-informazioni riguardo ai processi che sta terminando.
+perché non è detto che il padre sia in esecuzione e possa ricevere
+immediatamente lo stato di terminazione, quindi il kernel deve comunque
+conservare una certa quantità di informazioni riguardo ai processi che sta
+terminando.
Questo viene fatto mantenendo attiva la voce nella tabella dei processi, e
memorizzando alcuni dati essenziali, come il \ids{PID}, i tempi di CPU usati
La prima differenza fra le due funzioni è che con \func{waitpid} si può
specificare in maniera flessibile quale processo attendere, sulla base del
-valore fornito dall'argomento \param{pid}, questo può assumere diversi valori,
+valore fornito dall'argomento \param{pid}. Questo può assumere diversi valori,
secondo lo specchietto riportato in tab.~\ref{tab:proc_waidpid_pid}, dove si
-sono riportate anche le costanti definite per indicare alcuni di essi.
+sono riportate anche le costanti definite per indicare alcuni di essi.
\begin{table}[!htb]
\centering
Linux, che consentono un controllo più dettagliato per i processi creati con
la \textit{system call} generica \func{clone} (vedi
sez.~\ref{sec:process_clone}) e che vengono usati principalmente per la
-gestione della terminazione dei \textit{thread} (vedi
-sez.~\ref{sec:thread_xxx}).
+gestione della terminazione dei \textit{thread}\unavref{ (vedi
+sez.~\ref{sec:thread_xxx})}.
\begin{table}[!htb]
\centering
\const{WUNTRACED} & Ritorna anche quando un processo figlio è stato
fermato.\\
\const{WCONTINUED}& Ritorna anche quando un processo figlio che era stato
- fermato ha ripreso l'esecuzione (disponibile solo a
- partire dal kernel 2.6.10).\\
+ fermato ha ripreso l'esecuzione (dal kernel 2.6.10).\\
\hline
\constd{\_\_WCLONE}& Attende solo per i figli creati con \func{clone}
(vedi sez.~\ref{sec:process_clone}), vale a dire
processi figli ordinari ignorando quelli creati da
\func{clone}.\\
\constd{\_\_WALL} & Attende per qualunque figlio, sia ordinario che creato
- con \func{clone}, se specificata insieme a
+ con \func{clone}, se specificata con
\const{\_\_WCLONE} quest'ultima viene ignorata. \\
\constd{\_\_WNOTHREAD}& Non attende per i figli di altri \textit{thread}
dello stesso \textit{thread group}, questo era il
quando un processo figlio entra nello stato \textit{stopped}\footnote{in
realtà viene notificato soltanto il caso in cui il processo è stato fermato
da un segnale di stop (vedi sez.~\ref{sec:sess_ctrl_term}), e non quello in
- cui lo stato \textit{stopped} è dovuto all'uso di \func{ptrace} (vedi
- sez.~\ref{sec:process_ptrace}).} (vedi tab.~\ref{tab:proc_proc_states}),
-mentre con \const{WCONTINUED} la funzione ritorna quando un processo in stato
-\textit{stopped} riprende l'esecuzione per la ricezione del segnale
-\signal{SIGCONT} (l'uso di questi segnali per il controllo di sessione è
-trattato in sez.~\ref{sec:sess_ctrl_term}).
+ cui lo stato \textit{stopped} è dovuto all'uso di \func{ptrace}\unavref{
+ (vedi sez.~\ref{sec:process_ptrace})}.} (vedi
+tab.~\ref{tab:proc_proc_states}), mentre con \const{WCONTINUED} la funzione
+ritorna quando un processo in stato \textit{stopped} riprende l'esecuzione per
+la ricezione del segnale \signal{SIGCONT} (l'uso di questi segnali per il
+controllo di sessione è trattato in sez.~\ref{sec:sess_ctrl_term}).
\constend{WUNTRACED}
\constend{WCONTINUED}
di un programma e può avvenire in un qualunque momento. Per questo motivo,
come accennato nella sezione precedente, una delle azioni prese dal kernel
alla conclusione di un processo è quella di mandare un segnale di
-\signal{SIGCHLD} al padre. L'azione predefinita (si veda
-sez.~\ref{sec:sig_base}) per questo segnale è di essere ignorato, ma la sua
-generazione costituisce il meccanismo di comunicazione asincrona con cui il
-kernel avverte il processo padre che uno dei suoi figli è terminato.
+\signal{SIGCHLD} al padre. L'azione predefinita per questo segnale (si veda
+sez.~\ref{sec:sig_base}) è di essere ignorato, ma la sua generazione
+costituisce il meccanismo di comunicazione asincrona con cui il kernel avverte
+il processo padre che uno dei suoi figli è terminato.
Il comportamento delle funzioni è però cambiato nel passaggio dal kernel 2.4
al kernel 2.6, quest'ultimo infatti si è adeguato alle prescrizioni dello
Come accennato sia \func{wait} che \func{waitpid} restituiscono lo stato di
terminazione del processo tramite il puntatore \param{status}, e se non
-interessa memorizzare lo stato si può passare un puntatore nullo. Il valore
-restituito da entrambe le funzioni dipende dall'implementazione, ma
-tradizionalmente gli 8 bit meno significativi sono riservati per memorizzare
-lo stato di uscita del processo, e gli altri per indicare il segnale che ha
-causato la terminazione (in caso di conclusione anomala), uno per indicare se
-è stato generato un \textit{core dump} (vedi sez.~\ref{sec:sig_standard}),
-ecc.\footnote{le definizioni esatte si possono trovare in
- \file{<bits/waitstatus.h>} ma questo file non deve mai essere usato
- direttamente, esso viene incluso attraverso \file{<sys/wait.h>}.}
+interessa memorizzarlo si può passare un puntatore nullo. Il valore restituito
+da entrambe le funzioni dipende dall'implementazione, ma tradizionalmente gli
+8 bit meno significativi sono riservati per memorizzare lo stato di uscita del
+processo, e gli altri per indicare il segnale che ha causato la terminazione
+(in caso di conclusione anomala), uno per indicare se è stato generato un
+\textit{core dump} (vedi sez.~\ref{sec:sig_standard}), ecc.\footnote{le
+ definizioni esatte si possono trovare in \file{<bits/waitstatus.h>} ma
+ questo file non deve mai essere usato direttamente, esso viene incluso
+ attraverso \file{<sys/wait.h>}.}
\begin{table}[!htb]
\centering
programma letto da disco, eseguendo il \textit{link-loader} con gli effetti
illustrati in sez.~\ref{sec:proc_main}.
+\begin{figure}[!htb]
+ \centering \includegraphics[width=8cm]{img/exec_rel}
+ \caption{La interrelazione fra le sei funzioni della famiglia \func{exec}.}
+ \label{fig:proc_exec_relat}
+\end{figure}
+
Ci sono sei diverse versioni di \func{exec} (per questo la si è chiamata
famiglia di funzioni) che possono essere usate per questo compito, in realtà
(come mostrato in fig.~\ref{fig:proc_exec_relat}), tutte queste funzioni sono
passaggio degli argomenti, la funzione di sistema \funcd{execve}, il cui
prototipo è:
-\begin{funcproto}{
+\begin{funcproto}{
\fhead{unistd.h}
\fdecl{int execve(const char *filename, char *const argv[], char *const envp[])}
\fdesc{Esegue un programma.}
eseguibili, o il file è su un filesystem montato con l'opzione
\cmd{noexec}, o manca il permesso di attraversamento di una delle
directory del \textit{pathname}.
+ \item[\errcode{EAGAIN}] dopo un cambio di \ids{UID} si è ancora sopra il
+ numero massimo di processi consentiti per l'utente (dal kernel 3.1, per i
+ dettagli vedi sez.~\ref{sec:proc_setuid}).
\item[\errcode{EINVAL}] l'eseguibile ELF ha più di un segmento
\const{PT\_INTERP}, cioè chiede di essere eseguito da più di un
interprete.
\item[\errcode{ELIBBAD}] un interprete ELF non è in un formato
riconoscibile.
- \item[\errcode{ENOEXEC}] il file è in un formato non eseguibile o non
- riconosciuto come tale, o compilato per un'altra architettura.
\item[\errcode{ENOENT}] il file o una delle librerie dinamiche o l'interprete
necessari per eseguirlo non esistono.
+ \item[\errcode{ENOEXEC}] il file è in un formato non eseguibile o non
+ riconosciuto come tale, o compilato per un'altra architettura.
\item[\errcode{EPERM}] il file ha i bit \acr{suid} o \acr{sgid} e l'utente
non è root, ed il processo viene tracciato, oppure il filesystem è montato
con l'opzione \cmd{nosuid}.
In caso di successo la funzione non ritorna, in quanto al posto del programma
chiamante viene eseguito il nuovo programma indicato da \param{filename}. Se
-il processo corrente è tracciato con \func{ptrace} (vedi
-sez.~\ref{sec:process_ptrace}) in caso di successo viene emesso il segnale
+il processo corrente è tracciato con \func{ptrace}\unavref{ (vedi
+sez.~\ref{sec:process_ptrace})} in caso di successo viene emesso il segnale
\signal{SIGTRAP}.
Le altre funzioni della famiglia (\funcd{execl}, \funcd{execv},
convenzione che il primo argomento (\var{arg0} o \var{argv[0]}) viene usato
per indicare il nome del file che contiene il programma che verrà eseguito.
-\begin{figure}[!htb]
- \centering \includegraphics[width=9cm]{img/exec_rel}
- \caption{La interrelazione fra le sei funzioni della famiglia \func{exec}.}
- \label{fig:proc_exec_relat}
-\end{figure}
-
La seconda differenza fra le funzioni riguarda le modalità con cui si
specifica il programma che si vuole eseguire. Con lo mnemonico ``\texttt{p}''
si indicano le due funzioni che replicano il comportamento della shell nello
\item i limiti sulle risorse (vedi sez.~\ref{sec:sys_resource_limit});
\item i valori delle variabili \var{tms\_utime}, \var{tms\_stime};
\var{tms\_cutime}, \var{tms\_ustime} (vedi sez.~\ref{sec:sys_cpu_times});
-% TODO ===========Importante=============
-% TODO questo sotto è incerto, verificare
-% TODO ===========Importante=============
-\item la maschera dei segnali (si veda sez.~\ref{sec:sig_sigmask}).
+\item la maschera dei segnali (si veda sez.~\ref{sec:sig_sigmask});
+\item l'insieme dei segnali pendenti (vedi sez.~\ref{sec:sig_gen_beha}).
\end{itemize*}
Una serie di proprietà del processo originale, che non avrebbe senso mantenere
l'esecuzione di una \func{exec}. Lo standard POSIX.1-2001 prevede che le
seguenti proprietà non vengano preservate:
\begin{itemize*}
-\item l'insieme dei segnali pendenti (vedi sez.~\ref{sec:sig_gen_beha}), che
- viene cancellato;
\item gli eventuali stack alternativi per i segnali (vedi
sez.~\ref{sec:sig_specific_features});
\item i \textit{directory stream} (vedi sez.~\ref{sec:file_dir_read}), che
pendenti vengono cancellate;
\item le \textit{capabilities} vengono modificate come
illustrato in sez.~\ref{sec:proc_capabilities};
-\item tutti i \textit{thread} tranne il chiamante (vedi
- sez.~\ref{sec:thread_xxx}) sono cancellati e tutti gli oggetti ad essi
- relativi (vedi sez.~\ref{sec:thread_xxx}) rimossi;
+\item tutti i \textit{thread} tranne il chiamante\unavref{ (vedi
+ sez.~\ref{sec:thread_xxx})} vengono cancellati e tutti gli oggetti ad essi
+ relativi\unavref{ (vedi sez.~\ref{sec:thread_xxx})} sono rimossi;
\item viene impostato il flag \const{PR\_SET\_DUMPABLE} di \func{prctl} (vedi
sez.~\ref{sec:process_prctl}) a meno che il programma da eseguire non sia
\acr{suid} o \acr{sgid} (vedi sez.~\ref{sec:proc_access_id} e
l'esistenza dell'\ids{UID} salvato e del \ids{GID} salvato, sono
rispettivamente \funcd{setuid} e \funcd{setgid}; i loro prototipi sono:
-\begin{funcproto}{
+\begin{funcproto}{
\fhead{unistd.h}
\fhead{sys/types.h}
\fdecl{int setuid(uid\_t uid)}
-\fdesc{Imposta l'\ids{UID} del processo corrente.}
+\fdesc{Imposta l'\ids{UID} del processo corrente.}
\fdecl{int setgid(gid\_t gid)}
-\fdesc{Imposta il \ids{GID} del processo corrente.}
+\fdesc{Imposta il \ids{GID} del processo corrente.}
}
{Le funzioni ritornano $0$ in caso di successo e $-1$ per un errore, nel qual
-caso \var{errno} può assumere solo il valore \errcode{EPERM}.
+caso \var{errno} uno dei valori:
+\begin{errlist}
+\item[\errcode{EAGAIN}] (solo per \func{setuid}) la chiamata cambierebbe
+ l'\ids{UID} reale ma il kernel non dispone temporaneamente delle risorse per
+ farlo, oppure, per i kernel precendenti il 3.1, il cambiamento
+ dell'\ids{UID} reale farebbe superare il limite per il numero dei processi
+ \const{RLIMIT\_NPROC} (vedi sez.~\ref{sec:sys_resource_limit}).
+\item[\errcode{EINVAL}] il valore di dell'argomento non è valido per il
+ \textit{namespace} corrente (vedi sez.~\ref{sec:process_namespaces}).
+\item[\errcode{EPERM}] non si hanno i permessi per l'operazione richiesta.
+\end{errlist}
}
\end{funcproto}
Il funzionamento di queste due funzioni è analogo, per cui considereremo solo
la prima, la seconda si comporta esattamente allo stesso modo facendo
-riferimento al \ids{GID} invece che all'\ids{UID}. Gli eventuali \ids{GID}
+riferimento al \ids{GID} invece che all'\ids{UID}. Gli eventuali \ids{GID}
supplementari non vengono modificati.
L'effetto della chiamata è diverso a seconda dei privilegi del processo; se
-l'\ids{UID} effettivo è zero (cioè è quello dell'amministratore di sistema)
-allora tutti gli identificatori (\textit{real}, \textit{effective} e
-\textit{saved}) vengono impostati al valore specificato da \param{uid},
-altrimenti viene impostato solo l'\ids{UID} effettivo, e soltanto se il valore
-specificato corrisponde o all'\ids{UID} reale o all'\ids{UID} salvato. Negli
-altri casi viene segnalato un errore con \errcode{EPERM}.
+l'\ids{UID} effettivo è zero (cioè è quello dell'amministratore di sistema o
+il processo ha la la capacità \const{CAP\_SETUID}) allora tutti gli
+identificatori (\textit{real}, \textit{effective} e \textit{saved}) vengono
+impostati al valore specificato da \param{uid}, altrimenti viene impostato
+solo l'\ids{UID} effettivo, e soltanto se il valore specificato corrisponde o
+all'\ids{UID} reale o all'\ids{UID} salvato, ottenendo un errore di
+\errcode{EPERM} negli altri casi.
+
+E' importante notare che la funzione può fallire con \errval{EAGAIN} anche
+quando viene invocata da un processo con privilegi di amministratore per
+cambiare il proprio l'\ids{UID} reale, sia per una temporanea indisponibilità
+di risorse del kernel, sia perché l'utente di cui si vuole assumere
+l'\ids{UID} andrebbe a superare un eventuale limite sul numero di processi (il
+limite \const{RLIMIT\_NPROC}, che tratteremo in
+sez.~\ref{sec:sys_resource_limit}),\footnote{non affronteremo qui l'altro caso
+ di errore, che può avvenire solo quando si esegue la funzione all'interno di
+ un diverso \textit{user namespace}, argomento su cui torneremo in
+ sez.~\ref{sec:process_namespaces}.} pertanto occorre sempre verificare lo
+stato di uscita della funzione.
+
+Non controllare questo tipo di errori perché si presume che la funzione abbia
+sempre successo quando si hanno i privilegi di amministratore può avere
+conseguente devastanti per la sicurezza, in particolare quando la si usa per
+cedere i suddetti privilegi ed eseguire un programma per conto di un utente
+non privilegiato.
+
+E' per diminuire l'impatto di questo tipo di disattenzioni che a partire dal
+kernel 3.1 il comportamento di \func{setuid} e di tutte le analoghe funzioni
+che tratteremo nel seguito di questa sezione è stato modificato e nel caso di
+superamento del limite sulle risorse esse hanno comunque successo. Quando
+questo avviene il processo assume comunque il nuovo \ids{UID} ed il controllo
+sul superamento di \const{RLIMIT\_NPROC} viene posticipato ad una eventuale
+successiva invocazione di \func{execve} (essendo questo poi il caso d'uso più
+comune). In tal caso, se alla chiamata ancora sussiste la situazione di
+superamento del limite, sarà \func{execve} a fallire con un errore di
+\const{EAGAIN}.\footnote{che pertanto, a partire dal kernel 3.1, può
+ restituire anche questo errore, non presente in altri sistemi
+ \textit{unix-like}.}
Come accennato l'uso principale di queste funzioni è quello di poter
consentire ad un programma con i bit \acr{suid} o \acr{sgid} impostati (vedi
viene gestito l'accesso al file \sysfiled{/var/run/utmp}. In questo file viene
registrato chi sta usando il sistema al momento corrente; chiaramente non può
essere lasciato aperto in scrittura a qualunque utente, che potrebbe
-falsificare la registrazione. Per questo motivo questo file (e l'analogo
-\sysfiled{/var/log/wtmp} su cui vengono registrati login e logout) appartengono
-ad un gruppo dedicato (in genere \acr{utmp}) ed i programmi che devono
-accedervi (ad esempio tutti i programmi di terminale in X, o il programma
-\cmd{screen} che crea terminali multipli su una console) appartengono a questo
-gruppo ed hanno il bit \acr{sgid} impostato.
+falsificare la registrazione.
+
+Per questo motivo questo file (e l'analogo \sysfiled{/var/log/wtmp} su cui
+vengono registrati login e logout) appartengono ad un gruppo dedicato (in
+genere \acr{utmp}) ed i programmi che devono accedervi (ad esempio tutti i
+programmi di terminale in X, o il programma \cmd{screen} che crea terminali
+multipli su una console) appartengono a questo gruppo ed hanno il bit
+\acr{sgid} impostato.
Quando uno di questi programmi (ad esempio \cmd{xterm}) viene lanciato, la
situazione degli identificatori è la seguente:
i privilegi di amministratore, in tal caso infatti l'esecuzione di una
\func{setuid} comporta il cambiamento di tutti gli identificatori associati al
processo, rendendo impossibile riguadagnare i privilegi di amministratore.
-Questo comportamento è corretto per l'uso che ne fa \cmd{login} una volta che
-crea una nuova shell per l'utente, ma quando si vuole cambiare soltanto
-l'\ids{UID} effettivo del processo per cedere i privilegi occorre
-ricorrere ad altre funzioni.
+Questo comportamento è corretto per l'uso che ne fa un programma come
+\cmd{login} una volta che crea una nuova shell per l'utente, ma quando si
+vuole cambiare soltanto l'\ids{UID} effettivo del processo per cedere i
+privilegi occorre ricorrere ad altre funzioni.
Le due funzioni di sistema \funcd{setreuid} e \funcd{setregid} derivano da BSD
che, non supportando (almeno fino alla versione 4.3+BSD) gli identificatori
\fdesc{Imposta \ids{GID} reale e \ids{GID} effettivo del processo corrente.}
}
{Le funzioni ritornano $0$ in caso di successo e $-1$ per un errore, nel qual
-caso \var{errno} può assumere solo il valore \errcode{EPERM}.
+caso \var{errno} assume i valori visti per \func{setuid}/\func{setgid}.
}
\end{funcproto}
\ids{UID} si applica alla seconda per i \ids{GID}. La funzione
\func{setreuid} imposta rispettivamente l'\ids{UID} reale e l'\ids{UID}
effettivo del processo corrente ai valori specificati da \param{ruid}
-e \param{euid}. I processi non privilegiati possono impostare solo valori che
-corrispondano o al loro \ids{UID} effettivo o a quello reale o a quello
-salvato, valori diversi comportano il fallimento della chiamata.
-L'amministratore invece può specificare un valore qualunque. Specificando un
-argomento di valore $-1$ l'identificatore corrispondente verrà lasciato
-inalterato.
+e \param{euid}.
+
+I processi non privilegiati possono impostare solo valori che corrispondano o
+al loro \ids{UID} effettivo o a quello reale o a quello salvato, valori
+diversi comportano il fallimento della chiamata. L'amministratore invece può
+specificare un valore qualunque. Specificando un argomento di valore $-1$
+l'identificatore corrispondente verrà lasciato inalterato.
Con queste funzioni si possono scambiare fra loro gli \ids{UID} reale ed
effettivo, e pertanto è possibile implementare un comportamento simile a
\fdesc{Imposta il \ids{GID} effettivo del processo corrente.}
}
{Le funzioni ritornano $0$ in caso di successo e $-1$ per un errore, nel qual
-caso \var{errno} può assumere solo il valore \errcode{EPERM}.
+caso \var{errno} assume i valori visti per \func{setuid}/\func{setgid}.
}
\end{funcproto}
\end{basedescript}
+\subsection{I \textit{namespace} ed i \textit{container}}
+\label{sec:process_namespaces}
+
+
%TODO sezione separata sui namespace
%TODO trattare unshare, vedi anche http://lwn.net/Articles/532748/