Google is committed to advancing racial equity for Black communities. See how.
Questa pagina è stata tradotta dall'API Cloud Translation.
Switch to English

Personalizzare SELinux

Dopo aver integrato il livello base della funzionalità SELinux e analizzato accuratamente i risultati, è possibile aggiungere le proprie impostazioni dei criteri per coprire le 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 dovrebbero rimuovere la politica SELinux esistente. Altrimenti, rischiano di rompere l'implementazione di Android SELinux e le applicazioni che gestisce. Ciò include applicazioni di terze parti che probabilmente dovranno essere migliorate per essere conformi e operative. Le applicazioni non devono richiedere alcuna modifica per continuare a funzionare sui dispositivi abilitati per SELinux.

Quando inizi a personalizzare SELinux, ricorda di:

  • Scrivi la policy SELinux per tutti i nuovi demoni
  • Usa domini predefiniti quando appropriato
  • Assegna un dominio a qualsiasi processo generato come servizio di init
  • Acquisire familiarità con le macro prima di scrivere la politica
  • Invia le modifiche alla policy di base ad AOSP

E ricorda di non:

  • Crea criterio incompatibile
  • Consenti la personalizzazione dei criteri dell'utente finale
  • Consenti personalizzazioni dei criteri MDM
  • Spaventa gli utenti con violazioni delle norme
  • Aggiungi backdoor

Vedere la sezione Funzionalità di sicurezza del kernel del documento Definizione di compatibilità Android per requisiti specifici.

SELinux utilizza un approccio whitelist, il che significa che tutti gli accessi devono essere esplicitamente consentiti nella policy per poter essere concessi. Poiché la policy SELinux predefinita di Android supporta già Android Open Source Project, non è necessario modificare le impostazioni di SELinux in alcun modo. Se personalizzi le impostazioni di SELinux, fai molta attenzione a non rompere le applicazioni esistenti. Per iniziare:

  1. Usa l' ultimo kernel Android .
  2. Adotta il principio del privilegio minimo .
  3. Affronta solo le tue aggiunte ad Android. Il criterio predefinito funziona automaticamente con la base di codice del progetto Android Open Source .
  4. Suddividere in compartimenti i componenti software in moduli che conducono compiti singolari.
  5. Crea politiche SELinux che isolano queste attività da funzioni non correlate.
  6. Metti questi criteri nei file *.te (l'estensione per i file sorgente dei criteri SELinux) nella directory /device/ manufacturer / device-name /sepolicy e usa BOARD_SEPOLICY variabili BOARD_SEPOLICY per includerli nella tua build.
  7. Rendi inizialmente permissivi i nuovi domini. Questo viene fatto utilizzando una dichiarazione permissiva nel file .te del dominio.
  8. Analizza i risultati e perfeziona le definizioni del tuo dominio.
  9. Rimuovere la dichiarazione permissiva quando non compaiono ulteriori negazioni nelle build userdebug.

Dopo aver integrato la modifica della politica di 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, 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 eccessivi e eccessivamente compatibili che troppo restrittivi e incompatibili, il che si traduce in funzioni del dispositivo danneggiate. Al contrario, se le tue modifiche andranno a beneficio di altri, dovresti inviare le modifiche alla policy SELinux predefinita come patch . Se la patch viene applicata al criterio di sicurezza predefinito, non sarà necessario apportare questa modifica a 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 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 };

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;

Politica di esempio

Ecco un esempio completo di criteri 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 politica di sicurezza di base ( domain ). Dagli esempi di istruzioni precedenti, DHCP può leggere e scrivere su /dev/null .

Nella seconda riga, DHCP è identificato come un dominio permissivo.

Nella init_daemon_domain(dhcp) , il criterio afferma che DHCP viene generato da init ed è autorizzato a comunicare con esso.

Nella net_domain(dhcp) , il criterio consente a DHCP di utilizzare le funzionalità di rete comuni dal dominio di net come la lettura e la scrittura di pacchetti TCP, la comunicazione sui socket e la conduzione di richieste DNS.

Nella riga allow dhcp proc_net:file write; , il criterio afferma che DHCP può scrivere su file specifici in /proc . Questa riga mostra l'etichettatura dei file a grana fine di SELinux. Usa 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; descrive come le applicazioni possono essere autorizzate a interagire tra loro. La politica dice che DHCP e netd possono comunicare tra loro tramite descrittori di file, file FIFO, socket di datagramma 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

non consentire mai regole

SELinux non neverallow mai che le regole proibiscano comportamenti che non dovrebbero mai verificarsi. Con i test di compatibilità , SELinux non neverallow regole vengano ora applicate su tutti i dispositivi.

Le seguenti linee guida hanno lo scopo di aiutare i produttori a evitare errori relativi a non neverallow regole durante la personalizzazione. I numeri delle regole qui utilizzati corrispondono ad Android 5.1 e sono soggetti a modifiche in base al rilascio.

Regola 48: non neverallow { domain -debuggerd -vold -dumpstate -system_server } self:capability sys_ptrace;
Vedere la pagina man per ptrace . La funzionalità sys_ptrace garantisce la capacità di ptrace 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 capacità spesso indica la presenza di qualcosa che non è pensato per build rivolte agli utenti o funzionalità che non sono necessarie. Rimuovere il componente non necessario.

Regola 76: non 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 migliore soluzione quando si incontra un problema con questa regola neverallow è spostare il codice offensivo nella partizione /system .

Personalizzazione di SEPolicy in Android 8.0+

Questa sezione fornisce le linee guida per la policy SELinux del fornitore in Android 8.0 e versioni successive, inclusi i dettagli sulle estensioni SEPolicy ed SEPolicy di Android Open Source Project (AOSP). Per ulteriori informazioni su come la politica SELinux viene mantenuta compatibile tra le partizioni e le versioni di Android, vedere Compatibilità .

Posizionamento delle politiche

In Android 7.0 e BOARD_SEPOLICY_DIRS precedenti, i produttori di dispositivi potevano aggiungere criteri a BOARD_SEPOLICY_DIRS , inclusi criteri intesi 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:

  • system / sepolicy / public . Include la politica esportata per l'uso nella politica specifica del fornitore. Tutto va nell'infrastruttura di compatibilità di Android 8.0. La politica pubblica è destinata a persistere tra le versioni in modo da poter includere qualsiasi cosa /public nella politica personalizzata. Per questo motivo, il tipo di criterio che può essere inserito in /public è più limitato. Considera questa l'API dei criteri esportati dalla piattaforma: tutto ciò che riguarda l'interfaccia tra /system e /vendor appartiene qui.
  • system / sepolicy / private . Include la politica necessaria per il funzionamento dell'immagine del sistema, ma di cui la politica dell'immagine del fornitore non dovrebbe essere a conoscenza.
  • system / sepolicy / vendor . Include la politica per i componenti che vanno in /vendor ma esistono nell'albero della piattaforma principale (non nelle directory specifiche del dispositivo). Questo è un artefatto della distinzione del sistema di compilazione tra dispositivi e componenti globali; concettualmente questo fa parte della politica specifica del dispositivo descritta di seguito.
  • dispositivo / manufacturer / device-name / sepolicy . Include la policy specifica del dispositivo. Include anche le personalizzazioni del dispositivo per i criteri, che in Android 8.0 e versioni successive corrispondono ai criteri per i componenti sull'immagine del fornitore.

Scenari di policy supportati

Sui dispositivi che si avviano 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 trasmettere 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 che si avviano con le versioni precedenti di Android, aggiungi la personalizzazione specifica del device/ manufacturer / device-name /sepolicy 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 . La policy scritta qui consente il funzionamento del codice sul fornitore, non verrà aggiornata come parte di un OTA solo framework e sarà presente nella policy combinata su un dispositivo con l'immagine del 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 che si avviano con le versioni precedenti di Android, esegui la personalizzazione specifica del device/ manufacturer / device-name /sepolicy in device/ manufacturer / device-name /sepolicy . La policy esportata come parte di system/sepolicy/public/ è disponibile per l'uso e viene fornita come parte della policy del fornitore. Tipi e attributi della politica pubblica possono essere utilizzati in nuove regole che determinano le interazioni con i nuovi bit specifici del fornitore, fatte neverallow restrizioni fornite neverallow . 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 del sistema AOSP di riferimento.

estensioni di sola immagine di sistema

Esempio : aggiunta di un nuovo servizio (registrato con servicemanager) a cui si accede solo da altri processi dall'immagine del sistema.

Aggiungi questo criterio 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 nuovi componenti sull'immagine del fornitore (in particolare, tali processi o oggetti devono funzionare completamente senza policy dall'immagine del fornitore) . La policy esportata da system/sepolicy/public è disponibile qui proprio come lo è per le estensioni solo immagine del fornitore. Questa politica fa parte dell'immagine del sistema e potrebbe essere aggiornata in un OTA solo framework, ma non sarà presente quando si utilizza l'immagine del sistema AOSP di riferimento.

estensioni immagine del fornitore che servono componenti AOSP estesi

Esempio: un nuovo HAL non AOSP per l'uso da parte di client estesi che esistono anche nell'immagine del sistema AOSP (come un system_server esteso).

La politica per l'interazione tra il sistema e il fornitore deve essere inclusa nella directory device/ manufacturer / device-name /sepolicy fornita sulla partizione del fornitore. Questo è simile allo scenario precedente di aggiunta del supporto dell'immagine del fornitore per lavorare con l'immagine AOSP di riferimento, tranne per il fatto che i componenti AOSP modificati potrebbero richiedere criteri aggiuntivi per funzionare correttamente con il resto della partizione di sistema (che va bene fintanto che continuano hanno 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 dell'estensione solo immagine di sistema , tranne per il fatto che i nuovi componenti di sistema possono interagire attraverso l'interfaccia del system/vendor . La policy per il nuovo componente di sistema deve andare in system/sepolicy/private , il che è accettabile a condizione che sia attraverso un'interfaccia già stabilita da AOSP in system/sepolicy/public (cioè i tipi e gli attributi richiesti per la funzionalità sono presenti). Sebbene la policy possa essere inclusa nella policy specifica del dispositivo, non sarebbe in grado di utilizzare altri tipi di system/sepolicy/private o modificare (in qualsiasi modo che influisce sulla policy) a seguito di un aggiornamento solo del 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 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 delle estensioni AOSP , la politica per le interazioni tra il sistema e il fornitore deve essere device/ manufacturer / device-name /sepolicy directory device/ manufacturer / device-name /sepolicy fornita sulla partizione del fornitore (per garantire che la politica di sistema non sia a conoscenza dei 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 mapping e che è soggetta ad altre restrizioni. Solo nuovi tipi e le corrispondenti regole di autorizzazione 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 nella politica /vendor .

Scenari di policy non supportati

I dispositivi che si avviano con Android 8.0 e versioni successive non supportano il seguente scenario di criteri ed esempi.

Ulteriori estensioni 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 necessita dell'accesso a un nuovo HAL non AOSP.

Simile al nuovo sistema (non AOSP) e all'interazione dei componenti del fornitore , tranne per il fatto che il nuovo tipo di sistema viene introdotto in un'OTA solo framework. Sebbene il nuovo tipo possa essere aggiunto alla policy in system/sepolicy/public , la policy del fornitore esistente non è a conoscenza del nuovo tipo poiché monitora solo la policy pubblica del sistema Android 8.0. AOSP gestisce questo esponendo le risorse fornite dal fornitore tramite un attributo (ad es hal_foo Attributo hal_foo ) ma poiché le estensioni dei partner degli attributi 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 esistente in precedenza.

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 del sistema deve essere scritta senza la conoscenza di personalizzazioni specifiche del fornitore. La politica relativa a interfacce specifiche in AOSP viene quindi esposta tramite attributi in system / sepolicy / public in modo che la policy del fornitore possa optare per la futura policy di sistema che utilizza questi attributi. Tuttavia, le estensioni degli attributi in system/sepolicy/public non sono supportate , quindi tutti i criteri che determinano come i componenti di sistema interagiscono con i nuovi componenti del fornitore (e che non sono gestiti da 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.