Dopo aver integrato il livello di base della funzionalità SELinux e aver esaminato attentamente i risultati, puoi aggiungere le tue impostazioni dei criteri per coprire le tue personalizzazioni del sistema operativo Android. Questi criteri devono comunque soddisfare i requisiti del Programma di compatibilità Android e non devono rimuovere le impostazioni SELinux predefinite.
I produttori non devono rimuovere le norme SELinux esistenti. In caso contrario, rischia di interrompere l'implementazione di Android SELinux e le app che governa. Sono incluse le app di terze parti che probabilmente dovranno essere migliorate per essere conformi e operative. Le app non devono richiedere modifiche per continuare a funzionare sui dispositivi abilitati per SELinux.
Quando inizi a personalizzare SELinux, ricordati di:
- Scrivi criterio SELinux per tutti i nuovi daemon
- Utilizza i domini predefiniti, se opportuno
- Assegna un dominio a qualsiasi processo generato come servizio
init
- Acquisisci familiarità con le macro prima di scrivere le norme
- Inviare le modifiche alle norme di base ad AOSP
Inoltre, ricordati di non:
- Crea criterio incompatibile
- Consentire la personalizzazione delle norme per gli utenti finali
- Consenti personalizzazioni dei criteri MDM
- Spaventare gli utenti con violazioni delle norme
- Aggiungere backdoor
Per requisiti specifici, consulta la sezione Funzionalità di sicurezza del kernel del documento sulla definizione di compatibilità Android.
SELinux utilizza un approccio di tipo whitelist, il che significa che tutto l'accesso deve essere esplicitamente consentito nel criterio per essere concesso. Poiché il criterio SELinux predefinito di Android supporta già il progetto open source Android, non è necessario modificare le impostazioni di SELinux in alcun modo. Se personalizzi le impostazioni SELinux, fai molta attenzione a non danneggiare le app esistenti. Per iniziare:
- Usa il kernel Android più recente.
- Adotta il principio del privilegio minimo.
- Rivolgiti solo per le tue aggiunte ad Android. Il criterio predefinito funziona automaticamente con la base di codice del progetto Android Open Source.
- Suddividi i componenti software in moduli che svolgono singole attività.
- Crea criteri SELinux che isolino queste attività da funzioni non correlate.
- Inserisci questi criteri nei file
*.te
(l'estensione per i file di codice sorgente dei criteri SELinux) all'interno della directory/device/manufacturer/device-name/sepolicy
e utilizza le variabiliBOARD_SEPOLICY
per includerli nella compilazione. - Rendi inizialmente permissivi i nuovi domini. Ciò viene fatto utilizzando una dichiarazione permissiva nel file
.te
del dominio. - Analizza i risultati e perfeziona le definizioni di dominio.
- Rimuovi la dichiarazione permissiva quando non vengono visualizzati ulteriori rifiuti nelle build di userdebug.
Dopo aver integrato la modifica del criterio SELinux, aggiungi un passaggio al flusso di lavoro di sviluppo per garantire la compatibilità con SELinux in futuro. In un processo di sviluppo software ideale, il criterio SELinux cambia solo quando cambia il modello software e non l'implementazione effettiva.
Quando inizi a personalizzare SELinux, controlla prima le aggiunte ad Android. Se hai aggiunto un componente che esegue una nuova funzione, assicurati che il componente soddisfi i criteri di sicurezza di Android, nonché eventuali criteri associati creati dall'OEM, prima di attivare la modalità di applicazione.
Per evitare problemi inutili, è meglio avere un testo troppo ampio e compatibile che troppo restrittivo e incompatibile, con la conseguenza di interrompere le funzioni del dispositivo. Al contrario, se le tue modifiche saranno utili per altri, dovresti inviarle al criterio SELinux predefinito come patch. Se la patch viene applicata al criterio di sicurezza predefinito, non dovrai apportare questa modifica con ogni nuova release di Android.
Dichiarazioni di norme di esempio
SELinux si basa sul linguaggio di programmazione M4 e pertanto supporta una serie di macro per farti risparmiare tempo.
Nell'esempio seguente, a tutti i domini viene concesso l'accesso in lettura o scrittura in /dev/null
e in lettura da /dev/zero
.
# Allow read / write access to /dev/null allow domain null_device:chr_file { getattr open read ioctl lock append write}; # Allow read-only access to /dev/zero allow domain zero_device:chr_file { getattr open read ioctl lock };
La stessa istruzione può essere scritta con le macro *_file_perms
SELinux (abbreviazione):
# Allow read / write access to /dev/null allow domain null_device:chr_file rw_file_perms; # Allow read-only access to /dev/zero allow domain zero_device:chr_file r_file_perms;
Norme di esempio
Di seguito è riportato un esempio completo di criterio per DHCP:
type dhcp, domain; permissive dhcp; type dhcp_exec, exec_type, file_type; type dhcp_data_file, file_type, data_file_type; init_daemon_domain(dhcp) net_domain(dhcp) allow dhcp self:capability { setgid setuid net_admin net_raw net_bind_service }; allow dhcp self:packet_socket create_socket_perms; allow dhcp self:netlink_route_socket { create_socket_perms nlmsg_write }; allow dhcp shell_exec:file rx_file_perms; allow dhcp system_file:file rx_file_perms; # For /proc/sys/net/ipv4/conf/*/promote_secondaries allow dhcp proc_net:file write; allow dhcp system_prop:property_service set ; unix_socket_connect(dhcp, property, init) type_transition dhcp system_data_file:{ dir file } dhcp_data_file; allow dhcp dhcp_data_file:dir create_dir_perms; allow dhcp dhcp_data_file:file create_file_perms; allow dhcp netd:fd use; allow dhcp netd:fifo_file rw_file_perms; allow dhcp netd:{ dgram_socket_class_set unix_stream_socket } { read write }; allow dhcp netd:{ netlink_kobject_uevent_socket netlink_route_socket netlink_nflog_socket } { read write };
Analizziamo l'esempio:
Nella prima riga, la dichiarazione del tipo, il demone DHCP eredita dal
criterio di sicurezza di base (domain
). Dagli esempi di dichiarazione
precedenti, DHCP può leggere e scrivere in /dev/null
.
Nella seconda riga, DHCP è identificato come dominio permissivo.
Nella riga init_daemon_domain(dhcp)
, il criterio indica che DHCP viene generato da init
ed è autorizzato a comunicare con questo.
Nella riga net_domain(dhcp)
, il criterio consente a DHCP di usare le funzionalità di rete comuni del dominio net
, come la lettura e la scrittura di pacchetti TCP, la comunicazione su socket e l'esecuzione di richieste DNS.
Nella riga allow dhcp proc_net:file write;
, il criterio indica
che DHCP può scrivere su file specifici in /proc
. Questa riga mostra la classificazione granulare dei file di SELinux. Utilizza l'etichetta proc_net
per limitare l'accesso in scrittura solo ai file in /proc/sys/net
.
L'ultimo blocco dell'esempio che inizia con allow dhcp netd:fd use;
mostra in che modo le app possono interagire tra loro. Il criterio indica che DHCP e netd possono comunicare tra loro tramite descrittori file, file FIFO, socket datagram e socket stream UNIX. DHCP può leggere e scrivere solo nelle socket di datagrammi e nelle socket stream UNIX, senza crearle o aprirle.
Controlli disponibili
Classe | Autorizzazione |
---|---|
file |
ioctl read write create getattr setattr lock relabelfrom relabelto append unlink link rename execute swapon quotaon mounton |
directory |
add_name remove_name reparent search rmdir open audit_access execmod |
presa |
ioctl read write create getattr setattr lock relabelfrom relabelto append bind connect listen accept getopt setopt shutdown recvfrom sendto recv_msg send_msg name_bind |
filesystem |
mount remount unmount getattr relabelfrom relabelto transition associate quotamod quotaget |
processo |
fork transition sigchld sigkill sigstop signull signal ptrace getsched setsched getsession getpgid setpgid getcap setcap share getattr setexec setfscreate noatsecure siginh setrlimit rlimitinh dyntransition setcurrent execmem execstack execheap setkeycreate setsockcreate |
sicurezza |
compute_av compute_create compute_member check_context load_policy compute_relabel compute_user setenforce setbool setsecparam setcheckreqprot read_policy |
funzionalità |
chown dac_override dac_read_search fowner fsetid kill setgid setuid setpcap linux_immutable net_bind_service net_broadcast net_admin net_raw ipc_lock ipc_owner sys_module sys_rawio sys_chroot sys_ptrace sys_pacct sys_admin sys_boot sys_nice sys_resource sys_time sys_tty_config mknod lease audit_write audit_control setfcap |
ALTRO |
E ANCORA |
Regole neverallow
Le regole neverallow
di SELinux vietano un comportamento che non dovrebbe mai verificarsi.
Con i test di compatibilità,
le regole SELinux neverallow
vengono ora applicate su tutti i dispositivi.
Le seguenti linee guida hanno lo scopo di aiutare i produttori a evitare errori correlati alle regole neverallow
durante la personalizzazione. I numeri di regole
usati qui corrispondono ad Android 5.1 e sono soggetti a modifiche in base alla release.
Regola 48: neverallow { domain -debuggerd -vold -dumpstate
-system_server } self:capability sys_ptrace;
consulta la pagina man di ptrace
. La funzionalità sys_ptrace
consente di ptrace
qualsiasi processo, il che consente un notevole controllo sugli altri processi e dovrebbe appartenere solo ai componenti di sistema designati, descritti nella regola. La necessità di questa funzionalità spesso indica la presenza di qualcosa che non è destinato agli utenti per build o funzionalità non necessarie. Rimuovi il componente non necessario.
Regola 76: neverallow { domain -appdomain -dumpstate
-shell -system_server -zygote } { file_type -system_file -exec_type }:file execute;
Questa regola ha lo scopo di impedire l'esecuzione di codice arbitrario sul sistema.
Nello specifico, afferma che viene eseguito solo il codice su /system
,
il che consente garanzie di sicurezza grazie a meccanismi come l'avvio verificato.
Spesso, la soluzione migliore quando si verifica un problema con questa
neverallow
regola è spostare il codice in violazione nella
/system
partizione.
Personalizzare SEPolicy in Android 8.0 e versioni successive
Questa sezione fornisce le linee guida per i criteri SELinux del fornitore in Android 8.0 e versioni successive, inclusi dettagli sulle estensioni SEPolicy e SEPolicy di Android Open Source Project (AOSP). Per ulteriori informazioni su come il criterio SELinux viene mantenuto compatibile tra le partizioni e le versioni di Android, consulta Compatibilità.
Posizionamento dei criteri
In Android 7.0 e versioni precedenti, i produttori di dispositivi potevano aggiungere criteri a
BOARD_SEPOLICY_DIRS
, inclusi criteri pensati per integrare i criteri AOSP
su diversi tipi di dispositivi. In Android 8.0 e versioni successive, l'aggiunta di un criterio a
BOARD_SEPOLICY_DIRS
lo inserisce solo nell'immagine del fornitore.
In Android 8.0 e versioni successive, i criteri esistono nelle seguenti posizioni in AOSP:
- system/sepolicy/public. Sono incluse le norme esportate per l'utilizzo
nelle norme specifiche del fornitore. Tutto rientra nell'infrastruttura di compatibilità
di Android 8.0.
Le norme pubbliche sono destinate a essere mantenute nelle release, pertanto puoi includere qualsiasi cosa
/public
nei tuoi criteri personalizzati. Per questo motivo, il tipo di criterio che può essere inserito in/public
è più limitato. Considerala l'API dei criteri esportata della piattaforma: tutto ciò che riguarda l'interfaccia tra/system
e/vendor
appartiene a questa sezione. - system/sepolicy/private. Sono inclusi i criteri necessari per il funzionamento dell'immagine di sistema, ma i criteri relativi alle immagini del fornitore non devono essere presi in considerazione.
- system/sepolicy/vendor. Include le norme per i componenti che vanno in
/vendor
, ma esistono nella struttura ad albero della piattaforma di base (non nelle directory specifiche del dispositivo). Si tratta di un artefatto della distinta tra dispositivi e componenti globali del sistema di compilazione. A livello concettuale, fa parte delle norme specifiche per i dispositivi descritte di seguito. - device/manufacturer/device-name/sepolicy. Include criteri specifici per i dispositivi. Sono incluse anche le personalizzazioni del dispositivo per le norme, che in Android 8.0 e versioni successive corrispondono alle norme per i componenti sull'immagine del fornitore.
In Android 11 e versioni successive, le partizioni system_ext e product possono includere anche criteri specifici per le partizioni. I criteri system_ext e product sono inoltre suddivisi in pubblici e privati e i fornitori possono utilizzare i criteri pubblici di system_ext e product, come i criteri di sistema.
SYSTEM_EXT_PUBLIC_SEPOLICY_DIRS
. Sono inclusi i criteri esportati per essere utilizzati nei criteri specifici del fornitore. Installato nella partizione system_ext.SYSTEM_EXT_PRIVATE_SEPOLICY_DIRS
. Include i criteri necessari per il funzionamento dell'immagine system_ext, ma di cui i criteri dell'immagine del fornitore non devono essere a conoscenza. Installato nella partizione system_ext.PRODUCT_PUBLIC_SEPOLICY_DIRS
. Include il criterio esportato per l'utilizzo in criteri specifici del fornitore. Installato nella partizione del prodotto.PRODUCT_PRIVATE_SEPOLICY_DIRS
. Sono incluse le norme necessarie per il funzionamento dell'immagine del prodotto, ma le norme relative alle immagini del fornitore non devono essere prese in considerazione. Installato nella partizione del prodotto.
Scenari di criteri supportati
Sui dispositivi lanciati con Android 8.0 e versioni successive, l'immagine del fornitore deve funzionare con l'immagine di sistema OEM e l'immagine di sistema AOSP di riferimento fornite da Google (e superare il CTS su questa immagine di riferimento). Questi requisiti garantiscono una separazione chiara tra il framework e il codice del fornitore. Questi dispositivi supportano i seguenti scenari.
estensioni solo immagini del fornitore
Esempio: aggiunta di un nuovo servizio a vndservicemanager
dall'immagine del fornitore che supporta i processi dell'immagine del fornitore.
Come per i dispositivi lanciati con versioni precedenti di Android, aggiungi la personalizzazione specifica del dispositivo in device/manufacturer/device-name/sepolicy
.
Le nuove norme che regolano il modo in cui i componenti del fornitore interagiscono con (solo) altri componenti del fornitore devono coinvolgere tipi presenti solo in
device/manufacturer/device-name/sepolicy
.
Le norme scritte qui consentono il funzionamento del codice del fornitore, non verranno aggiornate nell'ambito di un aggiornamento OTA solo del framework e sono presenti nelle norme combinate su un dispositivo con l'immagine di sistema AOSP di riferimento.
supporto immagini del fornitore per lavorare con AOSP
Esempio: aggiunta di un nuovo processo (registrato con
hwservicemanager
dall'immagine del fornitore) che implementa un
HAL definito da AOSP.
Come per i dispositivi lanciati con versioni precedenti di Android, esegui la personalizzazione specifica del dispositivo in device/manufacturer/device-name/sepolicy
.
Il criterio esportato nell'ambito di system/sepolicy/public/
è disponibile per l'utilizzo e viene fornito nell'ambito delle norme del fornitore. I tipi e gli attributi delle norme pubbliche possono essere utilizzati nelle nuove regole che definiscono le interazioni con i nuovi bit specifici del fornitore, rispettando le limitazioni neverallow
fornite. Come nel caso del solo fornitore, i nuovi criteri in questo caso non verranno aggiornati
nell'ambito di un'agenzia di viaggi online esclusiva ed è presente nei criteri combinati su un
dispositivo con l'immagine di sistema AOSP di riferimento.
Estensioni solo per immagini di sistema
Esempio: aggiunta di un nuovo servizio (registrato con servicemanager) a cui accedono solo altri processi dall'immagine di sistema.
Aggiungi questo criterio a system/sepolicy/private
. Puoi aggiungere ulteriori processi o oggetti per abilitare la funzionalità in un'immagine di sistema del partner, a condizione che questi nuovi bit non debbano interagire con i nuovi componenti dell'immagine del fornitore (in particolare, questi processi o oggetti devono funzionare completamente senza il criterio dell'immagine del fornitore). Il criterio esportato da system/sepolicy/public
è disponibile qui, così come per le estensioni solo con immagine del fornitore. Questo criterio fa parte dell'immagine di sistema e potrebbe essere aggiornato in un'OTA solo del framework, ma non sarà presente quando si utilizza l'immagine di sistema AOSP di riferimento.
Estensioni vendor-image che forniscono componenti AOSP estesi
Esempio: un nuovo HAL non AOSP da utilizzare da parte di client estesi che esiste anche nell'immagine di sistema AOSP (ad esempio un system_server esteso).
I criteri per l'interazione tra il sistema e il fornitore devono essere inclusi nella directory
device/manufacturer/device-name/sepolicy
fornita nella partizione del fornitore.
È simile allo scenario precedente di aggiunta del supporto delle immagini del fornitore per il funzionamento con l'immagine AOSP di riferimento, tranne per il fatto che i componenti AOSP modificati potrebbero anche richiedere criteri aggiuntivi per funzionare correttamente con il resto della partizione di sistema (il che va bene purché abbiano ancora le etichette di tipo AOSP pubblico).
Le norme per l'interazione dei componenti AOSP pubblici con le estensioni solo per l'immagine di sistema devono essere in system/sepolicy/private
.
Estensioni dell'immagine di sistema che accedono solo alle interfacce AOSP
Esempio: un nuovo processo di sistema non AOSP deve accedere a un HAL su cui si basa AOSP.
È simile all'esempio di estensione solo immagine del sistema, tranne per il fatto che i nuovi componenti di sistema possono interagire tramite l'interfacciasystem/vendor
. I criteri per il nuovo componente di sistema devono essere inseriti in system/sepolicy/private
, il che è accettabile a condizione che vengano utilizzati tramite un'interfaccia già stabilita da AOSP in system/sepolicy/public
(ovvero che siano presenti i tipi e gli attributi richiesti per la funzionalità). Sebbene i criteri possano essere inclusi nei criteri specifici del dispositivo, non sarà possibile utilizzare altri tipi di system/sepolicy/private
o modificarli (in alcun modo che influisca sui criteri) a seguito di un aggiornamento solo del framework. Il criterio può essere modificato in un'OTA solo del framework, ma non sarà presente se si utilizza un'immagine di sistema AOSP (che non avrà nemmeno il nuovo componente di sistema).
estensioni immagine del fornitore che pubblicano nuovi componenti di sistema
Esempio: aggiunta di un nuovo HAL non AOSP da utilizzare da parte di un processo client senza un analogo AOSP (e quindi richiede un proprio dominio).
Come nell'esempio di estensioni AOSP, le norme per le interazioni tra il sistema e il fornitore devono essere inserite nella directory
device/manufacturer/device-name/sepolicy
fornita nella partizione del fornitore
(per garantire che le norme di sistema non siano a conoscenza di dettagli specifici del fornitore). Puoi
aggiungere nuovi tipi pubblici che estendono il criterio in
system/sepolicy/public
; questa operazione deve essere eseguita solo in aggiunta al
criterio AOSP esistente, ovvero non rimuovere il criterio pubblico AOSP. I nuovi tipi pubblici possono quindi essere utilizzati per i criteri in system/sepolicy/private
e in
device/manufacturer/device-name/sepolicy
.
Tieni presente che ogni aggiunta a system/sepolicy/public
aggiunge complessità mostrando una nuova garanzia di compatibilità che deve essere monitorata in un file di mappatura ed è soggetta ad altre limitazioni. Solo i nuovi tipi e
le regole di autorizzazione corrispondenti possono essere aggiunti in system/sepolicy/public
;
gli attributi e altre istruzioni relative ai criteri non sono supportati. Inoltre, i nuovi tipi pubblici non possono essere utilizzati per etichettare direttamente gli oggetti nel criterio /vendor
.
Scenari di criteri non supportati
I dispositivi lanciati con Android 8.0 e versioni successive non supportano lo scenario e gli esempi di norme riportati di seguito.
Estensioni aggiuntive all'immagine di sistema che richiedono l'autorizzazione per i nuovi componenti dell'immagine del fornitore dopo un aggiornamento OTA solo del framework
Esempio: nella prossima release di Android viene aggiunto un nuovo processo di sistema non AOSP che richiede un proprio dominio e deve accedere a un nuovo HAL non AOSP.
Simile all'interazione di nuovi componenti di sistema e fornitori (non AOSP), tranne per il fatto che il nuovo tipo di sistema è stato introdotto in un'agenzia di viaggi online basata solo sul framework. Sebbene il nuovo tipo possa essere aggiunto al criterio in
system/sepolicy/public
, il criterio del fornitore esistente non è a conoscenza
del nuovo tipo in quanto monitora solo le norme pubbliche del sistema Android 8.0.
AOSP gestisce questo problema esponendo le risorse fornite dal fornitore tramite un attributo (ad esempio, l'attributo hal_foo
), ma poiché le estensioni dei partner di attributo non sono supportate in system/sepolicy/public
, questo metodo non è disponibile per i criteri del fornitore. L'accesso deve essere fornito da un tipo pubblico esistente in precedenza.
Esempio: una modifica a un processo di sistema (AOSP o non AOSP) deve cambiare il modo in cui interagisce con il nuovo componente del fornitore non AOSP.
I criteri nell'immagine di sistema devono essere scritti senza conoscenza di personalizzazioni specifiche del fornitore. I criteri relativi a interfacce specifiche in AOSP vengono quindi esposti tramite attributi in system/sepolicy/public, in modo che i criteri del fornitore possano attivare i futuri criteri di sistema che utilizzano questi attributi. Tuttavia,
le estensioni degli attributi in system/sepolicy/public
non sono
supportate, quindi tutti i criteri che determinano il modo in cui i componenti del sistema interagiscono
con i nuovi componenti del fornitore (e che non è gestito dagli attributi già
presenti in AOSP system/sepolicy/public
) devono essere in
device/manufacturer/device-name/sepolicy
.
Ciò significa che i tipi di sistema non possono modificare
l'accesso consentito ai tipi di fornitori nell'ambito di un aggiornamento OTA solo del framework.