6.2 Android Native Development Kit
8.1.1 Modifiche al codice sorgente
A causa delle numerose differenze esistenti tra la libreria standard C (GNU C Library) sulla quale umView si basa, e la sua implementazione per Android (Bionic), `e stato necessario apportare alcune modifiche ai sor- genti della virtual machine; in Bionic non sono presenti infatti alcuni header e implementazioni di funzioni indispensabili per la corretta esecuzione di um- View; nel seguente paragrafo saranno dunque descritte le modifiche apportate ai sorgenti e le funzionalit`a introdotte per ovviare a questo problema.
Header implementati
Un header non presente in Android ma necessario all’interno di umView `e
wordsize.hutilizzato nel sorgentetreepoch.c, in cui `e indicata la dimensione
di una word in base all’architettura di riferimento.
/* D e t e r m i n e the w o r d s i z e f r o m the p r e p r o c e s s o r d e f i n e s */ # if d e f i n e d _ _ x 8 6 _ 6 4 _ _ # d e f i n e _ _ W O R D S I Z E 64 # d e f i n e _ _ W O R D S I Z E _ C O M P A T 3 2 1 # e l s e # d e f i n e _ _ W O R D S I Z E 32 # e n d i f
Nel fileum_plusio.c`e presente inoltre un riferimento alla strutturastatfs64
definita, all’interno della GNU C Library, nell’header bits/statfs.h; Bionic
non ne fornisce un’implementazione indicando tuttavia, nel file$NDK/platforms /android-14/arch-x86/usr/include/sys/vfs.h, la structstatfscome strut- tura corrispondente all’interno del proprio kernel:
/* n o t e : t h i s c o r r e s p o n d s to the k e r n e l ’ s s t a t f s 6 4 t y p e */ s t r u c t s t a t f s { u i n t 3 2 _ t f _ t y p e ; u i n t 3 2 _ t f _ b s i z e ; u i n t 6 4 _ t f _ b l o c k s ; u i n t 6 4 _ t f _ b f r e e ; u i n t 6 4 _ t f _ b a v a i l ; u i n t 6 4 _ t f _ f i l e s ; u i n t 6 4 _ t f _ f f r e e ; _ _ k e r n e l _ f s i d _ t f _ f s i d ; u i n t 3 2 _ t f _ n a m e l e n ; u i n t 3 2 _ t f _ f r s i z e ; u i n t 3 2 _ t f _ s p a r e [ 5 ] ; };
Gli header mancanti sono stati dunque implementati e inseriti nella directory
include_adds.
Definizione UTSNAME LENGTH
All’interno dell’header um_lib.h `e contenuta la struttura viewinfo cos`ı
definita: s t r u c t v i e w i n f o { s t r u c t u t s n a m e u n a m e ; p i d _ t s e r v e r i d ; v i e w i d _ t v i e w i d ; c h a r v i e w n a m e [ _ U T S N A M E _ L E N G T H ]; }
in cui `e la dimensione della stringaviewname`e quindi pari a_UTSNAME_LENGTH; nella GNU C Library la definizione di quest’ultima costante `e contenuta all’interno dell’header <bits/utsname.h>, corrisponde al valore 65 ed in-
dica la dimensione dei campi della struttura utsname definita nell’header <sys/utsname.h> F I L E < b i t s / u t s n a m e . h > /* L e n g t h of the e n t r i e s in ‘ s t r u c t u t s n a m e ’ is 65. */ # d e f i n e _ U T S N A M E _ L E N G T H 65 F I L E < sys / u t s n a m e . h > # i f n d e f _ U T S N A M E _ S Y S N A M E _ L E N G T H # d e f i n e _ U T S N A M E _ S Y S N A M E _ L E N G T H _ U T S N A M E _ L E N G T H # e n d i f /* S t r u c t u r e d e s c r i b i n g the s y s t e m and m a c h i n e . */ s t r u c t u t s n a m e { c h a r s y s n a m e [ _ U T S N A M E _ S Y S N A M E _ L E N G T H ];
c h a r n o d e n a m e [ _ U T S N A M E _ N O D E N A M E _ L E N G T H ]; c h a r r e l e a s e [ _ U T S N A M E _ R E L E A S E _ L E N G T H ]; c h a r v e r s i o n [ _ U T S N A M E _ V E R S I O N _ L E N G T H ]; c h a r m a c h i n e [ _ U T S N A M E _ M A C H I N E _ L E N G T H ]; # if _ U T S N A M E _ D O M A I N _ L E N G T H - 0 /* N a m e of the d o m a i n of t h i s n o d e on the n e t w o r k . */ # i f d e f _ _ U S E _ G N U c h a r d o m a i n n a m e [ _ U T S N A M E _ D O M A I N _ L E N G T H ]; # e l s e c h a r _ _ d o m a i n n a m e [ _ U T S N A M E _ D O M A I N _ L E N G T H ]; # e n d i f # e n d i f };
All’interno di Bionic tuttavia la costante _UTSNAME_LENGTH risulta essere
assente e la strutturautsname, presente nel file$NDK/platforms/android-14/ arch-x86/usr/include/sys/utsname.h, `e dunque cos`ı definita:
# d e f i n e S Y S _ N M L N 65 s t r u c t u t s n a m e { c h a r s y s n a m e [ S Y S _ N M L N ]; c h a r n o d e n a m e [ S Y S _ N M L N ]; c h a r r e l e a s e [ S Y S _ N M L N ]; c h a r v e r s i o n [ S Y S _ N M L N ]; c h a r m a c h i n e [ S Y S _ N M L N ]; c h a r d o m a i n n a m e [ S Y S _ N M L N ]; };
La definizione della costante_UTSNAME_LENGTH`e stata quindi aggiunta all’in- terno del fileum_lib.h
# i f n d e f _ U T S N A M E _ L E N G T H
# d e f i n e _ U T S N A M E _ L E N G T H S Y S _ N M L N # e n d i f
rimanendo coerenti con la definizione presente nella libreria standard C.
Definizione fd mask
Un ulteriore lacuna evidenziata in Bionic nel corso della ricompilazione del del codice di umView riguarda l’assenza della costante __fd_mask utilizzata
all’interno del sorgenteum_select.c:
s t a t i c v o i d g e t f d s e t ( l o n g addr , s t r u c t pcb * pc , int max , f d _ s e t * l f d s ) { F D _ Z E R O ( l f d s ); if ( a d d r != u m N U L L ) u m o v e n ( pc , addr ,( _ _ F D E L T ( max ) + 1 ) * s i z e o f ( _ _ f d _ m a s k ) , l f d s ); }
s t a t i c v o i d p u t f d s e t ( l o n g addr , s t r u c t pcb * pc , int max , f d _ s e t * l f d s ) { if ( a d d r != u m N U L L ) u s t o r e n ( pc , addr ,( _ _ F D E L T ( max ) + 1 ) * s i z e o f ( _ _ f d _ m a s k ) , l f d s ); }
Nella GNU C Library la definizione di __fd_mask `e contenuta all’interno dell’header di sistema <sys/select.h> e, com’`e possibile notare, `e utilizzata all’interno dell’header stesso per la definizione della costante __NFDBITS e della macro __FD_MASK(d):
/* The f d _ s e t m e m b e r is r e q u i r e d to be an a r r a y of l o n g s . */
t y p e d e f l o n g int _ _ f d _ m a s k ;
# d e f i n e _ _ N F D B I T S (8 * ( int ) s i z e o f ( _ _ f d _ m a s k ))
Queste ultime due definizioni sono tuttavia presenti anche in Bionic all’inter- no dell’header $NDK/platforms/android-14/arch-x86/usr/include/linux/ posix_types.h: # d e f i n e _ _ N F D B I T S (8 * s i z e o f ( u n s i g n e d l o n g )) # d e f i n e _ _ F D M A S K ( d ) (1 UL < < (( d ) % _ _ N F D B I T S )) `
E evidente come le dichiarazioni di __NFDBITS e __FD_MASK(d) contenute
nelle due librerie siano sostanzialmente coincidenti ad eccezione dell’utiliz- zo della costante __fd_mask che nel secondo caso `e sostituita dalla dicitu-
ra unsigned long; per tale motivo all’interno del file um_select.c `e stata aggiunta la definizione
t y p e d e f u n s i g n e d l o n g _ _ f d _ m a s k ;
che risulta essere concorde con le definizioni presenti nel relativo header.
Supporto per ptrace
In Bionic `e fornita una differente implementazione della system callptrace, utilizzata in umView per l’intercettazione delle chiamate di sistema del pro- cesso virtualizzato; quest’ultima permette infatti ad un processo, chiamato tracer, di controllare l’esecuzione di un secondo processo, che prende il nome di tracee, esaminandone e modificandone la rispettiva area di memoria; at- traverso il parametrorequest della funzione ptrace, il tracer pu`o specificare una serie operazioni da compiere sul processo controllato.
Nella libreria standard C la definizione della funzione ptrace`e contenuta
nell’header di sistema sys/ptrace.h:
e x t e r n l o n g int p t r a c e ( e n u m _ _ p t r a c e _ r e q u e s t _ _ r e q u e s t , . . . ) _ _ T H R O W ;
Nello stesso file `e inoltre definita l’enumerazione enum __ptrace_request in cui sono elencate le operazioni che `e possibile indicare come parametrorequest
All’interno dei sorgenti di umView l’header defs_i386_um.hdefinisce la fun-
zione setregs per la modifica e l’impostazione dei registri del processo con- trollato e, in accordo con la definizione di ptrace appena descritta, indica per il parametro call il tipo enum __ptrace_request:
s t a t i c i n l i n e l o n g s e t r e g s ( s t r u c t pcb * pc ,
e n u m _ _ p t r a c e _ r e q u e s t call , l o n g op , l o n g sig ){ . . . }
Tuttavia, come precedentemente anticipato, Bionic fornisce un’implemen- tazione differente per la funzione ptrace, contenuta all’interno dell’header $NDK/platforms/android-14/arch-x86/usr/include/sys/ptrace.h:
e x t e r n l o n g p t r a c e ( int request , p i d _ t pid , v o i d * addr , v o i d * d a t a );
Com’`e possibile notare a differenza della definizione presente nella GNU C Li- brary, il parametro formalerequest ha tipo intero e nel file$NDK/platforms/ android-14/arch-x86/usr/include/linux/ptrace.h sono definite, nella for- ma di singole costanti intere, le operazioni che `e possibile indicare. Per permettere dunque la corretta compilazione dell’header defs_i386_um.h at- traverso Bionic, la definizione della funzionesetregs`e stata cos`ı modificata:
s t a t i c i n l i n e l o n g s e t r e g s ( s t r u c t pcb * pc , int call ,
l o n g op , l o n g sig ){ . . . }
Directory Temporanea
Nella funzioneum_proc_open, contenuta nel file sorgenteum_proc.c, `e sta- to modificato il path in cui la virtual machine crea la directory per la me- morizzazione dei file temporanei relativi al processo virtualizzato. Ci`o si `e rivelato necessario poich`e il path originale, /tmp/.umview, non `e disponibile
su sistema operativo Android.
Nello stesso sorgente `e stata inoltre commentata la funzione rec_rm_all a causa di un errore evidenziato in fase di compilazione1; tale scelta `e non pregiudica il corretto funzionamento della virtual machine ma comporta la necessit`a di eliminare manualmente la directory temporanea creata a runti- me.
Backtrace
Il file gdebug.c, presente all’interno dei sorgenti di umView, contiene le definizioni di alcune funzioni utilizzate per effettuare operazioni di debug sul codice; in particolare la funzionefgbacktracerichiama le funzionibacktrace
ebacktrace_symbolsdefinite all’interno dell’header<execinfo.h>; queste ul-
time permettono di determinare il backtrace del thread corrente, definito come la lista delle chiamate attive all’interno del processo. La versione cor- rente di Bionic non offre tuttavia funzionalit`a di backtrace e per tale motivo si `e deciso di eliminare dal file gdebug.c l’implementazione di fgbacktrace,
dal momento che quest’ultima non risulta essere utilizzata all’interno degli altri sorgenti. Sempre nel file gdebug.c`e stato modificato il riferimento alla
libreria libc.so contenuto nel costruttore del sorgente2, poich`e a differenza di quanto accade nei sistemi Linux in cui `e utilizzato il soname libc.so.6, in Android quest’ultimo assume semplicemente il nome dilibc.so.
Sorgenti esclusi dalla compilazione
Durante la cross-compilazione del file loginshell.c `e stata riscontra- ta l’assenza, all’interno dell’header pwd.h implementato per Android, della funzione getpwuid_r; com’`e possibile infatti notare, all’interno dell’header `e presente la seguente dichiarazione:
1In function ’rec_rm_all’: 330:15: error: dereferencing pointer to incomplete type. 2Per costruttori si intende un particolare tipo di funzioni, definite dal compilatore GCC, attraverso le quali `e possibile indicare all’interno di un programma delle azioni da eseguire prima dell’esecuzione della funzione main.
# if 0 /* M I S S I N G F R O M B I O N I C */ int g e t p w n a m _ r ( c o n s t c h a r * , s t r u c t p a s s w d * , c h a r * , size_t , s t r u c t p a s s w d * * ) ; int g e t p w u i d _ r ( uid_t , s t r u c t p a s s w d * , c h a r * , size_t , s t r u c t p a s s w d * * ) ; s t r u c t p a s s w d * g e t p w e n t ( v o i d ); int s e t p w e n t ( v o i d ); # e n d i f /* M I S S I N G */
Per tale motivo si `e deciso di escludere dalla compilazione il file sorgen- te loginshell.c, rimuovendo dunque da umView la possibilit`a di lanciare la virtual machine come shell di login; tale funzionalit`a non risulta essere comunque essenziale per il presente lavoro e dunque l’esclusione del file non pregiudica la corretta implementazione dello scenario.
Parametri di compilazione
All’interno del file Android.mk, tra i parametri di compilazione del mo- dulo umview `e stata rimossa la definizione di _UM_EPOLL, presente invece
nel Makefile.am originale per l’utilizzo di epoll3. La necessit`a di apporta- re tale modifica deriva dall’assenza, all’interno dell’header sys/epoll.h im- plementato per Android, della definizione delle costanti EPOLL_CLOEXEC ed
EPOLL_NONBLOCK utilizzate nel file um_select.c; tuttavia, come documentato
all’interno del codice, il supporto per epoll in umView risulta essere ancora in fase di sviluppo e non costituisce dunque una funzionalit`a indispensabile per il corretto funzionamento della macchina virtuale.
Sono state inoltre definite le costanti MODULES_DIR, USER_MODULES_DIR e
LIBEXECDIRattraverso le quali sono indicati i path in cui saranno contenuti i moduli di virtualizzazione all’interno del dispositivo Android.
3Meccanismo di I/O notification introdotto nel kernel Linux dalla versione 2.5.44 e si propone di sostituire le system call POSIXselectepoll