Dopo aver integrato il livello base della funzionalità di SELinux e aver analizzato a fondo i risultati, puoi aggiungere le tue impostazioni dei criteri per coprire le tue personalizzazioni al sistema operativo Android. Questi criteri devono comunque soddisfare i requisiti del programma di compatibilità Android e non devono rimuovere le impostazioni predefinite di SELinux.
I produttori non dovrebbero rimuovere la politica SELinux esistente. Altrimenti, rischiano di rompere l'implementazione di Android SELinux e le applicazioni che governa. Ciò include applicazioni di terze parti che probabilmente dovranno essere migliorate per essere conformi e operative. Le applicazioni non devono richiedere modifiche per continuare a funzionare su dispositivi abilitati per SELinux.
Quando inizi a personalizzare SELinux, ricorda di:
- Scrivi la politica di SELinux per tutti i nuovi demoni
- Usa domini predefiniti quando appropriato
- Assegna un dominio a qualsiasi processo generato come servizio
init
- Acquisisci familiarità con le macro prima di scrivere la politica
- Invia le modifiche alla policy principale ad AOSP
E ricorda di non:
- Crea criteri incompatibili
- Consenti la personalizzazione dei criteri dell'utente finale
- Consenti personalizzazioni dei criteri MDM
- Spaventa gli utenti con violazioni delle norme
- Aggiungi backdoor
Per i requisiti specifici, vedere la sezione Funzionalità di sicurezza del kernel del documento Definizione di compatibilità Android .
SELinux utilizza un approccio whitelist, il che significa che tutti gli accessi devono essere esplicitamente consentiti nella policy per poter essere concessi. Poiché la politica SELinux predefinita di Android supporta già il progetto Open Source di Android, non è necessario modificare le impostazioni di SELinux in alcun modo. Se personalizzi le impostazioni di SELinux, fai molta attenzione a non interrompere le applicazioni esistenti. Per iniziare:
- Usa il kernel Android più recente .
- Adottare il principio del privilegio minimo .
- Indirizza solo le tue aggiunte ad Android. Il criterio predefinito funziona automaticamente con la codebase di Android Open Source Project .
- Compartimenta i componenti software in moduli che svolgono attività singole.
- Crea politiche SELinux che isolano tali attività da funzioni non correlate.
- Metti quelle politiche nei file
*.te
(l'estensione per i file di origine delle politiche SELinux) all'interno della directory/device/ manufacturer / device-name /sepolicy
e usa le variabiliBOARD_SEPOLICY
per includerle nella tua build. - Rendi permissivi i nuovi domini inizialmente. Questo viene fatto utilizzando una dichiarazione permissiva nel file
.te
del dominio. - Analizza i risultati e perfeziona le definizioni di dominio.
- Rimuovere la dichiarazione permissiva quando non vengono visualizzati ulteriori rifiuti nelle build di userdebug.
Dopo aver integrato la modifica della politica di SELinux, aggiungere un passaggio al flusso di lavoro di sviluppo per garantire la compatibilità con SELinux in futuro. In un processo di sviluppo software ideale, la politica di SELinux cambia solo quando cambia il modello software e non l'effettiva implementazione.
Quando inizi a personalizzare SELinux, controlla prima le tue 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é qualsiasi criterio associato creato dall'OEM, prima di attivare la modalità di applicazione.
Per evitare problemi inutili, è meglio essere troppo ampi e compatibili piuttosto che troppo restrittivi e incompatibili, il che si traduce in funzioni del dispositivo interrotte. Al contrario, se le tue modifiche andranno a beneficio di altri, dovresti inviare le modifiche alla politica predefinita di SELinux come patch . Se la patch viene applicata al criterio di sicurezza predefinito, non sarà necessario apportare questa modifica con ogni nuova versione di Android.
Esempi di dichiarazioni politiche
SELinux si basa sul linguaggio del computer M4 e quindi supporta una varietà di macro per risparmiare tempo.
Nell'esempio seguente, a tutti i domini viene concesso l'accesso per leggere o scrivere in /dev/null
e leggere 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 };
Questa stessa istruzione può essere scritta con le macro SELinux *_file_perms
(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;
Esempio di politica
Ecco un esempio completo di policy per DHCP, che esaminiamo di seguito:
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 dalla policy di sicurezza di base ( domain
). Dagli esempi di istruzioni precedenti, DHCP può leggere e scrivere in /dev/null
.
Nella seconda riga, DHCP è identificato come dominio permissivo.
Nella init_daemon_domain(dhcp)
, la politica afferma che DHCP viene generato da init
e gli è consentito comunicare con esso.
Nella net_domain(dhcp)
, il criterio consente a DHCP di utilizzare la funzionalità di rete comune dal dominio di net
, ad esempio la lettura e la scrittura di pacchetti TCP, la comunicazione tramite socket e l'esecuzione di richieste DNS.
Nella riga allow dhcp proc_net:file write;
, la politica afferma che DHCP può scrivere su file specifici in /proc
. Questa riga mostra l'etichettatura dei file a grana fine di SELinux. Utilizza l'etichetta proc_net
per limitare l'accesso in scrittura solo ai file in /proc/sys/net
.
Il blocco finale dell'esempio che inizia con allow dhcp netd:fd use;
illustra come le applicazioni possono interagire tra loro. La politica dice che DHCP e netd possono comunicare tra loro tramite descrittori di file, file FIFO, socket di datagrammi e socket di flusso UNIX. DHCP può solo leggere e scrivere dai socket del datagramma e dai socket del flusso UNIX e non crearli o aprirli.
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 |
processi | 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 |
capacità | 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 |
DI PIÙ | E ALTRO |
regole mai consentite
Le regole neverallow
di SELinux proibiscono comportamenti che non dovrebbero mai verificarsi. Con i test di compatibilità , le regole neverallow
di SELinux vengono ora applicate su tutti i dispositivi.
Le seguenti linee guida hanno lo scopo di aiutare i produttori a evitare errori relativi alle regole di neverallow
durante la personalizzazione. I numeri delle regole qui utilizzati corrispondono ad Android 5.1 e sono soggetti a modifiche in base alla versione.
Regola 48: neverallow { domain -debuggerd -vold -dumpstate -system_server } self:capability sys_ptrace;
Vedi la pagina man per ptrace
. La funzionalità sys_ptrace
garantisce la possibilità di eseguire il ptrace
di qualsiasi processo, il che consente un grande controllo su altri processi e dovrebbe appartenere solo ai componenti di sistema designati, delineati nella regola. La necessità di questa funzionalità spesso indica la presenza di qualcosa che non è pensato per build rivolte all'utente o funzionalità che non sono necessarie. Rimuovere 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. In particolare, 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 riscontra un problema con questa regola neverallow
è spostare il codice incriminato nella partizione /system
.
Personalizzazione di SEPolicy in Android 8.0+
Questa sezione fornisce le linee guida per i criteri SELinux del fornitore in Android 8.0 e versioni successive, inclusi i dettagli sulle estensioni SEPolicy e SEPolicy di Android Open Source Project (AOSP). Per ulteriori informazioni su come la politica di SELinux viene mantenuta compatibile tra le partizioni e le versioni di Android, vedere Compatibilità .
Posizionamento della politica
In Android 7.0 e versioni precedenti, i produttori di dispositivi potevano aggiungere criteri a BOARD_SEPOLICY_DIRS
, inclusi criteri volti ad aumentare i criteri AOSP su diversi tipi di dispositivi. In Android 8.0 e versioni successive, l'aggiunta di una policy a BOARD_SEPOLICY_DIRS
inserisce la policy solo nell'immagine del fornitore.
In Android 8.0 e versioni successive, i criteri esistono nelle seguenti posizioni in AOSP:
- sistema/sepolicy/pubblico . Include la politica esportata per l'uso nella politica specifica del fornitore. Tutto va nell'infrastruttura di compatibilità con Android 8.0. La policy pubblica è pensata per persistere tra le versioni in modo da poter includere qualsiasi cosa
/public
nella tua policy personalizzata. Per questo motivo, il tipo di criterio che può essere inserito in/public
è più limitato. Considera questa API della politica esportata dalla piattaforma: tutto ciò che riguarda l'interfaccia tra/system
e/vendor
appartiene qui. - sistema/sepolicy/privato . Include la politica necessaria per il funzionamento dell'immagine di sistema, ma di quale politica dell'immagine del fornitore non dovrebbe essere a conoscenza.
- sistema/sepolicy/fornitore . Include la politica per i componenti che vanno in
/vendor
ma esistono nell'albero della piattaforma principale (non directory specifiche del dispositivo). Questo è un artefatto della distinzione del sistema di build tra dispositivi e componenti globali; concettualmente questa è una parte della politica specifica del dispositivo descritta di seguito. - dispositivo/ manufacturer / device-name /sepolicy . Include criteri specifici del dispositivo. Include anche le personalizzazioni del dispositivo in base ai criteri, che in Android 8.0 e versioni successive corrispondono ai criteri per i componenti nell'immagine del fornitore.
In Android 11 e versioni successive, le partizioni system_ext e prodotto possono includere anche criteri specifici della partizione. Anche le policy di system_ext e product sono suddivise in public e private e i fornitori possono utilizzare le policy public di system_ext e product, come la policy di sistema.
-
SYSTEM_EXT_PUBLIC_SEPOLICY_DIRS
. Include la politica esportata per l'uso nella politica specifica del fornitore. Installato nella partizione system_ext. -
SYSTEM_EXT_PRIVATE_SEPOLICY_DIRS
. Include la politica necessaria per il funzionamento dell'immagine system_ext, ma di quale politica dell'immagine del fornitore non dovrebbe essere a conoscenza. Installato nella partizione system_ext. -
PRODUCT_PUBLIC_SEPOLICY_DIRS
. Include la politica esportata per l'uso nella politica specifica del fornitore. Installato nella partizione del prodotto. -
PRODUCT_PRIVATE_SEPOLICY_DIRS
. Include la politica necessaria per il funzionamento dell'immagine del prodotto, ma di quale politica dell'immagine del fornitore non dovrebbe essere a conoscenza. Installato nella partizione del prodotto.
Scenari politici supportati
Sui dispositivi con Android 8.0 e versioni successive, l'immagine del fornitore deve funzionare con l'immagine del sistema OEM e l'immagine del sistema AOSP di riferimento fornita da Google (e passare CTS su questa immagine di riferimento). Questi requisiti garantiscono una netta separazione tra il framework e il codice del fornitore. Tali dispositivi supportano i seguenti scenari.
estensioni solo immagine del fornitore
Esempio : aggiunta di un nuovo servizio a vndservicemanager
del fornitore che supporta i processi dall'immagine del fornitore.
Come per i dispositivi avviati con versioni precedenti di Android, aggiungi la personalizzazione specifica del dispositivo in device/ manufacturer / device-name /sepolicy
. La nuova politica che disciplina il modo in cui i componenti del fornitore interagiscono con (solo) altri componenti del fornitore dovrebbe coinvolgere i tipi presenti solo in device/ manufacturer / device-name /sepolicy
. Il criterio scritto qui consente al codice del fornitore di funzionare, non verrà aggiornato come parte di un'OTA solo framework e sarà presente nel criterio combinato su un dispositivo con l'immagine di sistema AOSP di riferimento.
supporto dell'immagine del fornitore per lavorare con AOSP
Esempio : aggiunta di un nuovo processo (registrato con hwservicemanager
del fornitore) che implementa un HAL definito da AOSP.
Come per i dispositivi avviati con versioni precedenti di Android, esegui la personalizzazione specifica del dispositivo in device/ manufacturer / device-name /sepolicy
. La politica esportata come parte di system/sepolicy/public/
è disponibile per l'uso e viene fornita come parte della politica del fornitore. I tipi e gli attributi della politica pubblica possono essere utilizzati nelle nuove regole che dettano le interazioni con i nuovi bit specifici del fornitore, fatte salve le restrizioni di neverallow
fornite. Come nel caso del solo fornitore, la nuova policy qui non verrà aggiornata come parte di un'OTA solo framework e sarà presente nella policy combinata su un dispositivo con l'immagine di sistema AOSP di riferimento.
estensioni solo immagine di sistema
Esempio : aggiunta di un nuovo servizio (registrato con servicemanager) a cui accedono solo altri processi dall'immagine di sistema.
Aggiungi questa politica a system/sepolicy/private
. È possibile aggiungere processi o oggetti aggiuntivi per abilitare la funzionalità in un'immagine del sistema partner, a condizione che quei nuovi bit non debbano interagire con i nuovi componenti nell'immagine del fornitore (in particolare, tali processi o oggetti devono funzionare completamente senza la politica dell'immagine del fornitore) . La politica esportata da system/sepolicy/public
è disponibile qui proprio come per le estensioni solo immagine del fornitore. Questo criterio fa parte dell'immagine di sistema e potrebbe essere aggiornato in un'OTA solo framework, ma non sarà presente quando si utilizza l'immagine di sistema AOSP di riferimento.
estensioni dell'immagine del fornitore che servono componenti AOSP estesi
Esempio: un nuovo HAL non AOSP per l'utilizzo da parte di client estesi che esistono anche nell'immagine di sistema AOSP (come un server_sistema esteso).
La politica per l'interazione tra il sistema e il fornitore deve essere inclusa nella directory device/ manufacturer / device-name /sepolicy
fornita nella partizione del fornitore. Questo è simile allo scenario precedente dell'aggiunta del supporto dell'immagine del fornitore per funzionare 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é avere le etichette di tipo AOSP pubbliche).
La politica per l'interazione dei componenti AOSP pubblici con le estensioni di sola immagine di sistema dovrebbe 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.
Questo è simile all'esempio di estensione solo immagine di sistema , tranne per il fatto che i nuovi componenti di sistema possono interagire attraverso l'interfaccia system/vendor
. La policy per il nuovo componente di sistema deve andare in system/sepolicy/private
, che è accettabile a condizione che sia tramite un'interfaccia già stabilita da AOSP in system/sepolicy/public
(cioè i tipi e gli attributi richiesti per la funzionalità sono presenti). Sebbene il criterio possa essere incluso nel criterio specifico del dispositivo, non sarebbe in grado di utilizzare altri tipi di system/sepolicy/private
o modificare (in qualsiasi modo che influisca sui criteri) a seguito di un aggiornamento del solo framework. La politica può essere modificata in un'OTA solo framework, ma non sarà presente quando si utilizza un'immagine di sistema AOSP (che non avrà nemmeno il nuovo componente di sistema).
estensioni dell'immagine del fornitore che servono nuovi componenti di sistema
Esempio: aggiunta di un nuovo HAL non AOSP per l'utilizzo da parte di un processo client senza un analogo AOSP (e quindi richiede il proprio dominio).
Analogamente all'esempio AOSP-extensions , la politica per le interazioni tra sistema e fornitore deve essere contenuta nella directory device/ manufacturer / device-name /sepolicy
fornita nella partizione del fornitore (per garantire che la politica di sistema non conosca i dettagli specifici del fornitore). È possibile aggiungere nuovi tipi pubblici che estendono la politica in system/sepolicy/public
; questo dovrebbe essere fatto solo in aggiunta alla politica AOSP esistente, cioè non rimuovere la politica pubblica 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à esponendo una nuova garanzia di compatibilità che deve essere tracciata in un file di mappatura e che è soggetta ad altre restrizioni. Solo i nuovi tipi e le regole di autorizzazione corrispondenti possono essere aggiunti in system/sepolicy/public
; attributi e altre dichiarazioni di 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 avviati con Android 8.0 e versioni successive non supportano lo scenario e gli esempi di criteri seguenti.
Estensioni aggiuntive all'immagine di sistema che richiedono l'autorizzazione per i nuovi componenti dell'immagine del fornitore dopo un'OTA solo framework
Esempio: un nuovo processo di sistema non AOSP, che richiede il proprio dominio, viene aggiunto nella prossima versione di Android e richiede l'accesso a un nuovo HAL non AOSP.
Simile all'interazione tra il nuovo sistema (non AOSP) e i componenti del fornitore , tranne per il fatto che il nuovo tipo di sistema è stato introdotto in un OTA solo 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 poiché tiene traccia solo del criterio pubblico del sistema Android 8.0. AOSP gestisce questo esponendo le risorse fornite dal fornitore tramite un attributo (ad es. hal_foo
attributo) ma poiché le estensioni del partner di attributo non sono supportate in system/sepolicy/public
, questo metodo non è disponibile per la politica del fornitore. L'accesso deve essere fornito da un tipo pubblico preesistente.
Esempio: una modifica a un processo di sistema (AOSP o non AOSP) deve modificare il modo in cui interagisce con il nuovo componente del fornitore non AOSP.
La politica sull'immagine di sistema deve essere scritta senza conoscere le personalizzazioni del fornitore specifico. La politica relativa a interfacce specifiche in AOSP viene quindi esposta tramite attributi in system/sepolicy/public in modo che la politica del fornitore possa accettare la futura politica di sistema che utilizza questi attributi. Tuttavia, le estensioni degli attributi in system/sepolicy/public
non sono supportate , quindi tutte le policy che determinano il modo in cui i componenti del sistema interagiscono con i nuovi componenti del fornitore (e che non sono gestite 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 come parte di un'OTA solo framework.