From: Simone Piccardi Date: Sat, 27 Aug 2011 18:06:53 +0000 (+0000) Subject: Quasi finito con le capabilities, aggiunti pezzi su prctl, spostata la X-Git-Url: https://gapil.gnulinux.it/gitweb/?p=gapil.git;a=commitdiff_plain;h=68fa6cc298c7449a011865c55c5af979963a2753 Quasi finito con le capabilities, aggiunti pezzi su prctl, spostata la parte sulla endianess all'inizio dove risulta appropriata. Trattati anche altri due flag di prctl per i core dump. --- diff --git a/filedir.tex b/filedir.tex index b94e1d8..e959de8 100644 --- a/filedir.tex +++ b/filedir.tex @@ -4687,14 +4687,14 @@ loro significato è diverso: capacità \textsl{permesse} del processo. \item[\textit{inheritable}] (chiamato originariamente \textit{allowed}) l'insieme delle capacità che con l'esecuzione del programma possono essere - ereditate dal processo originario (che cioè vengono tolte + ereditate dal processo originario (che cioè non vengono tolte dall'\textit{inheritable set} del processo originale all'esecuzione di \func{exec}). \item[\textit{effective}] in questo caso non si tratta di un insieme ma di un unico valore logico; se attivo all'esecuzione del programma tutte le capacità che risulterebbero \textsl{permesse} verranno pure attivate, inserendole automaticamente nelle \textsl{effettive}, se disattivato nessuna - capacità verrà attivata (cioè l'\textit{effective set} resta vuoto). + capacità verrà attivata (cioè l'\textit{effective set} resterà vuoto). \end{basedescript} \itindbeg{capabilities~bounding~set} @@ -4714,21 +4714,22 @@ sede di compilazione del kernel, e da sempre ha previsto come default la presenza di tutte le \textit{capabilities} eccetto \const{CAP\_SETPCAP}. In questa situazione solo il primo processo eseguito nel sistema (quello con \textsl{pid} 1, di norma \texttt{/sbin/init}) ha la possibilità di -modificarlo, ogni processo eseguito successivamente, anche se eseguito con -privilegi di amministratore,\footnote{per essere precisi occorreva la capacità - \const{CAP\_SYS\_MODULE}.} è in grado soltanto di rimuovere una delle -\textit{capabilities} già presenti dell'insieme. - -In questo caso l'effetto del \textit{capabilities bounding set} è che solo le -capacità in esso presenti possono essere trasmesse ad un altro programma -attraverso una \func{exec}. Questo in sostanza significa che se si elimina da -esso una capacità, considerato che \texttt{init} (almeno nelle versioni -ordinarie) non supporta la reimpostazione del \textit{bounding set}, questa -non sarà più disponibile per nessun processo a meno di un riavvio, eliminando -così in forma definitiva quella capacità per tutti, compreso -l'amministratore.\footnote{la qual cosa, visto il default usato per il - \textit{capabilities bounding set}, significa anche che \const{CAP\_SETPCAP} - non è stata praticamente mai usata nella sua forma originale.} +modificarlo; ogni processo eseguito successivamente, se dotato dei privilegi +di amministratore, è in grado soltanto di rimuovere una delle +\textit{capabilities} già presenti dell'insieme.\footnote{per essere precisi + occorreva la capacità \const{CAP\_SYS\_MODULE}.} + +In questo caso l'effetto complessivo del \textit{capabilities bounding set} è +che solo le capacità in esso presenti possono essere trasmesse ad un altro +programma attraverso una \func{exec}. Questo in sostanza significa che se un +qualunque programma elimina da esso una capacità, considerato che +\texttt{init} (almeno nelle versioni ordinarie) non supporta la reimpostazione +del \textit{bounding set}, questa non sarà più disponibile per nessun processo +a meno di un riavvio, eliminando così in forma definitiva quella capacità per +tutti, compreso l'amministratore.\footnote{la qual cosa, visto il default + usato per il \textit{capabilities bounding set}, significa anche che + \const{CAP\_SETPCAP} non è stata praticamente mai usata nella sua forma + originale.} Con il kernel 2.6.25 e le \textit{file capabilities} il \textit{bounding set} è diventato una proprietà di ciascun processo, che viene propagata invariata @@ -4761,7 +4762,7 @@ un limite per le capacità che possono essere aggiunte all'\textit{inheritable devono essere presenti nel \textit{bounding set} oltre che nel \textit{permitted set} del processo. Questo limite vale anche per processi con i privilegi di amministratore,\footnote{si tratta sempre di avere la - \textit{capability} \const{CAP\_SETPCAP}.} per i quali non vale la + \textit{capability} \const{CAP\_SETPCAP}.} per i quali invece non vale la condizione che le \textit{capabilities} da aggiungere nell'\textit{inheritable set} debbano essere presenti nel proprio \textit{permitted set}.\footnote{lo scopo anche in questo caso è ottenere una rimozione definitiva della @@ -4772,8 +4773,8 @@ comunque farsi carico di una notevole complessità di gestione, aggravata dalla presenza di una radicale modifica del loro funzionamento con l'introduzione delle \textit{file capabilities}. Considerato che il meccanismo originale era incompleto e decisamente problematico nel caso di programmi che non ne -sappessero tener conto,\footnote{si ebbe un grosso problema di sicurezza con - \texttt{sendmail}: riuscendo a rimuovere \const{CAP\_SETGID} +sapessero tener conto,\footnote{c'è stato un grosso problema di sicurezza con + \texttt{sendmail}, riuscendo a rimuovere \const{CAP\_SETGID} dall'\textit{inheritable set} di un processo si ottenne di far fallire \func{setuid} in maniera inaspettata per il programma (che aspettandosi sempre il successo della funzione non ne controllava lo stato di uscita) con @@ -4789,7 +4790,7 @@ ereditate senza modifiche attraverso una \func{fork} mentre, indicati con \texttt{file\_*} quelli del file eseguito e con \texttt{bound\_set} il \textit{capabilities bounding set}, dopo l'invocazione di \func{exec} il processo otterrà dei nuovi insiemi di capacità \texttt{new\_*} secondo la -formula (espressa in pseudocodice C) di fig.~\ref{fig:cap_across_exec}; si +formula (espressa in pseudo-codice C) di fig.~\ref{fig:cap_across_exec}; si noti come in particolare il \textit{capabilities bounding set} non viene comunque modificato e resta lo stesso sia attraverso una \func{fork} che attraverso una \func{exec}. @@ -4807,36 +4808,142 @@ attraverso una \func{exec}. \itindend{capabilities~bounding~set} A queste regole se ne aggiungono delle altre che servono a riprodurre il -comportamento tradizionale di un sistema unix-like quando viene eseguito un -file senza \textit{capabilities}, se si applicassero sempre così infatti, non -essendo definite delle capacità né nel \textit{permitted set} né -nell'\textit{inheritable set} del file, anche l'amministratore perderebbe -tutti i privilegi eventualmente avuti dal processo. - -Per questo motivo se un programma senza \textit{capabilities} viene eseguito -da un processo con \textit{real user-ID} 0, o se ha attivo il \acr{suid} bit -ed appartiene all'amministratore, esso viene trattato come se tanto il -\textit{permitted set} che l'\textit{inheritable set} fossero con tutte le -\textit{capabilities} abilitate, e con l'\textit{effective set} attivo, col -risultato di fornire comunque al processo tutte le capacità presenti nel -proprio \textit{bounding set}. - - +comportamento tradizionale di un sistema unix-like in tutta una serie di +circostanze. La prima di queste è relativa a quello che avviene quando si +esegue un file senza \textit{capabilities}; se infatti si considerasse questo +equivalente al non averne assegnata alcuna, non essendo presenti capacità né +nel \textit{permitted set} né nell'\textit{inheritable set} del file, +nell'esecuzione di un qualunque programma l'amministratore perderebbe tutti i +privilegi originali dal processo. + +Per questo motivo se un programma senza \textit{capabilities} assegnate viene +eseguito da un processo con \textit{real user-ID} 0, esso verrà trattato come +se tanto il \textit{permitted set} che l'\textit{inheritable set} fossero con +tutte le \textit{capabilities} abilitate, con l'\textit{effective set} attivo, +col risultato di fornire comunque al processo tutte le capacità presenti nel +proprio \textit{bounding set}. Lo stesso avviene quando l'eseguibile ha attivo +il \acr{suid} bit ed appartiene all'amministratore, in entrambi i casi si +riesce così a riottenere il comportamento classico di un sistema unix-like. + +Una seconda circostanza è quella relativa a cosa succede alle +\textit{capabilities} di un processo nelle possibili transizioni da +\textit{user-ID} nullo a \textit{user-ID} non nullo o viceversa (corrispondenti +rispettivamente a cedere o riottenere i i privilegi di amministratore) che si +possono effettuare con le varie funzioni viste in +sez.~\ref{sec:proc_setuid}. In questo caso la casistica è di nuovo alquanto +complessa, considerata anche la presenza dei diversi gruppi di identificatori +illustrati in tab.~\ref{tab:proc_uid_gid}, si avrà allora che: +\begin{enumerate*} +\item se si passa da \textit{effective user-ID} nullo a non nullo + l'\textit{effective set} del processo viene totalmente azzerato, se + viceversa si passa da \textit{effective user-ID} non nullo a nullo il + \textit{permitted set} viene copiato nell'\textit{effective set}; +\item se si passa da \textit{file system user-ID} nullo a non nullo verranno + cancellate dall'\textit{effective set} del processo tutte le capacità + attinenti i file, e cioè \const{CAP\_LINUX\_IMMUTABLE}, \const{CAP\_MKNOD}, + \const{CAP\_DAC\_OVERRIDE}, \const{CAP\_DAC\_READ\_SEARCH}, + \const{CAP\_MAC\_OVERRIDE}, \const{CAP\_CHOWN}, \const{CAP\_FSETID} e + \const{CAP\_FOWNER} (le prime due a partire dal kernel 2.2.30), nella + transizione inversa verranno invece inserite nell'\textit{effective set} + quelle capacità della precedente lista che sono presenti nel suo + \textit{permitted set}. +\item se come risultato di una transizione riguardante gli identificativi dei + gruppi \texttt{real}, \textit{saved} ed \textit{effective} in cui si passa + da una situazione in cui uno di questi era nullo ad una in cui sono tutti + non nulli,\footnote{in sostanza questo è il caso di quando si chiama + \func{setuid} per rimuovere definitivamente i privilegi di amministratore + da un processo.} verranno azzerati completamente sia il \textit{permitted + set} che l'\textit{effective set}. +\end{enumerate*} +La combinazione di tutte queste regole consente di riprodurre il comportamento +ordinario di un sistema di tipo Unix tradizionale, ma può risultare +problematica qualora si voglia passare ad una configurazione di sistema +totalmente basata sull'applicazione delle \textit{capabilities}; in tal caso +infatti basta ad esempio eseguire un programma con \acr{suid} bit di proprietà +dell'amministratore per far riottenere ad un processo tutte le capacità +presenti nel suo \textit{bounding set}, anche se si era avuta la cura di +cancellarle dal \textit{permitted set}. + +\itindbeg{securebits} + +Per questo motivo a partire dal kernel 2.6.26, se le \textit{file + capabilities} sono abilitate, ad ogni processo viene stata associata una +ulteriore maschera binaria, chiamata \textit{securebits flags}, il cui sono +mantenuti una serie di flag (vedi tab.~\ref{tab:securebits_values}) il cui +valore consente di modificare queste regole speciali che si applicano ai +processi con \textit{user-ID} nullo. La maschera viene sempre mantenuta +attraverso una \func{fork}, mentre attraverso una \func{exec} viene sempre +cancellato il flag \const{SECURE\_KEEP\_CAPS}. -Quando un programma viene messo in esecuzione\footnote{cioè quando viene - eseguita la \func{execve} con cui lo si lancia; in corrispondenza di una - \func{fork} le \textit{capabilities} non vengono modificate.} esso eredita -(nel senso che assume negli insiemi \textit{effective} e \textit{permitted}) -le \textit{capabilities} mantenute nell'insieme \textit{inherited}, a meno che -non sia eseguito un programma \acr{suid} di root o la \func{exec} sia stata -eseguita da un programma con \textsl{uid} reale zero; in tal caso il programma -ottiene tutte le \textit{capabilities} presenti nel \textit{capabilities - bounding set}. In questo modo si può far si che ad un processo eseguito in -un secondo tempo possano essere trasmesse solo un insieme limitato di -capacità, impedendogli di recuperare quelle assenti nell'insieme -\textit{inherited}. +\begin{table}[htb] + \centering + \footnotesize + \begin{tabular}{|l|p{10cm}|} + \hline + \textbf{Flag} & \textbf{Descrizione} \\ + \hline + \hline + \const{SECURE\_KEEP\_CAPS}& Il processo non subisce la cancellazione delle + sue \textit{capabilities} quando tutti i suoi + \textit{user-ID} passano ad un valore non + nullo (regola di compatibilità per il cambio + di \textit{user-ID} n. 3 del precedente + elenco), sostituisce il precedente uso + dell'operazione \const{PR\_SET\_KEEPCAPS} di + \func{prctl}.\\ + \const{SECURE\_NO\_SETUID\_FIXUP}&Il processo non subisce le modifiche + delle sue \textit{capabilities} nel passaggio + da nullo a non nullo degli \textit{user-ID} + dei gruppi \textit{effective} e + \textit{file system} (regole di compatibilità + per il cambio di \textit{user-ID} nn. 1 e 2 del + precedente elenco).\\ + \const{SECURE\_NOROOT} & Il processo non assume nessuna capacità + aggiuntiva quando esegue un programma, anche + se ha \textit{user-ID} nullo o il programma ha + il \acr{suid} bit attivo ed appartiene + all'amministratore (regola di compatibilità + per l'esecuzione di programmi senza + \textit{capabilities}).\\ + \hline + \end{tabular} + \caption{Costanti identificative dei flag che compongono la maschera dei + \textit{securebits}.} + \label{tab:securebits_values} +\end{table} +A ciascuno dei flag di tab.~\ref{tab:securebits_values} è inoltre abbinato un +corrispondente flag di blocco, identificato da una costante omonima con +l'estensione \texttt{\_LOCKED}, la cui attivazione è irreversibile ed ha +l'effetto di rendere permanente l'impostazione corrente del corrispondente +flag ordinario; in sostanza con \const{SECURE\_KEEP\_CAPS\_LOCKED} si rende +non più modificabile \const{SECURE\_KEEP\_CAPS}, ed analogamente avviene con +\const{SECURE\_NO\_SETUID\_FIXUP\_LOCKED} per +\const{SECURE\_NO\_SETUID\_FIXUP} e con \const{SECURE\_NOROOT\_LOCKED} per +\const{SECURE\_NOROOT}. + +Per l'impostazione di questi flag sono stata predisposte due specifiche +operazioni di \func{prctl} (vedi sez.~\ref{sec:process_prctl}), +\const{PR\_GET\_SECUREBITS}, che consente di ottenerne il valore, e +\const{PR\_SET\_SECUREBITS}, che consente di modificarne il valore; per +quest'ultima sono comunque necessari i privilegi di amministratore ed in +particolare la capacità \const{CAP\_SETPCAP}. Prima dell'introduzione dei +\textit{securebits} era comunque possibile ottenere lo stesso effetto di +\const{SECURE\_KEEP\_CAPS} attraverso l'uso di un'altra operazione di +\func{prctl}, \const{PR\_SET\_KEEPCAPS}. + +\itindend{securebits} + +Oltre alla gestione dei \textit{securebits} la nuova versione delle +\textit{file capabilities} prevede l'uso di \func{prctl} anche per la gestione +del \textit{capabilities bounding set}, attraverso altre due operazioni +dedicate, \const{PR\_CAPBSET\_READ} per controllarne il valore e +\const{PR\_CAPBSET\_DROP} per modificarlo; quest'ultima di nuovo è una +operazione privilegiata che richiede la capacità \const{CAP\_SETPCAP} e che, +come indica chiaramente il nome, permette solo la rimozione di una +\textit{capability} dall'insieme; per i dettagli sull'uso di tutte queste +operazioni si rimanda alla rilettura di sez.~\ref{sec:process_prctl}. % TODO verificare per process capability bounding set, vedi: % http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=3b7391de67da515c91f48aa371de77cb6cc5c07e @@ -5656,14 +5763,14 @@ programmi e librerie) di cui il server potrebbe avere bisogno. % LocalWords: INDENT major number IDE Documentation makedev proc copy LNK long % LocalWords: euidaccess eaccess delete def tag qualifier permset calendar NOW % LocalWords: mutt noatime relatime strictatime atim nsec mtim ctim atimensec -% LocalWords: mtimensec utimes timeval futimes lutimes ENOSYS futimens OMIT +% LocalWords: mtimensec utimes timeval futimes lutimes ENOSYS futimens OMIT PR % LocalWords: utimensat timespec sec futimesat LIDS DAC OVERRIDE SEARCH chattr % LocalWords: Discrectionary KILL SETGID domain SETUID setuid setreuid SETPCAP % LocalWords: setresuid setfsuid IMMUTABLE immutable append only BIND SERVICE % LocalWords: BROADCAST broadcast multicast multicasting RAW PACKET IPC LOCK % LocalWords: memory mlock mlockall shmctl mmap MODULE RAWIO ioperm iopl PACCT -% LocalWords: ptrace accounting NICE RESOURCE TTY CONFIG hangup vhangup -% LocalWords: LEASE lease SETFCAP AUDIT permitted inherited inheritable AND +% LocalWords: ptrace accounting NICE RESOURCE TTY CONFIG hangup vhangup dell' +% LocalWords: LEASE lease SETFCAP AUDIT permitted inherited inheritable AND nn % LocalWords: bounding execve fork capget capset header hdrp datap ESRCH undef % LocalWords: version libcap lcap clear ncap caps pag capgetp CapInh CapPrm % LocalWords: fffffeff CapEff getcap scheduling lookup dqinfo SETINFO GETFMT @@ -5675,7 +5782,8 @@ programmi e librerie) di cui il server potrebbe avere bisogno. % LocalWords: REALTIME securebits GETSTATS QFMT curspace curinodes btime itime % LocalWords: QIF BLIMITS bhardlimit bsoftlimit ILIMITS ihardlimit isoftlimit % LocalWords: INODES LIMITS USAGE valid dqi IIF BGRACE bgrace IGRACE igrace -% LocalWords: Python Truelite Srl quotamodule Repository who +% LocalWords: Python Truelite Srl quotamodule Repository who nell' dall' KEEP +% LocalWords: SECURE KEEPCAPS prctl FIXUP NOROOT LOCKED dell'IPC dell'I %%% Local Variables: %%% mode: latex diff --git a/process.tex b/process.tex index 2918deb..eba8b3c 100644 --- a/process.tex +++ b/process.tex @@ -760,7 +760,7 @@ funzioni di allocazione della memoria. Per poterle utilizzare è necessario definire una della macro di funzionalità (vedi sez.~\ref{sec:intro_gcc_glibc_std}) fra \macro{\_BSD\_SOURCE}, \macro{\_SVID\_SOURCE} e \macro{\_XOPEN\_SOURCE} (ad un valore maggiore o -ugiale di 500). La prima funzione è \funcd{brk}, ed il suo prototipo è: +uguale di 500). La prima funzione è \funcd{brk}, ed il suo prototipo è: \begin{prototype}{unistd.h}{int brk(void *end\_data\_segment)} Sposta la fine del segmento dei dati. @@ -1071,7 +1071,7 @@ buffer sia un multiplo intero di questa dimensione, usualmente 512 byte. In tal caso l'uso di \func{malloc} non è sufficiente, ed occorre utilizzare una funzione specifica. -Tradizionalmente per rispondere a questa esigenza sono state crate due +Tradizionalmente per rispondere a questa esigenza sono state create due funzioni diverse, \funcd{memalign} e \funcd{valloc}, oggi obsolete; i rispettivi prototipi sono: \begin{functions} @@ -1104,7 +1104,7 @@ Nessuna delle due funzioni ha una chiara standardizzazione (nessuna delle due compare in POSIX.1), ed inoltre ci sono indicazioni discordi sui file che ne contengono la definizione;\footnote{secondo SUSv2 \func{valloc} è definita in \texttt{stdlib.h}, mentre sia le \acr{glibc} che le precedenti \acr{libc4} e - \acr{lic5} la dichiarano in \texttt{malloc.h}, lo stesso vale per + \acr{libc5} la dichiarano in \texttt{malloc.h}, lo stesso vale per \func{memalign} che in alcuni sistemi è dichiarata in \texttt{stdlib.h}.} per questo motivo il loro uso è sconsigliato, essendo state sostituite dalla nuova \funcd{posix\_memalign}, che è stata standardizzata in POSIX.1d; il suo @@ -1206,12 +1206,12 @@ tab.~\ref{tab:mcheck_status_value}. buffer.\\ \macro{MCHECK\_TAIL} & i dati immediatamente seguenti il buffer sono stati modificati, succede quando si va scrivere - oltre la dimensione correttta del buffer.\\ + oltre la dimensione corretta del buffer.\\ \macro{MCHECK\_FREE} & il buffer è già stato disallocato.\\ \hline \end{tabular} \caption{Valori dello stato dell'allocazione di memoria ottenibili dalla - funzione di teminazione installata con \func{mcheck}.} + funzione di terminazione installata con \func{mcheck}.} \label{tab:mcheck_status_value} \end{table} @@ -1438,7 +1438,7 @@ terminata da un puntatore nullo. L'indirizzo della lista delle variabili di ambiente è passato attraverso la variabile globale \var{environ}, che viene definita automaticamente per -cisascun processo, e a cui si può accedere attraverso una semplice +ciascun processo, e a cui si può accedere attraverso una semplice dichiarazione del tipo: \includecodesnip{listati/env_ptr.c} un esempio della struttura di questa lista, contenente alcune delle variabili @@ -1481,7 +1481,7 @@ fig.~\ref{fig:proc_envirno_list}. Per convenzione le stringhe che definiscono l'ambiente sono tutte del tipo \textsl{\texttt{nome=valore}} ed in questa forma che le funzioni di gestione che vedremo a breve se le aspettano, se pertanto si dovesse costruire -manualemente un ambiente si abbia cura di rispettare questa convenzione. +manualmente un ambiente si abbia cura di rispettare questa convenzione. Inoltre alcune variabili, come quelle elencate in fig.~\ref{fig:proc_envirno_list}, sono definite dal sistema per essere usate da diversi programmi e funzioni: per queste c'è l'ulteriore convenzione di @@ -2097,13 +2097,123 @@ dichiarandole tutte come \direct{volatile}.\footnote{la direttiva \index{salto~non-locale|)} +\subsection{La \textit{endianess}} +\label{sec:sock_endianess} + +\itindbeg{endianess} + +Uno dei problemi di programmazione che può dar luogo ad effetti imprevisti è +quello relativo alla cosiddetta \textit{endianess}. Questa è una +caratteristica generale dell'architettura hardware di un computer che dipende +dal fatto che la rappresentazione di un numero binario può essere fatta in due +modi, chiamati rispettivamente \textit{big endian} e \textit{little endian} a +seconda di come i singoli bit vengono aggregati per formare le variabili +intere (ed in genere in diretta corrispondenza a come sono poi in realtà +cablati sui bus interni del computer). + +\begin{figure}[htb] + \centering + \includegraphics[height=3cm]{img/endianess} + \caption{Schema della disposizione dei dati in memoria a seconda della + \textit{endianess}.} + \label{fig:sock_endianess} +\end{figure} + +Per capire meglio il problema si consideri un intero a 32 bit scritto in una +locazione di memoria posta ad un certo indirizzo. Come illustrato in +fig.~\ref{fig:sock_endianess} i singoli bit possono essere disposti in memoria +in due modi: a partire dal più significativo o a partire dal meno +significativo. Così nel primo caso si troverà il byte che contiene i bit più +significativi all'indirizzo menzionato e il byte con i bit meno significativi +nell'indirizzo successivo; questo ordinamento è detto \textit{big endian}, +dato che si trova per prima la parte più grande. Il caso opposto, in cui si +parte dal bit meno significativo è detto per lo stesso motivo \textit{little + endian}. + +Si può allora verificare quale tipo di \textit{endianess} usa il proprio +computer con un programma elementare che si limita ad assegnare un valore ad +una variabile per poi ristamparne il contenuto leggendolo un byte alla volta. +Il codice di detto programma, \file{endtest.c}, è nei sorgenti allegati, +allora se lo eseguiamo su un normale PC compatibile, che è \textit{little + endian} otterremo qualcosa del tipo: +\begin{verbatim} +[piccardi@gont sources]$ ./endtest +Using value ABCDEF01 +val[0]= 1 +val[1]=EF +val[2]=CD +val[3]=AB +\end{verbatim}%$ +mentre su un vecchio Macintosh con PowerPC, che è \textit{big endian} avremo +qualcosa del tipo: +\begin{verbatim} +piccardi@anarres:~/gapil/sources$ ./endtest +Using value ABCDEF01 +val[0]=AB +val[1]=CD +val[2]=EF +val[3]= 1 +\end{verbatim}%$ + +L'attenzione alla \textit{endianess} nella programmazione è importante, perché +se si fanno assunzioni relative alla propria architettura non è detto che +queste restino valide su un'altra architettura. Inoltre, come vedremo ad +esempio in sez.~\ref{sec:sock_addr_func}, si possono avere problemi quando ci +si trova a usare valori di un formato con una infrastruttura che ne usa +un altro. + +La \textit{endianess} di un computer dipende essenzialmente dalla architettura +hardware usata; Intel e Digital usano il \textit{little endian}, Motorola, +IBM, Sun (sostanzialmente tutti gli altri) usano il \textit{big endian}. Il +formato dei dati contenuti nelle intestazioni dei protocolli di rete (il +cosiddetto \textit{network order} è anch'esso \textit{big endian}; altri +esempi di uso di questi due diversi formati sono quello del bus PCI, che è +\textit{little endian}, o quello del bus VME che è \textit{big endian}. + +Esistono poi anche dei processori che possono scegliere il tipo di formato +all'avvio e alcuni che, come il PowerPC o l'Intel i860, possono pure passare +da un tipo di ordinamento all'altro con una specifica istruzione. In ogni caso +in Linux l'ordinamento è definito dall'architettura e dopo l'avvio del sistema +in genere resta sempre lo stesso,\footnote{su architettura PowerPC è possibile + cambiarlo, si veda sez.~\ref{sec:process_prctl}.} anche quando il processore +permetterebbe di eseguire questi cambiamenti. + +\begin{figure}[htb] + \footnotesize \centering + \begin{minipage}[c]{15cm} + \includecodesample{listati/endian.c} + \end{minipage} + \normalsize + \caption{La funzione \func{endian}, usata per controllare il tipo di + architettura della macchina.} + \label{fig:sock_endian_code} +\end{figure} + +Per controllare quale tipo di ordinamento si ha sul proprio computer si è +scritta una piccola funzione di controllo, il cui codice è riportato +fig.~\ref{fig:sock_endian_code}, che restituisce un valore nullo (falso) se +l'architettura è \textit{big endian} ed uno non nullo (vero) se l'architettura +è \textit{little endian}. + +Come si vede la funzione è molto semplice, e si limita, una volta assegnato +(\texttt{\small 9}) un valore di test pari a \texttt{0xABCD} ad una variabile +di tipo \ctyp{short} (cioè a 16 bit), a ricostruirne una copia byte a byte. +Per questo prima (\texttt{\small 10}) si definisce il puntatore \var{ptr} per +accedere al contenuto della prima variabile, ed infine calcola (\texttt{\small + 11}) il valore della seconda assumendo che il primo byte sia quello meno +significativo (cioè, per quanto visto in fig.~\ref{fig:sock_endianess}, che sia +\textit{little endian}). Infine la funzione restituisce (\texttt{\small 12}) +il valore del confronto delle due variabili. +\itindend{endianess} + + % LocalWords: like exec kernel thread main ld linux static linker char envp Gb % LocalWords: sez POSIX exit system call cap abort shell diff errno stdlib int % LocalWords: SUCCESS FAILURE void atexit stream fclose unistd descriptor init % LocalWords: SIGCHLD wait function glibc SunOS arg argp execve fig high kb Mb % LocalWords: memory alpha swap table printf Unit MMU paging fault SIGSEGV BSS -% LocalWords: multitasking text segment NULL Block Started Symbol +% LocalWords: multitasking text segment NULL Block Started Symbol fill black % LocalWords: heap stack calling convention size malloc calloc realloc nmemb % LocalWords: ENOMEM ptr uClib cfree error leak smartpointers hook Dmalloc brk % LocalWords: Gray Watson Electric Fence Bruce Perens sbrk longjmp SUSv BSD ap @@ -2117,8 +2227,14 @@ dichiarandole tutte come \direct{volatile}.\footnote{la direttiva % LocalWords: clearenv libc value overwrite string reference result argument % LocalWords: socket variadic ellipsis header stdarg execl self promoting last % LocalWords: float double short register type dest src extern setjmp jmp buf -% LocalWords: env return if while Di page cdecl -% LocalWords: environment +% LocalWords: env return if while Di page cdecl rectangle node anchor west PS +% LocalWords: environment rounded corners dashed south width height draw east +% LocalWords: exithandler handler violation inline SOURCE SVID XOPEN mincore +% LocalWords: length unsigned vec EFAULT EAGAIN dell'I memalign valloc posix +% LocalWords: boundary memptr alignment sizeof overrun mcheck abortfn enum big +% LocalWords: mprobe DISABLED HEAD TAIL touch right emacs OSTYPE endianess IBM +% LocalWords: endian little endtest Macintosh PowerPC Intel Digital Motorola +% LocalWords: Sun order VME %%% Local Variables: %%% mode: latex diff --git a/prochand.tex b/prochand.tex index be5e976..8d7487b 100644 --- a/prochand.tex +++ b/prochand.tex @@ -138,7 +138,7 @@ fig.~\ref{fig:proc_task_struct}. \begin{figure}[htb] \centering - \includegraphics[width=12cm]{img/task_struct} + \includegraphics[width=14cm]{img/task_struct} \caption{Schema semplificato dell'architettura delle strutture usate dal kernel nella gestione dei processi.} \label{fig:proc_task_struct} @@ -868,8 +868,7 @@ terminare il processo che li ha generati, in modo che \cmd{init} possa adottarli e provvedere a concluderne la terminazione. -\subsection{La funzione \func{waitpid} e le funzioni di ricezione degli stati - di uscita} +\subsection{Le funzioni di attesa e ricezione degli stati di uscita} \label{sec:proc_wait} Uno degli usi più comuni delle capacità multitasking di un sistema unix-like @@ -878,8 +877,8 @@ principale attende le richieste che vengono poi soddisfatte da una serie di processi figli. Si è già sottolineato al paragrafo precedente come in questo caso diventi necessario gestire esplicitamente la conclusione dei figli onde evitare di riempire di \index{zombie} \textit{zombie} la tabella dei processi; -le funzioni deputate a questo compito sono principalmente due, \funcd{wait} e -\func{waitpid}. La prima, il cui prototipo è: +le funzioni deputate a questo compito sono principalmente due, la prima è +\funcd{wait} ed il suo prototipo è: \begin{functions} \headdecl{sys/types.h} \headdecl{sys/wait.h} @@ -895,16 +894,20 @@ segnale termina il processo o chiama una funzione di gestione. \end{errlist}} \end{functions} \noindent -è presente fin dalle prime versioni di Unix; la funzione ritorna non appena un -processo figlio termina. Se un figlio è già terminato la funzione ritorna -immediatamente, se più di un figlio è terminato occorre chiamare la funzione -più volte se si vuole recuperare lo stato di terminazione di tutti quanti. + +Questa funzione è presente fin dalle prime versioni di Unix; essa ritorna non +appena un qualunque processo figlio termina. Se un figlio è già terminato +prima della chiamata la funzione ritorna immediatamente, se più di un figlio è +già terminato occorre continuare chiamare la funzione più volte se si vuole +recuperare lo stato di terminazione di tutti quanti. Al ritorno della funzione lo stato di terminazione del figlio viene salvato nella variabile puntata da \param{status} e tutte le risorse del kernel -relative al processo (vedi sez.~\ref{sec:proc_termination}) vengono rilasciate. -Nel caso un processo abbia più figli il valore di ritorno (il \acr{pid} del -figlio) permette di identificare qual è quello che è uscito. +relative al processo (vedi sez.~\ref{sec:proc_termination}) vengono +rilasciate. Nel caso un processo abbia più figli il valore di ritorno della +funzione sarà impostato al \acr{pid} del processo di cui si è ricevuto lo +stato di terminazione, cosa che permette di identificare qual è il figlio che +è terminato. Questa funzione ha il difetto di essere poco flessibile, in quanto ritorna all'uscita di un qualunque processo figlio. Nelle occasioni in cui è @@ -913,14 +916,14 @@ predisporre un meccanismo che tenga conto dei processi già terminati, e provvedere a ripetere la chiamata alla funzione nel caso il processo cercato sia ancora attivo. -Per questo motivo lo standard POSIX.1 ha introdotto la funzione -\funcd{waitpid} che effettua lo stesso servizio, ma dispone di una serie di -funzionalità più ampie, legate anche al controllo di sessione (si veda +Per questo motivo lo standard POSIX.1 ha introdotto una seconda funzione che +effettua lo stesso servizio, ma dispone di una serie di funzionalità più +ampie, legate anche al controllo di sessione (si veda sez.~\ref{sec:sess_job_control}). Dato che è possibile ottenere lo stesso comportamento di \func{wait}\footnote{in effetti il codice \code{wait(\&status)} è del tutto equivalente a \code{waitpid(WAIT\_ANY, - \&status, 0)}.} si consiglia di utilizzare sempre questa funzione, il cui -prototipo è: + \&status, 0)}.} si consiglia di utilizzare sempre questa nuova funzione, +\funcd{waitpid}, il cui prototipo è: \begin{functions} \headdecl{sys/types.h} \headdecl{sys/wait.h} @@ -3283,9 +3286,12 @@ rimosso a partire dal kernel 2.6.25. Nelle precedenti sezioni si sono trattate la gran parte delle funzioni che attengono alla gestione ordinaria dei processi e delle loro proprietà più -comuni. Tratteremo qui alcune \textit{system call} specialistiche dedicate -alla gestione di alcune funzionalità specifiche ed avanzate il cui uso è in -genere piuttosto ridotto. +comuni. Tratteremo qui alcune \textit{system call} dedicate alla gestione di +funzionalità dei processi molto specifiche ed avanzate, il cui uso è in genere +piuttosto ridotto. Trattandosi di problematiche relativamente complesse, che +spesso presuppongono la conoscenza di altri argomenti trattati più avanti +nella guida, si può saltare questa lezione ad una prima lettura, tornando su +di essa in un secondo tempo. \subsection{La system call \func{clone}} \label{sec:process_clone} @@ -3295,7 +3301,122 @@ Da fare \subsection{La funzione \func{prctl}} \label{sec:process_prctl} -Da fare +Benché la gestione ordinaria possa essere effettuata attraverso le funzioni +che abbiamo già esaminato nelle sezioni precedenti, esistono una serie di +proprietà e caratteristiche particolari dei processi non coperte da esse, per +la cui gestione è stata predisposta una apposita \textit{system call} che +fornisce una interfaccia generica per tutte le operazioni specialistiche. La +funzione è \funcd{prctl} ed il suo prototipo è:\footnote{la funzione non è + standardizzata ed è specifica di Linux, anche se ne esiete una analoga in + IRIX, è stata introdotta con il kernel 2.1.57.} +\begin{functions} + \headdecl{sys/prctl.h} + + \funcdecl{int prctl(int option, unsigned long arg2, unsigned long arg3, + unsigned long arg4, unsigned long arg5)} + + Esegue una operazione speciale sul processo corrente. + + \bodydesc{La funzione ritorna 0 o un valore positivo dipendente + dall'operazione in caso di successo e $-1$ in caso di errore, nel qual + caso \var{errno} assumerà valori diversi a seconda del tipo di operazione + richiesta (in genere \errval{EINVAL} o \errval{EPERM}). } +\end{functions} + +La funzione ritorna un valore nullo o positivo in caso di successo e $-1$ in +caso di errore; il significato degli argomenti della funzione successivi al +primo, il valore di ritorno in caso di successo, il tipo di errore restituito +in \var{errno} dipendono dall'operazione eseguita, indicata tramite il primo +argomento, \param{option}. Questo è un valore intero che identifica +l'operazione, e deve essere specificato con l'uso di una delle costanti +predefinite del seguente elenco, che illustra quelle disponibili al momento: + +\begin{basedescript}{\desclabelstyle{\pushlabel}} +\item[\const{PR\_CAPBSET\_READ}] Controlla la disponibilità di una delle + \textit{capabilities} (vedi sez.~\ref{sec:proc_capabilities}). La funzione + ritorna 1 se la capacità specificata nell'argomento \param{arg2} (con una + delle costanti di tab.~\ref{tab:proc_capabilities}) è presente nel + \textit{capabilities bounding set} del processo e zero altrimenti, + se \param{arg2} non è un valore valido si avrà un errore di \errval{EINVAL}. + Introdotta a partire dal kernel 2.6.25. +\item[\const{PR\_CAPBSET\_DROP}] Rimuove permanentemente una delle + \textit{capabilities} (vedi sez.~\ref{sec:proc_capabilities}) dal processo e + da tutti i suoi discendenti. La funzione cancella la capacità specificata + nell'argomento \param{arg2} con una delle costanti di + tab.~\ref{tab:proc_capabilities} dal \textit{capabilities bounding set} del + processo. L'operazione richiede i privilegi di amministratore (la capacità + \const{CAP\_SETPCAP}), altrimenti fallisce con un errore di \errval{EPERM}; + se il valore di \param{arg2} non è valido o se il supporto per le + \textit{file capabilities} non è stato compilato nel kernel fallisce con un + errore di \errval{EINVAL}. Introdotta a partire dal kernel 2.6.25. +\item[\const{PR\_SET\_DUMPABLE}] Imposta il flag che determina se la + terminazione di un processo a causa di un segnale per il quale è prevista la + generazione di un file di \itindex{core~dump} \textit{core dump} (vedi + sez.~\ref{sec:sig_standard}) lo genera effettivamente. In genere questo flag + viene attivato automaticamente, ma per evitare problemi di sicurezza (la + generazione di un file da parte di processi privilegiati può essere usata + per sovrascriverne altri) viene cancellato quando si mette in esecuzione un + programma con i bit \acr{suid} e \acr{sgid} attivi (vedi + sez.~\ref{sec:file_special_perm}) o con l'uso delle funzioni per la modifica + degli \textit{user-ID} dei processi (vedi + sez.~\ref{sec:proc_setuid}). L'operazione è stata introdotta a partire dal + kernel 2.3.20, fino al kernel 2.6.12 e per i kernel successivi al 2.6.17 era + possibile usare solo un valore 0 di \param{arg2} per disattivare il flag ed + un valore 1 per attivarlo, nei kernel dal 2.6.13 al 2.6.17 è stato + supportato anche il valore 2 che causava la generazione di un + \itindex{core~dump} \textit{core dump} leggibile solo + dall'amministratore.\footnote{la funzionalità è stata rimossa per motivi di + sicurezza, in quanto consentiva ad un utente normale di creare un file di + \textit{core dump} appartenente all'amministratore in directory dove + l'utente avrebbe avuto permessi di accesso.} +\item[\const{PR\_GET\_DUMPABLE}] Ottiene come valore di ritorno della funzione + lo stato corrente del flag che controlla la effettiva generazione dei + \itindex{core~dump} \textit{core dump}. Introdotta a partire dal kernel + 2.3.20. +\item[\const{PR\_SET\_ENDIAN}] Imposta la \textit{endianess} del processo + chiamante secondo il valore fornito in \param{arg2}. I valori possibili sono + sono: \const{PR\_ENDIAN\_BIG} (\textit{big endian}), + \const{PR\_ENDIAN\_LITTLE} (\textit{little endian}), e + \const{PR\_ENDIAN\_PPC\_LITTLE} (lo pseudo \textit{little endian} del + PowerPC) Introdotta a partire dal kernel 2.6.18, solo per architettura + PowerPC. +\item[\const{PR\_GET\_ENDIAN}] Ottiene il valore della \textit{endianess} del + processo chiamante, salvato sulla variabile puntata da \param{arg2} che deve + essere passata come di tipo \type{(int *)}. Introdotta a partire dal kernel + 2.6.18, solo su PowerPC. +\item[\const{PR\_SET\_FPEMU}] Introdotta a partire dal kernel 2.4.18, solo su + ia64. +\item[\const{PR\_GET\_FPEMU}] Introdotta a partire dal kernel 2.4.18, solo su + ia64. +\item[\const{PR\_SET\_FPEXC}] Introdotta a partire dal kernel 2.4.21, solo su + PowerPC. +\item[\const{PR\_GET\_FPEXC}] Introdotta a partire dal kernel 2.4.21, solo su + PowerPC. +\item[\const{PR\_SET\_KEEPCAPS}] Introdotta a partire dal kernel 2.2.18. +\item[\const{PR\_GET\_KEEPCAPS}] Introdotta a partire dal kernel 2.2.18. +\item[\const{PR\_SET\_NAME}] Introdotta a partire dal kernel 2.6.9. +\item[\const{PR\_GET\_NAME}] Introdotta a partire dal kernel 2.6.9. +\item[\const{PR\_SET\_PDEATHSIG}] Introdotta a partire dal kernel 2.1.57. +\item[\const{PR\_GET\_PDEATHSIG}] Introdotta a partire dal kernel 2.3.15. +\item[\const{PR\_SET\_SECCOMP}] Introdotta a partire dal kernel 2.6.23. +\item[\const{PR\_GET\_SECCOMP}] Introdotta a partire dal kernel 2.6.23. +\item[\const{PR\_SET\_SECUREBITS}] Introdotta a partire dal kernel 2.6.26. +\item[\const{PR\_GET\_SECUREBITS}] Introdotta a partire dal kernel 2.6.26. +\item[\const{PR\_SET\_TIMING}] Introdotta a partire dal kernel 2.6.0-test4. +\item[\const{PR\_GET\_TIMING}] Introdotta a partire dal kernel 2.6.0-test4. +\item[\const{PR\_SET\_TSC}] Introdotta a partire dal kernel 2.6.26, solo su + x86. +\item[\const{PR\_GET\_TSC}] Introdotta a partire dal kernel 2.6.26, solo su + x86. +\item[\const{PR\_SET\_UNALIGN}] Introdotta con diverse versioni su diverse + architetture. +\item[\const{PR\_GET\_UNALIGN}] Introdotta con diverse versioni su diverse + architetture. +\label{sec:prctl_operation} +\end{basedescript} + + + \subsection{La funzione \func{ptrace}} \label{sec:process_ptrace} diff --git a/socket.tex b/socket.tex index c026305..b8538ab 100644 --- a/socket.tex +++ b/socket.tex @@ -488,10 +488,11 @@ tab.~\ref{tab:TCP_ipv4_addr}, che rincontreremo più avanti. Infine occorre sottolineare che sia gli indirizzi che i numeri di porta devono essere specificati in quello che viene chiamato \textit{network order}, cioè -con i bit ordinati in formato \textit{big endian}, questo comporta la -necessità di usare apposite funzioni di conversione per mantenere la -portabilità del codice (vedi sez.~\ref{sec:sock_addr_func} per i dettagli del -problema e le relative soluzioni). +con i bit ordinati in formato \textit{big endian} (vedi +sez.~\ref{sec:sock_endianess}), questo comporta la necessità di usare apposite +funzioni di conversione per mantenere la portabilità del codice (vedi +sez.~\ref{sec:sock_addr_func} per i dettagli del problema e le relative +soluzioni). \subsection{La struttura degli indirizzi IPv6} @@ -742,120 +743,23 @@ lunghezza effettiva del pacchetto così come arrivato sulla linea. In questa sezione tratteremo delle varie funzioni usate per manipolare gli indirizzi, limitandoci però agli indirizzi internet. Come accennato gli -indirizzi e i numeri di porta usati nella rete devono essere forniti in -formato opportuno (il \textit{network order}). Per capire cosa significa tutto -ciò occorre introdurre un concetto generale che tornerà utile anche in -seguito. - - -\subsection{La \textit{endianess}} -\label{sec:sock_endianess} - -\itindbeg{endianess} -La rappresentazione di un numero binario in un computer può essere fatta in -due modi, chiamati rispettivamente \textit{big endian} e \textit{little - endian} a seconda di come i singoli bit vengono aggregati per formare le -variabili intere (ed in genere in diretta corrispondenza a come sono poi in -realtà cablati sui bus interni del computer). - -\begin{figure}[htb] - \centering - \includegraphics[height=3cm]{img/endianess} - \caption{Schema della disposizione dei dati in memoria a seconda della - \textit{endianess}.} - \label{fig:sock_endianess} -\end{figure} - -Per capire meglio il problema si consideri un intero a 32 bit scritto in una -locazione di memoria posta ad un certo indirizzo. Come illustrato in -fig.~\ref{fig:sock_endianess} i singoli bit possono essere disposti in memoria -in due modi: a partire dal più significativo o a partire dal meno -significativo. Così nel primo caso si troverà il byte che contiene i bit più -significativi all'indirizzo menzionato e il byte con i bit meno significativi -nell'indirizzo successivo; questo ordinamento è detto \textit{big endian}, -dato che si trova per prima la parte più grande. Il caso opposto, in cui si -parte dal bit meno significativo è detto per lo stesso motivo \textit{little - endian}. - -Si può allora verificare quale tipo di \textit{endianess} usa il proprio -computer con un programma elementare che si limita ad assegnare un valore ad -una variabile per poi ristamparne il contenuto leggendolo un byte alla volta. -Il codice di detto programma, \file{endtest.c}, è nei sorgenti allegati, -allora se lo eseguiamo su un PC otterremo: -\begin{verbatim} -[piccardi@gont sources]$ ./endtest -Using value ABCDEF01 -val[0]= 1 -val[1]=EF -val[2]=CD -val[3]=AB -\end{verbatim}%$ -mentre su di un Mac avremo: -\begin{verbatim} -piccardi@anarres:~/gapil/sources$ ./endtest -Using value ABCDEF01 -val[0]=AB -val[1]=CD -val[2]=EF -val[3]= 1 -\end{verbatim}%$ - - -La \textit{endianess} di un computer dipende essenzialmente dalla architettura -hardware usata; Intel e Digital usano il \textit{little endian}, Motorola, -IBM, Sun (sostanzialmente tutti gli altri) usano il \textit{big endian}. Il -formato dei dati contenuti nelle intestazioni dei protocolli di rete è -anch'esso \textit{big endian}; altri esempi di uso di questi due diversi -formati sono quello del bus PCI, che è \textit{little endian}, o quello del -bus VME che è \textit{big endian}. - -Esistono poi anche dei processori che possono scegliere il tipo di formato -all'avvio e alcuni che, come il PowerPC o l'Intel i860, possono pure passare -da un tipo di ordinamento all'altro con una specifica istruzione. In ogni caso -in Linux l'ordinamento è definito dall'architettura e dopo l'avvio del sistema -resta sempre lo stesso, anche quando il processore permetterebbe di eseguire -questi cambiamenti. - -\begin{figure}[htb] - \footnotesize \centering - \begin{minipage}[c]{15cm} - \includecodesample{listati/endian.c} - \end{minipage} - \normalsize - \caption{La funzione \func{endian}, usata per controllare il tipo di - architettura della macchina.} - \label{fig:sock_endian_code} -\end{figure} - -Per controllare quale tipo di ordinamento si ha sul proprio computer si è -scritta una piccola funzione di controllo, il cui codice è riportato -fig.~\ref{fig:sock_endian_code}, che restituisce un valore nullo (falso) se -l'architettura è \textit{big endian} ed uno non nullo (vero) se l'architettura -è \textit{little endian}. - -Come si vede la funzione è molto semplice, e si limita, una volta assegnato -(\texttt{\small 9}) un valore di test pari a \texttt{0xABCD} ad una variabile -di tipo \ctyp{short} (cioè a 16 bit), a ricostruirne una copia byte a byte. -Per questo prima (\texttt{\small 10}) si definisce il puntatore \var{ptr} per -accedere al contenuto della prima variabile, ed infine calcola (\texttt{\small - 11}) il valore della seconda assumendo che il primo byte sia quello meno -significativo (cioè, per quanto visto in fig.~\ref{fig:sock_endianess}, che sia -\textit{little endian}). Infine la funzione restituisce (\texttt{\small 12}) -il valore del confronto delle due variabili. -\itindend{endianess} - +indirizzi e i numeri di porta usati nella rete devono essere forniti nel +cosiddetto \textit{network order}, che corrisponde al formato \textit{big + endian}, anche quando la proprio macchina non usa questo formati, cosa che +può comportare la necessità di eseguire delle conversioni. \subsection{Le funzioni per il riordinamento} \label{sec:sock_func_ord} -Il problema connesso \itindex{endianess} all'endianess è che quando si passano -dei dati da un tipo di architettura all'altra i dati vengono interpretati in -maniera diversa, e ad esempio nel caso dell'intero a 16 bit ci si ritroverà -con i due byte in cui è suddiviso scambiati di posto. Per questo motivo si -usano delle funzioni di conversione che servono a tener conto automaticamente -della possibile differenza fra l'ordinamento usato sul computer e quello che -viene usato nelle trasmissione sulla rete; queste funzioni sono \funcd{htonl}, +Come già visto in sez.~\ref{sec:sock_endianess} il problema connesso +\itindex{endianess} all'\textit{endianess} è che quando si passano dei dati da +un tipo di architettura all'altra i dati vengono interpretati in maniera +diversa, e ad esempio nel caso dell'intero a 16 bit ci si ritroverà con i due +byte in cui è suddiviso scambiati di posto. Per questo motivo si usano delle +funzioni di conversione che servono a tener conto automaticamente della +possibile differenza fra l'ordinamento usato sul computer e quello che viene +usato nelle trasmissione sulla rete; queste funzioni sono \funcd{htonl}, \funcd{htons}, \funcd{ntohl} e \funcd{ntohs} ed i rispettivi prototipi sono: \begin{functions} \headdecl{netinet/in.h}