Prima di tutto, devo ammettere che sono pienamente d'accordo con la tua dichiarazione "Ho trovato questo lavoro incredibilmente difficile da fare" . Google ha progettato Android principalmente dal punto di vista del consumatore e non per utenti esperti. Il risultato è che, non appena vuoi fare qualcosa al di fuori dell'uso dell'ultima app di Facebook o di giocare con Candy Crush, ti ritrovi molto rapidamente nel regno di Linux dei primi anni del 2000, quando era richiesta una conoscenza simile a quella degli sviluppatori per cambiare quali dovrebbero essere le impostazioni semplici. Credo che la situazione si evolverà rapidamente man mano che il sistema Android diventa più maturo, ma per ora abbiamo a che fare con quello che abbiamo ...
Come hai detto, ci sono due motivi per cui è necessario compilare il proprio set di strumenti SELinux:
- Il set di strumenti fornito dal sistema è in genere una versione precedente. Mentre SELinux di Android si basa sul DB delle politiche versione 30, le attuali scatole Linux di solito gestiscono solo la versione fino a 29.
- Anche se sarebbe più recente, non sarebbe di aiuto, infatti la creazione di SELinux dal codice upstream (che è facilmente eseguibile, almeno su macchine Fedora seguendo le raccomandazioni upstream) consente efficacemente al sistema di gestire il DB di politica versione 30, tuttavia SELinux di Android è stato fortemente modificato (la documentazione di Google evidenzia alcune modifiche), quindi il tentativo di gestire SELinux di Android fallisce a causa della sintassi e degli errori di analisi.
Quindi, per continuare la ricerca di analisi SELinux su Android, dovremo mettere le mani nella sporcizia ... nel modo più pulito possibile:
- Per prima cosa installeremo un ambiente sano,
- Fatto ciò, compileremo le librerie SELinux di Android e i primi strumenti,
- Inoltre, costruiremo strumenti SELinux,
- Concluderemo aggiungendo alcune utilità supplementari.
Imposta un ambiente adeguato
Proprietà dell'ambiente
Il modo più pulito consigliato, forse forse solo in modo affidabile, è quello di dedicare un ambiente al tuo lavoro Android:
Una macchina virtuale va benissimo (se non l'opzione migliore). Preferisci usarne uno VMware poiché dovrai connettere il tuo telefono tramite USB al sistema guest. L'alternativa gratuita Qemu non sembra gestire molto bene tale compito. Non ho provato con altri software di virualizzazione.
Dovrà essere un sistema a 64 bit, altrimenti il codice semplicemente non verrà compilato a causa della dimensione errata degli interi.
Si consiglia vivamente , possibilmente obbligatorio, di utilizzare un sistema Ubuntu. Sentiti libero di usare Xubuntu invece se preferisci l'ambiente desktop più leggero di XFCE, questo non cambia il core del sistema e il pacchetto disponibile e non avrà alcun impatto sul tuo lavoro relativo ad Android (tutto ciò che dico su Ubuntu in questa procedura si applica anche a Xubuntu). Nell'albero dei sorgenti SELinux di Android potresti trovare alcuni file Leggimi che raccomandano l'uso di Fedora, questi file sono ereditati dal progetto SELinux dell'NSA a monte e il loro contenuto non corrisponde necessariamente ad Android di Google.
La versione esatta di Unbuntu da utilizzare dipende dalla versione di Android che desideri creare. Per Android 6.0, si consiglia Ubuntu 14.04 (Trusty). Controlla la pagina dei requisiti di Google per ulteriori informazioni.
Avrai bisogno di molto spazio su disco (almeno 50 GB se pianifichi solo indagini relative a SELinux, almeno 100 GB se prevedi una build completa di Android). La CPU e la memoria sono meno rilevanti, hanno un impatto solo sul tempo per un build completo e non avranno alcun impatto reale per le attività relative a SELinux.
L'uso di Ubuntu ha due vantaggi principali:
Utilizzando il sistema consigliato, si lavora in un ambiente ben noto e testato: le librerie di sistema, gli strumenti e i pacchetti sono nella versione e nel percorso previsti dal progetto.
E più precisamente nel nostro caso attuale: Ubuntu stesso si basa su AppArmor che è un'alternativa SELinux, non utilizza SELinux. La buona notizia è che sarai quindi in grado di installare gli strumenti e i binari SELinux di Android a livello di sistema senza rischiare di alterare l'affidabilità del sistema.
Procedura di installazione dell'ambiente
Puoi installare Ubuntu in modo tradizionale partendo da un DVD live completo, ma un'alternativa più veloce è usare un'installazione netboot (installazione in modalità testo) e selezionare l'ambiente desktop che preferisci alla fine. In questo modo risparmierai il tempo di aggiornamento iniziale installando direttamente la versione aggiornata dei pacchetti anziché prima installando quelli obsoleti, quindi chiedendo di applicare 389 aggiornamenti in sospeso al primo avvio.
Il programma di installazione di netboot ISO per Ubuntu / Xubuntu 14.04 (stesso ISO) è disponibile qui .
Per saltare la fastidiosa funzione "Easy Install" di VMware, è una buona abitudine iniziare selezionando l' opzione "Installerò il sistema operativo in seguito" .
Assicurati di selezionare Linux , quindi Ubuntu 64 bit come SO guest.
La VM avrà bisogno delle risorse seguenti:
- Obbligatorio: lo spazio su disco deve essere di almeno 40 GB (i 20 GB predefiniti non saranno sufficienti, il codice sorgente da solo occupa più spazio di quello), si consiglia un valore superiore. Una build completa richiede un minimo di 100 GB di disco, questo è il valore che di solito prendo. Non dimenticare che questa impostazione è solo un limite massimo: le dimensioni effettive prese dalla VM aumentano in modo dinamico con le richieste dell'ospite.
- Facoltativo: aumentare la RAM da 1024 ad almeno 2048 o superiore (dipende dalla capacità dell'host, utilizzo 4096),
- Facoltativo: aumentare il numero di core del processore da 1 a 2 o superiore (dipende dalla capacità dell'host, io uso 3).
- Il CD-Rom deve puntare al file ISO di installazione.
- È possibile che si desideri cambiare USB dall'impostazione predefinita 1.1 alla 2.0 in quanto la prima potrebbe fornire avvisi quando si collega il dispositivo. A seconda dell'utilizzo, puoi anche deselezionare "Connetti automaticamente nuovi dispositivi USB" e "Condividi dispositivi Bluetooth con la macchina virtuale" .
- A seconda del proprio ambiente, potrebbe anche essere necessario modificare le impostazioni di visualizzazione (disabilitare il 3D, applicare una dimensione dello schermo).
Attenzione:
- Se hai scelto l'installazione di netboot, non dimenticare di selezionare il tuo ambiente desktop ( desktop Ubuntu o desktop Xubuntu ) quando raggiungi la schermata di selezione del software , o finirai con un ambiente di solo testo minimo!
- Al primo avvio, rifiuta di eseguire l'aggiornamento all'ultima versione: il punto qui è di rimanere in 14.04!
Al primo avvio, uno dei primi che potresti voler fare è installare gli strumenti guest Linux:
sudo apt-get install open-vm-tools
Questo pacchetto attiva i trigger all'avvio, pertanto l'installazione verrà completata solo dopo il riavvio del guest.
Recupera il codice sorgente Android
Sebbene simili, i dettagli della procedura dipendono dalla ROM scelta:
- Per CyanogenMod, cerca il tuo dispositivo (seleziona prima il fornitore), quindi fai clic sul link "Come costruire CyanogenMod" per ottenere istruzioni adattate per il tuo dispositivo.
- Per AOSP, seguire la procedura che inizia qui .
Vale la pena notare che CyanogeMod raggruppa nella sua struttura di origine uno strumento che consente di decomprimere i boot.img
file. Per dirlo in modo diverso, CyanogenMod ti fornisce uno strumento che ti permetterà di accedere al sepolicy
file archiviato nei dispositivi e negli archivi ROM. L'AOSP di Google non fornisce tale strumento, quindi se non hai altri imperativi utilizzando l'albero dei sorgenti di CyanogenMod potrebbe essere la scelta più conveniente, altrimenti dovrai installarlo appart (che è veloce e facile da fare, quindi non preoccuparti qui).
Qui sto seguendo la procedura CyanogenMod 13.0 (Android 6.0). Spiegazione sui comandi utilizzati è disponibile nelle pagine collegate sopra. Si prega di leggerli, il dattiloscritto di seguito viene fornito solo a scopo di riferimento.
Suggerimento: Mentre utilizzoapt-get
in questo post per attenermi al minimo comune denominatore e rendere tutti felici, potresti preferireaptitude
inveceutilizzarlopoiché si occuperà delle dipendenze in un modo migliore (durante la rimozione di un pacchetto che richiedeva l'installazione di alcune dipendenze , anche queste dipendenze verranno rimosse, lasciando il sistema più pulito). AFAIK ilaptitude
comando deve essere installato in Ubuntu ma è disponibile per impostazione predefinita su Xubuntu.
sudo apt-get install bison build-essential curl flex git gnupg gperf \
libesd0-dev liblz4-tool libncurses5-dev libsdl1.2-dev libwxgtk2.8-dev libxml2 \
libxml2-utils lzop maven openjdk-7-jdk pngcrush schedtool squashfs-tools \
xsltproc zip zlib1g-dev g++-multilib gcc-multilib lib32ncurses5-dev \
lib32readline-gplv2-dev lib32z1-dev
mkdir -p ~/bin
mkdir -p ~/android/system
PATH=~/bin:$PATH
curl https://storage.googleapis.com/git-repo-downloads/repo > ~/bin/repo
chmod u+x ~/bin/repo
cd ~/android/system/
git config --global user.name "Your Name"
git config --global user.email "you@example.com
repo init -u https://github.com/CyanogenMod/android.git -b cm-13.0
repo sync
# Coffee time: around 20GB are being downloaded, this may take several hours.
source ./build/envsetup.sh
breakfast
Ora hai un albero delle fonti pulito e quasi completo. Mancano i BLOB proprietari, ma non sono necessari per le attività relative a SELinux.
Suggerimento: recuperare le fonti è un processo noioso, potrebbe valere la pena fare un'istantanea o un backup della VM ora.
Compilare e installare il set di strumenti e le librerie SELinux di Android
Ora inizia la parte divertente del viaggio;)!
Fino ad ora la procedura avrebbe dovuto essere piuttosto semplice. L'obiettivo era principalmente quello di assicurarmi che tu abbia lo stesso ambiente in cui mi trovo. Se lo fai, anche il sequel dovrebbe rimanere semplice.
Sotto il cofano, Google non esita ad applicare profonde modifiche al codice sorgente di Android tra le versioni, quindi i passaggi esatti della compilazione dipenderanno sicuramente dalla versione (ad esempio, il master AOSP mostra che la sepolicy/
directory verrà spostata ).
Condividerò prima la mia esatta procedura per compilare e installare le librerie e il set di strumenti SElinux di Android, ma al fine di mantenere la pertinenza di questo post nel tempo, aggiungerò alcune note sull'approccio generico da seguire per risolvere la maggior parte dei problemi di compilazione.
Procedura dettagliata
Le librerie SELinux di Android forniscono il livello di astrazione che consentirà al software di livello superiore di gestire i file delle politiche SELinux specifici di Android. Dovremo quindi compilarli e installarli prima (che, di per sé, in realtà rappresenta il nucleo se le difficoltà qui, fino a quando non hai trovato la tua strada).
Saremo quindi in grado di costruire e installare strumenti SELinux. Come vedremo, fortunatamente questi non devono essere specifici per Android, devono solo corrispondere alla versione della libreria SELinux.
Questa procedura è stata testata sia usando gli alberi di codice sorgente CyanogenMod che AOSP.
Compilare e installare librerie e primi strumenti SELinux per Android
Dipendenze per la prima installazione:
sudo apt-get install libapol-dev libaudit-dev libdbus-glib-1-dev libgtk2.0-dev \
libustr-dev python-dev python-networkx swig xmlto
In questo post la variabile $ANDROID_BUILD_TOP
memorizza la posizione di origine (la directory in cui è stato emesso il repo sync
comando). Sentiti libero di cambiare il suo nome come preferisci.
ANDROID_BUILD_TOP=~/android/system
cd $ANDROID_BUILD_TOP
source ./build/envsetup.sh
Per impostazione predefinita, la compilazione dei programmi di utilità core non riesce a causa restorecond
del fatto che Makefile non è in grado di individuare alcune librerie. Devi modificare questo Makefile per usare percorsi generati dinamicamente pkg-config
invece di quelli hardcoded (non confondere i backtick con virgolette singole!):
sed -i 's/^CFLAGS ?= -g -Werror -Wall -W$/& `pkg-config --cflags --libs dbus-1 gtk+-2.0`/' \
$ANDROID_BUILD_TOP/external/selinux/policycoreutils/restorecond/Makefile
Sentiti libero di aprire il Makefile con qualche editor di testo per assicurarti che la modifica sia stata correttamente presa in considerazione.
E ora compila e installa:
cd $ANDROID_BUILD_TOP/external/bzip2/
make -f Makefile-libbz2_so
sudo make install
cd $ANDROID_BUILD_TOP/external/libcap-ng/libcap-ng-0.7/
./configure
make
sudo make install
cd $ANDROID_BUILD_TOP/external/selinux/
make -C ./libsepol/
sudo make -C /libsepol/ install
EMFLAGS=-fPIC make -C ./libselinux/
sudo make -C ./libselinux/ install
make -C ./libsemanage/
sudo make -C ./libsemanage/ install
make
sudo make install
make swigify
sudo make install-pywrap
sudo cp ./checkpolicy/test/{dispol,dismod} /usr/bin/
Attenzione: non perdere l'EMFLAGS=-fPIC
impostazione della variabile di ambiente durante la creazionelibselinux
. Non genererà ancora alcun errore, ma nel passaggio successivo non sarà possibile creare SETools. Se l'hai perso o hai fatto qualcos'altro, semplicemente emetti unmake clean
e riavvia la compilation.
Compilare e installare strumenti SELinux
Gli strumenti SELinux sono forniti in una forma predefinita che include:
- Script Python (e relativi wrapper di script shell) all'interno della
$ANDROID_BUILD_TOP/external/selinux/prebuilts/bin/
directory
- Pacchetti Python (inclusi
*.o
file compilati) di seguito $ANDROID_BUILD_TOP/prebuilts/python/linux-x86/2.7.5/lib/python2.7/site-packages/
.
Mi sarei aspettato che il codice sorgente di questi strumenti fosse disponibile di seguito $ANDROID_BUILD_TOP/external
, ma non lo è. In realtà, non ho trovato alcun posto in cui Google condividesse la versione esatta di SETools che utilizzavano (FYI la GPL richiede solo di condividere il codice se è stato modificato), quindi dovremo indovinare e provare e fare il meglio che possiamo .
Gli strumenti stessi sono script Python, questa è una nuova evoluzione da SETools 4 (in SETools 3, comandi come se sesearch
fossero eseguibili binari codificati in C). Tuttavia, gli strumenti stessi mostrano ancora una versione di 3.3.8:
$ $ANDROID_BUILD_TOP/external/selinux/prebuilts/bin/sesearch --version
3.3.8
Quindi la mia ipotesi è che Google abbia preso una prima istantanea di sviluppo da SETools 4. Fino alla 4.0.0 beta SETools si basava su libsepol
versoin 2.4, con la versione 4.0.0 hanno iniziato a fare affidamento sulla versione 2.5 della libreria che non è compatibile con la versione di SELinux in bundle con Android 6.0 (puoi provare a compilarlo, fallirà).
Quindi la scelta più saggia sembra andare con SETools 4.0.0 Beta.
Installa dipendenze supplementari:
sudo apt-get install python-setuptools
Scarica ed estrai il codice sorgente:
cd ~/android/
wget https://github.com/TresysTechnology/setools/archive/4.0.0-beta.tar.gz
tar xzf 4.0.0-beta.tar.gz
cd ./setools-4.0.0-beta/
A causa di un bug che interessa Flex 2.5, dobbiamo rimuovere -Wredundant-decls
dai flag del compilatore:
sed -i '/-Wredundant-decls/d' ./setup.py
E infine compilare e installare:
python ./setup.py build
sudo python ./setup.py install
Procedura generica (o "Come sbloccarsi")
Nel caso in cui la procedura sopra non ha funzionato nel tuo caso, ecco una visione di livello superiore su come provare a progredire.
Purtroppo non c'è magia (e nessun aiuto :() da queste parti: l'unico modo per ottenere questo codice da compilare è l'approccio ciclico classico ma temuto "prova a vedere".
Prova a compilare una prima volta, molto probabilmente fallirà a causa della mancanza di alcuni *.h
file:
Cerca nella external/
directory di Android :
find $ANDROID_BUILD_TOP/external -name filename.h
Se trovi il file richiesto, significa che una versione specifica della libreria o dello strumento corrispondente è stata inclusa nel codice sorgente di Android. Non dovresti quindi provare a installarlo dal sistema di pacchetti di Ubuntu, ma invece compila e installa la versione inclusa nel codice sorgente di Android.
Tieni presente che ciò va contro i consigli generali che potresti trovare sui forum: "La tua compilation fallisce a causa della mancanza di questa libreria? Installa questo pacchetto, quindi andrà bene!" , facendo ciò, molto probabilmente andrai in un problema peggiore: se una versione specifica è raggruppata, è molto probabilmente perché è necessaria una versione specifica (a causa di problemi di compatibilità o perché questa versione contiene modifiche specifiche da Google).
A proposito, se ti stai chiedendo: ovviamente questa libreria o strumento potrebbe anche avere dipendenze che causano errori a causa della mancanza di alcuni *.h
file, e sì, dovresti applicare lo stesso approccio ciclico "prova e vedi".
Cerca in tutto il sistema:
find / -name filename.h 2>/dev/null
Se trovi "mancante" che il file sia già presente nel tuo sistema in una posizione standard della libreria condivisa, ciò significa che probabilmente questa dipendenza è già soddisfatta nel tuo ambiente ma il Makefile che ha generato l'errore è troppo stupido per trovarlo.
Se si chiama manualmente direttamente questo Makefile, potrebbe essere possibile impostare alcune variabili di ambiente risolvendole ( LIBDIR=/usr/lib make
ad esempio), altrimenti potrebbe essere necessario modificare il Makefile stesso (il pkg-config
comando potrebbe essere di aiuto prezioso per generare automaticamente i parametri di build mancanti) .
Cerca nel sistema di imballaggio:
apt-cache search filename-dev
Dove filename-dev
rappresenta il nome del file mancante in minuscolo con l' .h
estensione sostituita dal -dev
suffisso (ad esempio, se Python.h
non viene trovato, cercare python-dev
). Alcune modifiche nel nome esatto possono essere necessarie per trovare il pacchetto giusto.
Se rimani bloccato e anche se una rapida ricerca su Internet non ha fornito alcuna risposta chiara, allora apt-file
sarà il tuo migliore amico. apt-file
non è installato per impostazione predefinita, è necessario installarlo e generare il suo database:
sudo apt-get apt-file
sudo apt-file update
apt-file
ti permette di cercare pacchetti (anche quelli disinstallati) fornendo un determinato file. Per evitare di avere troppi risultati, ti consiglio di associarlo grep
come di seguito:
apt-file search filename.h | grep -w filename.h
Se nel repository di Ubuntu è presente un pacchetto che fornisce questo file, apt-file
dovrebbe essere in grado di trovarlo.
Una volta trovato il pacchetto giusto, installalo usando apt-get install packagename
dove si packagename
trova il nome del pacchetto.
Suggerimento: Se si fregato qualcosa sul vostro sistema, il comando per reinstallare un pacchetto è questo:apt-get reinstall pkg_name
. Funzionerà anche quando una classica rimozione e installazione non sarebbe possibile a causa della rottura delle dipendenze (che è molto probabile per le librerie di sistema).
Strumenti supplementari
A questo punto, ora dovresti avere un ambiente pulito che ti permetta di investigare sulle regole SELinux di Android sia in formato compilato che sorgente.
Tuttavia, la maggior parte delle probabilità è che alla fine dell'indagine desidererai agire. Nella sua forma attuale, il tuo ambiente non ti consentirà di modificare il sepolicy
file di un dispositivo . In effetti, questo file non può essere facilmente sostituito: fa parte della directory principale del dispositivo e il contenuto della directory principale viene estratto al momento dell'avvio da un file del disco RAM, che a sua volta viene archiviato nell'immagine di avvio del dispositivo.
Quindi perdi ancora due cose prima che il tuo ambiente sia completo:
- Un modo per accedere e modificare l'immagine di avvio del dispositivo,
- Un modo per modificare il suo
sepolicy
file.
Fortunatamente, questi sono esattamente l'argomento delle ultime due sezioni di questo post! :)
Recupera e aggiorna l'immagine di avvio del dispositivo
Gli strumenti per recuperare e aggiornare l'immagine di avvio dei dispositivi possono essere utilizzati per una vasta gamma di cose oltre alla manomissione delle regole SELinux. Ho quindi creato una risposta dedicata , fare riferimento ad essa.
Modifica le regole SELinux del dispositivo
Hai due possibilità principali qui:
- Crea un nuovo
sepolicy
file dalle regole nella tua struttura di origine (cerca i .te
file per trovarli: find $ANDROID_BUILD_TOP -name \*.te
sono distribuiti in più directory).
- Modifica il
sepolicy
file attualmente utilizzato dal dispositivo.
A meno che tu non abbia davvero bisogno di costruire le tue regole da zero, che è più un compito legato allo sviluppo e quindi fuori portata qui, la seconda scelta sembra di gran lunga la più sicura in quanto sei sicuro che le uniche modifiche saranno quelle tue esplicitamente fatto.
C'è stato un progetto per creare uno strumento che ti consente di decompilare un sepolicy
file in un modulo ricompilabile, che consente di modificare liberamente le regole in mezzo. Tuttavia, questo progetto è stato abbandonato in uno stato di prova. Troverai tutte le informazioni alla fine di questo post sul blog , il resto dell'articolo contiene dettagli sufficienti per consentire a chiunque sia interessato a subentrare.
Il modo attualmente raccomandato di modificare le sepolicy
regole va in un'altra direzione: modificando direttamente il sepolicy
file binario. lo strumento sepolicy-inject consente proprio questo e viene attivamente mantenuto.
Per completezza, si noti che esiste un fork di questo strumento. Aggiunge alcune funzionalità, alcune delle quali sono nella lista delle cose da fare dell'autore originale (come la possibilità di rimuovere una regola), non chiedermi perché hanno scelto di fork invece di contribuire ...
Per compilare e installare sepolicy-inject
, procedi semplicemente come segue:
cd ~/android/
git clone https://bitbucket.org/joshua_brindle/sepolicy-inject.git
cd ./sepolicy-inject/
LIBDIR=/usr/lib make
sudo cp ./sepolicy-inject /usr/bin/
Esempio di caso d'uso
Diciamo ad esempio che si desidera aggiungere l'autorizzazione corrispondente al seguente messaggio di errore:
avc: denied { read } for pid=128 comm="file-storage"
path="/data/media/0/path/to/some/file"
dev="mmcblk0p28" ino=811035 scontext=u:r:kernel:s0
tcontext=u:object_r:media_rw_data_file:s0 tclass=file permissive=0
Dovrai recuperare l'immagine di avvio del dispositivo, quindi decomprimerlo per accedere al suo sepolicy
file.
Un rapido controllo usando sesearch
mostra che non esiste alcuna regola di consenso (ancora!):
$ sesearch -A -s kernel -t media_rw_data_file -c file -p read ./sepolicy
$
Il comando non ha output.
Quindi, utilizzare il comando seguente per aggiungere la regola richiesta (notare la somiglianza tra sesearch
e sepolicy-inject
parametri):
sepolicy-inject -s kernel -t media_rw_data_file -c file -p read -P ./sepolicy
Ora possiamo richiamare il nostro sesearch
comando:
$ sesearch -A -s kernel -t media_rw_data_file -c file -p read ./sepolicy
allow kernel media_rw_data_file:file read;
$
sesearch
l'output mostra che il criterio è stato aggiornato correttamente.
Ora puoi reimballare il boot.img
file del dispositivo e ripristinarlo sul dispositivo. Controllare l'ora dell'ultima modifica del /sepolicy
file è un modo semplice per assicurarsi che il dispositivo stia eseguendo il sepolicy
file appena aggiornato .
Conclusione
Ora dovresti avere un ambiente completo che ti consenta di ispezionare e modificare liberamente i criteri SELinux dei dispositivi Android. Godere! :)
Come nota a margine, ci sono anche strumenti che consentono di analizzare e modificare i criteri SELinux direttamente dal dispositivo .