X-Git-Url: https://gapil.gnulinux.it/gitweb/?p=gapil.git;a=blobdiff_plain;f=prochand.tex;h=f18d49691edca1f0da63708c78dd5076dc5c981b;hp=77fde66866240282070bde592145adfcec005bf4;hb=71bd769469078fc921d9646d62b0f9293b6ae47c;hpb=178bf99c6bcb8b3ce3b95082212cb380988bb193 diff --git a/prochand.tex b/prochand.tex index 77fde66..f18d496 100644 --- a/prochand.tex +++ b/prochand.tex @@ -1,6 +1,6 @@ %% prochand.tex %% -%% Copyright (C) 2000-2005 Simone Piccardi. Permission is granted to +%% Copyright (C) 2000-2006 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", @@ -143,23 +143,23 @@ fig.~\ref{fig:proc_task_struct}. \label{fig:proc_task_struct} \end{figure} -Come accennato in sez.~\ref{sec:intro_unix_struct} è lo -\textit{scheduler}\itindex{scheduler} che decide quale processo mettere in -esecuzione; esso viene eseguito ad ogni system call ed ad ogni -interrupt,\footnote{più in una serie di altre occasioni.} +Come accennato in sez.~\ref{sec:intro_unix_struct} è lo \textit{scheduler} +\itindex{scheduler} che decide quale processo mettere in esecuzione; esso +viene eseguito ad ogni system call ed ad ogni interrupt,\footnote{più in una + serie di altre occasioni.} % TODO completare questa parte. (ma può essere anche attivato esplicitamente). Il timer di sistema provvede comunque a che esso sia invocato periodicamente, generando un interrupt periodico secondo la frequenza specificata dalla costante \const{HZ}, definita in \file{asm/param.h}, ed il cui valore è espresso in Hertz.\footnote{Fino al - kernel 2.4 l valore usuale di questa costante era 100, per tutte le + kernel 2.4 il valore usuale di questa costante era 100, per tutte le architetture eccetto l'alpha, per la quale era 1000. Occorre fare attenzione a non confondere questo valore con quello dei clock tick (vedi sez.~\ref{sec:sys_unix_time}).} % TODO verificare gli ultimi cambiamenti del 2.6 % Si ha cioè un interrupt dal timer ogni centesimo di secondo. -Ogni volta che viene eseguito, lo \textit{scheduler}\itindex{scheduler} +Ogni volta che viene eseguito, lo \textit{scheduler} \itindex{scheduler} effettua il calcolo delle priorità dei vari processi attivi (torneremo su questo in sez.~\ref{sec:proc_priority}) e stabilisce quale di essi debba essere posto in esecuzione fino alla successiva invocazione. @@ -327,14 +327,14 @@ condivisa, pertanto padre e figlio vedono variabili diverse. Per quanto riguarda la gestione della memoria, in generale il\index{segmento!testo} segmento di testo, che è identico per i due processi, è condiviso e tenuto in read-only per il padre e per i figli. Per gli altri -segmenti Linux utilizza la tecnica del \textit{copy on - write}\itindex{copy~on~write}; questa tecnica comporta che una pagina di -memoria viene effettivamente copiata per il nuovo processo solo quando ci -viene effettuata sopra una scrittura (e si ha quindi una reale differenza fra -padre e figlio). In questo modo si rende molto più efficiente il meccanismo -della creazione di un nuovo processo, non essendo più necessaria la copia di -tutto lo spazio degli indirizzi virtuali del padre, ma solo delle pagine di -memoria che sono state modificate, e solo al momento della modifica stessa. +segmenti Linux utilizza la tecnica del \textit{copy on write} +\itindex{copy~on~write}; questa tecnica comporta che una pagina di memoria +viene effettivamente copiata per il nuovo processo solo quando ci viene +effettuata sopra una scrittura (e si ha quindi una reale differenza fra padre +e figlio). In questo modo si rende molto più efficiente il meccanismo della +creazione di un nuovo processo, non essendo più necessaria la copia di tutto +lo spazio degli indirizzi virtuali del padre, ma solo delle pagine di memoria +che sono state modificate, e solo al momento della modifica stessa. La differenza che si ha nei due processi è che nel processo padre il valore di ritorno della funzione \func{fork} è il \acr{pid} del processo figlio, mentre @@ -454,19 +454,19 @@ ciclo successivo), mentre la terza volta (fino alla conclusione) e poi il padre. In generale l'ordine di esecuzione dipenderà, oltre che dall'algoritmo di -scheduling usato dal kernel, dalla particolare situazione in cui si trova la -macchina al momento della chiamata, risultando del tutto impredicibile. -Eseguendo più volte il programma di prova e producendo un numero diverso di -figli, si sono ottenute situazioni completamente diverse, compreso il caso in -cui il processo padre ha eseguito più di una \func{fork} prima che uno dei -figli venisse messo in esecuzione. +\itindex{scheduler} scheduling usato dal kernel, dalla particolare situazione +in cui si trova la macchina al momento della chiamata, risultando del tutto +impredicibile. Eseguendo più volte il programma di prova e producendo un +numero diverso di figli, si sono ottenute situazioni completamente diverse, +compreso il caso in cui il processo padre ha eseguito più di una \func{fork} +prima che uno dei figli venisse messo in esecuzione. Pertanto non si può fare nessuna assunzione sulla sequenza di esecuzione delle istruzioni del codice fra padre e figli, né sull'ordine in cui questi potranno essere messi in esecuzione. Se è necessaria una qualche forma di precedenza occorrerà provvedere ad espliciti meccanismi di sincronizzazione, pena il -rischio di incorrere nelle cosiddette \textit{race - condition}\itindex{race~condition} (vedi sez.~\ref{sec:proc_race_cond}). +rischio di incorrere nelle cosiddette \textit{race condition} +\itindex{race~condition} (vedi sez.~\ref{sec:proc_race_cond}). Si noti inoltre che essendo i segmenti di memoria utilizzati dai singoli processi completamente separati, le modifiche delle variabili nei processi @@ -639,7 +639,7 @@ padre, che costituiva un inutile appesantimento in tutti quei casi in cui la \func{fork} veniva fatta solo per poi eseguire una \func{exec}. La funzione venne introdotta in BSD per migliorare le prestazioni. -Dato che Linux supporta il \textit{copy on write}\itindex{copy~on~write} la +Dato che Linux supporta il \textit{copy on write} \itindex{copy~on~write} la perdita di prestazioni è assolutamente trascurabile, e l'uso di questa funzione (che resta un caso speciale della system call \func{\_\_clone}) è deprecato; per questo eviteremo di trattarla ulteriormente. @@ -788,19 +788,19 @@ terminale (prima dello scadere dei 10 secondi) otterremo: \end{verbatim} %$ \normalsize e come si vede, dato che non si è fatto nulla per riceverne lo stato di terminazione, i tre processi figli sono ancora presenti pur essendosi -conclusi, con lo stato di zombie\index{zombie} e l'indicazione che sono stati +conclusi, con lo stato di zombie \index{zombie} e l'indicazione che sono stati terminati. -La possibilità di avere degli zombie\index{zombie} deve essere tenuta sempre +La possibilità di avere degli zombie \index{zombie} deve essere tenuta sempre presente quando si scrive un programma che deve essere mantenuto in esecuzione a lungo e creare molti figli. In questo caso si deve sempre avere cura di far leggere l'eventuale stato di uscita di tutti i figli (in genere questo si fa attraverso un apposito \textit{signal handler}, che chiama la funzione \func{wait}, vedi sez.~\ref{sec:sig_sigchld} e sez.~\ref{sec:proc_wait}). -Questa operazione è necessaria perché anche se gli -\textit{zombie}\index{zombie} non consumano risorse di memoria o processore, -occupano comunque una voce nella tabella dei processi, che a lungo andare -potrebbe esaurirsi. +Questa operazione è necessaria perché anche se gli \textit{zombie} +\index{zombie} non consumano risorse di memoria o processore, occupano +comunque una voce nella tabella dei processi, che a lungo andare potrebbe +esaurirsi. Si noti che quando un processo adottato da \cmd{init} termina, esso non diviene uno \textit{zombie}\index{zombie}; questo perché una delle funzioni di @@ -818,7 +818,7 @@ processo che li ha generati, in modo che \cmd{init} possa adottarli e provvedere a concluderne la terminazione. -\subsection{Le funzioni \func{wait} e \func{waitpid}} +\subsection{Le funzioni \func{wait} e \func{waitpid}} \label{sec:proc_wait} Uno degli usi più comuni delle capacità multitasking di un sistema unix-like @@ -1269,8 +1269,8 @@ condivise, viene lanciato il \textit{linker} dinamico \cmd{/lib/ld.so} prima del programma per caricare le librerie necessarie ed effettuare il link dell'eseguibile. Se il programma è in formato ELF per caricare le librerie dinamiche viene usato l'interprete indicato nel segmento \const{PT\_INTERP}, -in genere questo è \file{/lib/ld-linux.so.1} per programmi linkati con le -\acr{libc5}, e \file{/lib/ld-linux.so.2} per programmi linkati con le +in genere questo è \file{/lib/ld-linux.so.1} per programmi collegati con le +\acr{libc5}, e \file{/lib/ld-linux.so.2} per programmi collegati con le \acr{glibc}. Infine nel caso il file sia uno script esso deve iniziare con una linea nella @@ -1278,12 +1278,12 @@ forma \cmd{\#!/path/to/interpreter [argomenti]} dove l'interprete indicato deve essere un programma valido (binario, non un altro script) che verrà chiamato come se si fosse eseguito il comando \cmd{interpreter [argomenti] filename}.\footnote{si tenga presente che con Linux quanto viene scritto - come \texttt{argomenti} viene passato all'inteprete come un unico argomento + come \texttt{argomenti} viene passato all'interprete come un unico argomento con una unica stringa di lunghezza massima di 127 caratteri e se questa dimensione viene ecceduta la stringa viene troncata; altri Unix hanno dimensioni massime diverse, e diversi comportamenti, ad esempio FreeBSD esegue la scansione della riga e la divide nei vari argomenti e se è troppo - lunga restitituisce un errore di \const{ENAMETOOLONG}, una comparazione dei + lunga restituisce un errore di \const{ENAMETOOLONG}, una comparazione dei vari comportamenti si trova su \href{http://www.in-ulm.de/~mascheck/various/shebang/} {\texttt{http://www.in-ulm.de/\tild mascheck/various/shebang/}}.} @@ -1575,10 +1575,9 @@ l'\textsl{user-ID effettivo} del processo per cedere i privilegi occorre ricorrere ad altre funzioni. Le due funzioni \funcd{setreuid} e \funcd{setregid} derivano da BSD che, non -supportando\footnote{almeno fino alla versione 4.3+BSD TODO, FIXME verificare - e aggiornare la nota.} gli identificatori del gruppo \textit{saved}, le usa -per poter scambiare fra di loro \textit{effective} e \textit{real}. I -rispettivi prototipi sono: +supportando\footnote{almeno fino alla versione 4.3+BSD.} gli identificatori +del gruppo \textit{saved}, le usa per poter scambiare fra di loro +\textit{effective} e \textit{real}. I rispettivi prototipi sono: \begin{functions} \headdecl{unistd.h} \headdecl{sys/types.h} @@ -1924,6 +1923,9 @@ implementata.\footnote{per attualmente si intende fino al kernel 2.6.13, e \textbf{Capacità}&\textbf{Descrizione}\\ \hline \hline +% +% POSIX-draft defined capabilities. +% \const{CAP\_CHOWN} & la capacità di cambiare proprietario e gruppo proprietario di un file (vedi sez.~\ref{sec:file_chown}).\\ @@ -1967,79 +1969,82 @@ implementata.\footnote{per attualmente si intende fino al kernel 2.6.13, e di impostare il bit \acr{sgid} su un file anche quando questo è relativo ad un gruppo cui non si appartiene (vedi sez.~\ref{sec:file_chmod}).\\ - \const{CAP\_IPC\_LOCK} & la capacità di effettuare il \textit{memory - locking} \itindex{memory~locking} con le - funzioni \func{mlock}, \func{mlockall}, - \func{shmctl}, \func{mmap} (vedi - sez.~\ref{sec:proc_mem_lock} e - sez.~\ref{sec:file_memory_map}). \\ - \const{CAP\_IPC\_OWNER} & la capacità di evitare il controllo dei permessi - per le operazioni sugli oggetti di - intercomunicazione fra processi (vedi - sez.~\ref{sec:ipc_sysv}).\\ \const{CAP\_KILL} & la capacità di mandare segnali a qualunque processo (vedi sez.~\ref{sec:sig_kill_raise}).\\ - \const{CAP\_LEASE} & la capacità di creare dei \textit{file lease} - \index{file!lease} su di un file (vedi - sez.~\ref{sec:file_asyncronous_lease}) - indipendentemente dalla proprietà dello - stesso.\footnotemark\\ - \const{CAP\_LINUX\_IMMUTABLE}& la capacità di impostare gli attributi - \textit{immutable} e \textit{append only} per i - file su un filesystem che supporta questi - attributi estesi.\\ - \const{CAP\_MKNOD} & la capacità di creare file di dispositivo con la - funzione \func{mknod} (vedi - sez.~\ref{sec:file_mknod}).\footnotemark\\ - \const{CAP\_NET\_ADMIN} & la capacità di eseguire alcune operazioni - privilegiate sulla rete (impostare le opzioni - privilegiate dei socket, abilitare il - multicasting, impostare interfacce di rete e - tabella di instradamento).\\ - \const{CAP\_NET\_BIND\_SERVICE}& la capacità di porre in ascolto server - su porte riservate (vedi - sez.~\ref{sec:TCP_func_bind}).\\ - \const{CAP\_NET\_BROADCAST}& la capacità di consentire l'uso di socket in - broadcast e multicast.\\ - \const{CAP\_NET\_RAW} & la capacità di usare socket \texttt{RAW} e - \texttt{PACKET} (quelli che permettono di creare - pacchetti nei protocolli di basso livello).\\ \const{CAP\_SETGID} & la capacità di manipolare i group ID dei processi, sia il principale che i supplementari, (vedi sez.~\ref{sec:proc_setgroups} che quelli trasmessi tramite i \index{socket} socket \textit{unix domain} (vedi sez.~\ref{sec:unix_socket}).\\ - \const{CAP\_SETPCAP} & la capacità di impostare o rimuovere una capacità - (limitatamente a quelle che il processo - chiamante ha nel suo insieme di capacità - permesse) da qualunque processo.\\ \const{CAP\_SETUID} & la capacità di manipolare gli user ID del processo (con \func{setuid}, \func{setreuid}, \func{setresuid}, \func{setfsuid}) e di trasmettere un valore arbitrario dell'\textsl{uid} nel passaggio delle credenziali coi socket unix domain (vedi - sez.~\ref{sec:unix_socket_xxx}).\\ + sez.~\ref{sec:unix_socket}).\\ +% +% Linux specific capabilities +% +\hline + \const{CAP\_SETPCAP} & la capacità di impostare o rimuovere una capacità + (limitatamente a quelle che il processo + chiamante ha nel suo insieme di capacità + permesse) da qualunque processo.\\ + \const{CAP\_LINUX\_IMMUTABLE}& la capacità di impostare gli attributi + \textit{immutable} e \itindex{append~mode} + \textit{append only} per i file su un + filesystem che supporta questi + attributi estesi.\\ + \const{CAP\_NET\_BIND\_SERVICE}& la capacità di porre in ascolto server + su porte riservate (vedi + sez.~\ref{sec:TCP_func_bind}).\\ + \const{CAP\_NET\_BROADCAST}& la capacità di consentire l'uso di socket in + \itindex{broadcast} \textit{broadcast} e + \itindex{multicast} \textit{multicast}.\\ + \const{CAP\_NET\_ADMIN} & la capacità di eseguire alcune operazioni + privilegiate sulla rete (impostare le opzioni + privilegiate dei socket, abilitare il + \itindex{multicast} \textit{multicasting}, + impostare interfacce di rete e + tabella di instradamento).\\ + \const{CAP\_NET\_RAW} & la capacità di usare socket \texttt{RAW} e + \texttt{PACKET} (quelli che permettono di creare + pacchetti nei protocolli di basso livello).\\ + \const{CAP\_IPC\_LOCK} & la capacità di effettuare il \textit{memory + locking} \itindex{memory~locking} con le + funzioni \func{mlock}, \func{mlockall}, + \func{shmctl}, \func{mmap} (vedi + sez.~\ref{sec:proc_mem_lock} e + sez.~\ref{sec:file_memory_map}). \\ + \const{CAP\_IPC\_OWNER} & la capacità di evitare il controllo dei permessi + per le operazioni sugli oggetti di + intercomunicazione fra processi (vedi + sez.~\ref{sec:ipc_sysv}).\\ + \const{CAP\_SYS\_MODULE}& la capacità di caricare e rimuovere moduli del + kernel. \\ + \const{CAP\_SYS\_RAWIO} & la capacità di eseguire operazioni sulle porte + di I/O con \func{ioperm} e \func{iopl} (vedi + sez.~\ref{sec:file_io_port}).\\ + \const{CAP\_SYS\_CHROOT}& la capacità di eseguire la funzione + \func{chroot} (vedi + sez.~\ref{sec:file_chroot}).\\ + \const{CAP\_SYS\_PTRACE}& consente di tracciare qualunque processo con + \func{ptrace} (vedi + sez.~\ref{sec:xxx_ptrace}).\\ +% TODO documentatare ptrace + \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\_ADMIN} & la capacità di eseguire una serie di compiti amministrativi (come impostare le quote, attivare e disattivare la swap, montare, rimontare e smontare filesystem, ecc.). \\ - \const{CAP\_SYS\_BOOT} & la capacità di fare eseguire un reboot del + \const{CAP\_SYS\_BOOT} & la capacità di fare eseguire un riavvio del sistema.\\ - \const{CAP\_SYS\_CHROOT}& la capacità di eseguire la funzione - \func{chroot} (vedi - sez.~\ref{sec:file_chroot}).\\ - \const{CAP\_SYS\_MODULE}& la capacità di caricare e rimuovere moduli del - kernel. \\ \const{CAP\_SYS\_NICE} & la capacità di modificare le priorità dei 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\_RAWIO} & la capacità di eseguire operazioni sulle porte - di I/O con \func{ioperm} e \func{iopl} (vedi - sez.~\ref{sec:file_io_port}).\\ \const{CAP\_SYS\_RESOURCE}& la capacità di superare le limitazioni sulle risorse, aumentare le quote disco, usare lo spazio disco riservato all'amministratore.\\ @@ -2048,10 +2053,17 @@ implementata.\footnote{per attualmente si intende fino al kernel 2.6.13, e \const{CAP\_SYS\_TTY\_CONFIG}& la capacità di simulare un \textit{hangup} della console, con la funzione \func{vhangup}.\\ - \const{CAP\_SYS\_PTRACE}& consente di tracciare qualunque processo con - \func{ptrace} (vedi - sez.~\ref{sec:xxx_ptrace}).\\ -% TODO documentatare ptrace + \const{CAP\_MKNOD} & la capacità di creare file di dispositivo con la + funzione \func{mknod} (vedi + sez.~\ref{sec:file_mknod}).\footnotemark\\ + \const{CAP\_LEASE} & la capacità di creare dei \textit{file lease} + \index{file!lease} su di un file (vedi + sez.~\ref{sec:file_asyncronous_lease}) + indipendentemente dalla proprietà dello + stesso.\footnotemark\\ + \const{CAP\_SETFCAP} & la capacità di impostare le + \textit{capabilities} di un file (non + supportata).\\ \hline \end{tabular} \caption{Le costanti che identificano le \textit{capabilities} presenti nel @@ -2059,10 +2071,10 @@ implementata.\footnote{per attualmente si intende fino al kernel 2.6.13, e \label{tab:proc_capabilities} \end{table} -\footnotetext[21]{questa capacità è presente soltato a partire dai kernel +\footnotetext[21]{questa capacità è presente soltanto a partire dai kernel della serie 2.4.x.} -\footnotetext{questa capacità è presente soltato a partire dai kernel della +\footnotetext{questa capacità è presente soltanto a partire dai kernel della serie 2.4.x.} Per gestire questo nuovo meccanismo ciascun processo porta con sé tre distinti @@ -2078,9 +2090,12 @@ vengono mantenuti in forma di tre diverse maschere binarie,\footnote{il kernel ciascun bit corrisponde ad una capacità diversa; se ne è riportato l'elenco,\footnote{si tenga presente che l'elenco delle \textit{capabilities} presentato questa tabella, ripreso dalla relativa pagina di manuale - (accessibile con \texttt{man capabilities}), è quello aggiornato al kernel - 2.6.6.} con una breve descrizione, ed il nome delle costanti che -identificano i singoli bit, in tab.~\ref{tab:proc_capabilities}. + (accessibile con \texttt{man capabilities}) e dalle definizioni in + \texttt{sys/capabilities.h}, è quello aggiornato al kernel 2.6.6.} con una +breve descrizione, ed il nome delle costanti che identificano i singoli bit, +in tab.~\ref{tab:proc_capabilities}; la tabella è divisa in due parti, la +prima riporta le \textit{capabilities} previste nella bozza dello standard +POSIX1.e, la seconda quelle specifiche di Linux. L'utilizzo di tre distinti insiemi serve a fornire una interfaccia flessibile per l'uso delle \textit{capabilities}, con scopi analoghi a quelli per cui @@ -2181,7 +2196,7 @@ 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. Pertando se si vogliono scrivere +assicurazione che questa venga mantenuta. Pertanto se si vogliono scrivere programmi portabili che possano essere eseguiti su qualunque versione del kernel è opportuno utilizzare le interfacce di alto livello. @@ -2219,22 +2234,21 @@ una libreria a parte,\footnote{la libreria programma le utilizza si dovrà indicare esplicitamente l'uso della suddetta libreria attraverso l'opzione \texttt{-lcap} del compilatore. -Le funzioni dell'interfaccia 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 fornirà 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 è allora quella che permette di -inizializzare un \textit{capability state}, allocando al contempo la memoria -necessaria per i relativi dati. La funzione è \funcd{cap\_init} ed il suo -prototipo è: +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}. + +La prima funzione dell'interfaccia è quella che permette di inizializzare un +\textit{capability state}, allocando al contempo la memoria necessaria per i +relativi dati. La funzione è \funcd{cap\_init} ed il suo prototipo è: \begin{functions} \headdecl{sys/capability.h} @@ -2244,12 +2258,12 @@ prototipo \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 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 suffuciente ad allocare i dati) viene restituito \macro{NULL} +non c'è memoria sufficiente ad allocare i dati) viene restituito \macro{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 la @@ -2262,7 +2276,7 @@ funzione \funcd{cap\_free}, il cui prototipo \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 permette di liberare la memoria allocata dalle altre funzioni @@ -2285,15 +2299,15 @@ precedenza tramite la funzione \funcd{cap\_dup}, il cui prototipo \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 valori \errval{ENOMEM} o \errval{EINVAL}. -} + } \end{functions} -La funzione crea una copia del \textit{capability state} \param{cap\_p} -passato come argomento, restituendo il puntatore alla copia che conterrà gli -stessi valori delle \textit{capabilities} presenti nell'originale. La memoria -necessaria viene allocata automaticamente dalla funzione. Una volta effettuata -la copia i due \textit{capability state} potranno essere modificati in maniera -completamente indipendente. +La funzione crea una copia del \textit{capability state} posto all'indirizzo +\param{cap\_p} che si è passato come argomento, restituendo il puntatore alla +copia, che conterrà gli stessi valori delle \textit{capabilities} presenti +nell'originale. La memoria necessaria viene allocata automaticamente dalla +funzione. Una volta effettuata la copia i due \textit{capability state} +potranno essere modificati in maniera completamente indipendente. Una seconda classe di funzioni di servizio sono quelle per la gestione dei dati contenuti all'interno di un \textit{capability state}; la prima di esse è @@ -2307,13 +2321,13 @@ dati contenuti all'interno di un \textit{capability state}; la prima di esse \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 si limita ad azzerare tutte le \textit{capabilities} presenti nel -\textit{capability state} \param{cap\_p} passato come argomento restituendo -uno stato \textsl{vuoto}, analogo a quello che si ottiene nella creazione con -\func{cap\_init}. +\textit{capability state} all'indirizzo \param{cap\_p} passato come argomento, +restituendo uno stato \textsl{vuoto}, analogo a quello che si ottiene nella +creazione con \func{cap\_init}. Per la gestione dei valori delle \textit{capabilities} presenti in un \textit{capability state} l'interfaccia prevede due funzioni, @@ -2336,11 +2350,11 @@ rispettivamente di leggere o impostare il valore di un flag delle } \end{functions} -In entrambe le funzioni l'argomento \param{cap\_p} indica il +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. Questo deve essere -specificato con una variabile di tipo \type{cap\_flag\_t} e può assumere +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 @@ -2364,18 +2378,18 @@ tab.~\ref{tab:cap_set_identifier}. \label{tab:cap_set_identifier} \end{table} -La capacità che si intende controllare o impostare 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 -\textit{capabilities}.\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}.} -Infine lo stato di una \textit{capabilities} è descritto ad una variabile di -tipo \type{cap\_flag\_value\_t}, che a sua volta può assumere soltanto -uno\footnote{anche questo è un tipo enumerato.} dei valori di -tab.~\ref{tab:cap_value_type}. +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}.} Infine lo stato di una capacità è +descritto ad una variabile di tipo \type{cap\_flag\_value\_t}, che a sua volta +può assumere soltanto uno\footnote{anche questo è un tipo enumerato.} dei +valori di tab.~\ref{tab:cap_value_type}. \begin{table}[htb] \centering @@ -2398,7 +2412,7 @@ La funzione \func{cap\_get\_flag} legge lo stato della capacit 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 \textit{capability} alla volta. +stato di una capacità alla volta. La funzione \func{cap\_set\_flag} può invece impostare in una sola chiamata più capacità, anche se solo all'interno dello stesso insieme; per questo essa @@ -2407,10 +2421,142 @@ prende un vettore di valori di tipo \type{cap\_value\_t} nell'argomento 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 è: +\begin{functions} + \headdecl{sys/capability.h} + + \funcdecl{char * cap\_to\_text(cap\_t caps, ssize\_t * length\_p)} + + Genera una visualizzazione testuale delle \textit{capabilities}. + + \bodydesc{La funzione ritorna un puntatore alla stringa con la descrizione + delle \textit{capabilities} 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 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 deve essere liberata con \func{cap\_free}. + +Fin quei abbiamo trattato delle funzioni di manipolazione dei +\textit{capabilities state}; quando si vuole eseguire la lettura delle +\textit{capabilities} del processo corrente si deve usare la funzione +\funcd{cap\_get\_proc}, il cui prototipo è: +\begin{functions} + \headdecl{sys/capability.h} + + \funcdecl{cap\_t cap\_get\_proc(void)} + Legge le \textit{capabilities} del processo corrente. + + \bodydesc{La funzione ritorna un valore diverso da \val{NULL} in caso di + successo e \val{NULL} in caso di errore, nel qual caso \var{errno} può + assumere i valori \errval{EINVAL}, \errval{EPERM} o \errval{ENOMEM}. } +\end{functions} + +La funzione legge il valore delle \textit{capabilities} del processo corrente +e restituisce il puntatore ad un \textit{capabilities state} contenente il +risultato, che provvede ad allocare autonomamente, e che occorrerà liberare +con \func{cap\_free} quando non sarà più utilizzato. + +Se invece si vogliono leggere le \textit{capabilities} di un processo +specifico occorre usare la funzione \funcd{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}.} è: +\begin{functions} + \headdecl{sys/capability.h} + + \funcdecl{int capgetp(pid\_t pid, cap\_t cap\_d)} + Legge le \textit{capabilities} del processo indicato da \param{pid}. + + \bodydesc{La funzione ritorna 0 in caso di successo e $-1$ in caso di + errore, nel qual caso \var{errno} può assumere i valori \errval{EINVAL}, + \errval{EPERM} o \errval{ENOMEM}. + } +\end{functions} +La funzione legge il valore delle \textit{capabilities} del processo indicato +con l'argomento \param{pid}, salvando il risultato nel \textit{capabilities + state} all'indirizzo \param{cap\_d} che deve essere stato creato in +precedenza. Qualora il processo non esista si avrà un errore di +\errval{ESRCH}. Gli stessi valori possono essere letti direttamente nel +filesystem \textit{proc}, nei file \texttt{/proc//status}; ad esempio per +\texttt{init} si otterrà qualcosa del tipo: +\begin{Verbatim} +... +CapInh: 0000000000000000 +CapPrm: 00000000fffffeff +CapEff: 00000000fffffeff +\end{Verbatim} + +Infine per impostare le \textit{capabilities} del processo corrente (non +esiste una funzione che permetta di cambiare le \textit{capabilities} di un +altro processo) si deve usare la funzione \funcd{cap\_set\_proc}, il cui +prototipo è: +\begin{functions} + \headdecl{sys/capability.h} + \funcdecl{int cap\_set\_proc(cap\_t cap\_p)} + Imposta le \textit{capabilities} del processo corrente. + + \bodydesc{La funzione ritorna 0 in caso di successo e $-1$ in caso di + errore, nel qual caso \var{errno} può assumere i valori \errval{EINVAL}, + \errval{EPERM} o \errval{ENOMEM}. + } +\end{functions} +La funzione modifica le \textit{capabilities} del processo corrente secondo +quanto specificato con l'argomento \param{cap\_p}, posto che questo sia +possibile nei termini spiegati in precedenza (non sarà ad esempio possibile +impostare capacità non presenti nell'insieme di quelle permesse). In caso di +successo i nuovi valori saranno effettivi al ritorno della funzione, in caso +di fallimento invece lo stato delle capacità resterà invariato. Si tenga +presente che \textsl{tutte} le capacità specificate tramite \param{cap\_p} +devono essere permesse; se anche una sola non lo è la funzione fallirà, e per +quanto appena detto, lo stato delle \textit{capabilities} non verrà modificato +(neanche per le parti eventualmente permesse). + +Come esempio di utilizzo di queste funzioni nei sorgenti allegati alla guida +si è distribuito il programma \texttt{getcap.c}, che consente di leggere le +\textit{capabilities} del processo corrente\footnote{vale a dire di sé stesso, + quando lo si lancia, il che può sembrare inutile, ma serve a mostrarci quali + sono le \textit{capabilities} standard che ottiene un processo lanciato + dalla riga di comando.} o tramite l'opzione \texttt{-p}, quelle di un +processo qualunque il cui pid viene passato come parametro dell'opzione. +\begin{figure}[htb] + \footnotesize \centering + \begin{minipage}[c]{15cm} + \includecodesample{listati/getcap.c} + \end{minipage} + \normalsize + \caption{Corpo principale del programma \texttt{getcap.c}.} + \label{fig:proc_getcap} +\end{figure} + +La sezione principale del programma è riportata in fig.~\ref{fig:proc_getcap}, +e si basa su una condizione sulla variabile \var{pid} che se si è usato +l'opzione \texttt{-p} è impostata (nella sezione di gestione delle opzioni, +che si è tralasciata) al valore del \textsl{pid} del processo di cui si vuole +leggere le \textit{capabilities} e nulla altrimenti. Nel primo caso +(\texttt{\small 1--6}) si utilizza direttamente (\texttt{\small 2}) +\func{cap\_get\_proc} per ottenere lo stato delle capacità del processo, nel +secondo (\texttt{\small 7--14}) prima si inizializza (\texttt{\small 8}) uno +stato vuoto e poi (\texttt{\small 9}) si legge il valore delle capacità del +processo indicato. + +Il passo successivo è utilizzare (\texttt{\small 16}) \func{cap\_to\_text} per +tradurre in una stringa lo stato, e poi (\texttt{\small 17}) stamparlo; infine +(\texttt{\small 19--20}) si libera la memoria allocata dalle precedenti +funzioni con \func{cap\_free} per poi ritornare dal ciclo principale della +funzione. \itindend{capabilities} @@ -3023,7 +3169,7 @@ su quali processori far eseguire un determinato processo attraverso una \texttt{len} è stato eliminato, successivamente si è introdotta la versione riportata con però un secondo argomento di tipo \texttt{size\_t cpusetsize} (anche questa citata nella pagina di manuale); la versione citata è quella - riportata nel manuale delle \textsl{glibc} e corripondente alla definizione + riportata nel manuale delle \textsl{glibc} e corrispondente alla definizione presente in \file{sched.h}.} è: \begin{prototype}{sched.h} {int sched\_setaffinity (pid\_t pid, const cpu\_set\_t *cpuset)} @@ -3075,7 +3221,7 @@ di processore. Per facilitare l'uso dell'argomento \param{cpuset} le \acr{glibc} hanno introdotto un apposito dato di tipo, \ctyp{cpu\_set\_t},\footnote{questa è una estensione specifica delle \acr{glibc}, da attivare definendo la macro - \macro{\_GNU\_SOURCE}, non esiste infatti una standardardizzazione per + \macro{\_GNU\_SOURCE}, non esiste infatti una standardizzazione per questo tipo di interfaccia e POSIX al momento non prevede nulla al riguardo.} che permette di identificare un insieme di processori. Il dato è una maschera binaria: in generale è un intero a 32 bit in cui ogni bit @@ -3130,7 +3276,7 @@ valore per un processo specifico usando la funzione La funzione restituirà all'indirizzo specificato da \param{cpuset} il valore della maschera di affinità del processo, così da poterla riutilizzare per una successiva reimpostazione. In questo caso non sono necessari privilegi -paricolari. +particolari. È chiaro che queste funzioni per la gestione dell'affinità hanno significato soltanto su un sistema multiprocessore, esse possono comunque essere @@ -3272,7 +3418,7 @@ multi-thread, ma si hanno gli stessi problemi quando si vogliono chiamare delle funzioni all'interno dei gestori dei segnali. Fintanto che una funzione opera soltanto con le variabili locali è rientrante; -queste infatti vengono allocate nello \itindex{stack} stack, e un'altra +queste infatti vengono allocate nello \itindex{stack} stack, ed un'altra invocazione non fa altro che allocarne un'altra copia. Una funzione può non essere rientrante quando opera su memoria che non è nello \itindex{stack} stack. Ad esempio una funzione non è mai rientrante se usa una variabile @@ -3296,8 +3442,51 @@ varie funzioni di libreria, che sono identificate aggiungendo il suffisso \code{\_r} al nome della versione normale. - %%% Local Variables: %%% mode: latex %%% TeX-master: "gapil" %%% End: + +% LocalWords: multitasking like VMS child process identifier pid sez shell fig +% LocalWords: parent kernel init pstree keventd kswapd table struct linux call +% LocalWords: nell'header scheduler system interrupt timer HZ asm Hertz clock +% LocalWords: l'alpha tick fork wait waitpid exit exec image glibc int pgid ps +% LocalWords: sid threads thread Ingo Molnar ppid getpid getppid sys unistd LD +% LocalWords: void ForkTest tempnam pathname sibling cap errno EAGAIN ENOMEM +% LocalWords: stack read only copy write tab client spawn forktest sleep PATH +% LocalWords: source LIBRARY scheduling race condition printf descriptor dup +% LocalWords: close group session tms lock vfork execve BSD stream main abort +% LocalWords: SIGABRT SIGCHLD SIGHUP foreground SIGCONT termination signal ANY +% LocalWords: handler kill EINTR POSIX options WNOHANG ECHILD option WUNTRACED +% LocalWords: dump bits rusage getrusage heap const filename argv envp EACCES +% LocalWords: filesystem noexec EPERM suid sgid root nosuid ENOEXEC ENOENT ELF +% LocalWords: ETXTBSY EINVAL ELIBBAD BIG EFAULT EIO ENAMETOOLONG ELOOP ENOTDIR +% LocalWords: ENFILE EMFILE argc execl path execv execle execlp execvp vector +% LocalWords: list environ NULL umask pending utime cutime ustime fcntl linker +% LocalWords: opendir libc interpreter FreeBSD capabilities Mandatory Access +% LocalWords: Control MAC SELinux Security Modules LSM superuser uid gid saved +% LocalWords: effective euid egid dell' fsuid fsgid getuid geteuid getgid SVr +% LocalWords: getegid IDS NFS setuid setgid all' logout utmp screen xterm TODO +% LocalWords: setreuid setregid FIXME ruid rgid seteuid setegid setresuid size +% LocalWords: setresgid getresuid getresgid value result argument setfsuid DAC +% LocalWords: setfsgid NGROUPS sysconf getgroups getgrouplist groups ngroups +% LocalWords: setgroups initgroups patch LIDS CHOWN OVERRIDE Discrectionary PF +% LocalWords: SEARCH chattr sticky NOATIME socket domain immutable append mmap +% LocalWords: broadcast multicast multicasting memory locking mlock mlockall +% LocalWords: shmctl ioperm iopl chroot ptrace accounting swap reboot hangup +% LocalWords: vhangup mknod lease permitted inherited inheritable bounding AND +% LocalWords: capability capget capset header ESRCH undef version obj clear PT +% LocalWords: pag ssize length proc capgetp prehemptive cache runnable Stopped +% LocalWords: Uninterrutible SIGSTOP soft slice nice niceness counter which SC +% LocalWords: getpriority who setpriority RTLinux RTAI Adeos fault FIFO First +% LocalWords: yield Robin setscheduler policy param OTHER priority setparam to +% LocalWords: min getparam getscheduler interval robin ENOSYS fifo ping long +% LocalWords: affinity setaffinity unsigned mask cpu NUMA CLR ISSET SETSIZE RR +% LocalWords: getaffinity assembler deadlock REENTRANT SAFE tgz MYPGRP l'OR rr +% LocalWords: WIFEXITED WEXITSTATUS WIFSIGNALED WTERMSIG WCOREDUMP WIFSTOPPED +% LocalWords: WSTOPSIG opt char INTERP arg SIG IGN DFL mascheck grp FOWNER RAW +% LocalWords: FSETID SETPCAP BIND SERVICE ADMIN PACKET IPC OWNER MODULE RAWIO +% LocalWords: PACCT RESOURCE TTY CONFIG SETFCAP hdrp datap libcap lcap text tp +% LocalWords: get ncap caps CapInh CapPrm fffffeff CapEff getcap STAT dall'I +% LocalWords: inc PRIO SUSv PRGR prio SysV SunOS Ultrix sched timespec len sig +% LocalWords: cpusetsize cpuset atomic