Implementare SELinux

SELinux è configurato per il rifiuto predefinito, il che significa che ogni singolo accesso per il quale ha un hook nel kernel deve essere consentito esplicitamente dal criterio. Ciò significa che un file di criteri è costituito da una grande quantità di informazioni su regole, tipi, classi, autorizzazioni e altro ancora. Una considerazione completa di SELinux non rientra nell'ambito di questo documento, ma una comprensione di come scrivere le regole dei criteri ora sono essenziali quando vengono introdotti nuovi dispositivi Android. C'è un sono già disponibili molte informazioni su SELinux. Vedi Supporto documentazione per le risorse suggerite.

File di chiavi

Per abilitare SELinux, integra più recenti kernel Android e quindi incorporare i file che si trovano nel sistema/politica di trasporto . Una volta compilati, questi file comprendono i criteri di sicurezza del kernel SELinux e coprono il sistema operativo Android upstream.

In generale, non devi modificare direttamente i file system/sepolicy. Aggiungi o modifica i tuoi file di criteri specifici per il dispositivo nella directory/device/manufacturer/device-name/sepolicy. In Android 8.0 e versioni successive, le modifiche apportate a questi file interessano solo i criteri nella directory dei fornitori. Per ulteriori dettagli sulla separazione di sepolicy pubblico in Android 8.0 e versioni successive, consulta Personalizzazione di SEPolicy in Android 8.0 e versioni successive. Indipendentemente dalla versione di Android, dovrai comunque modificare questi file:

File di criteri

I file che terminano con *.te sono file di origine dei criteri SELinux, che definiscono i domini e le relative etichette. Potresti dover creare nuovi file di norme in /device/manufacturer/device-name/sepolicy, ma, se possibile, dovresti provare ad aggiornare i file esistenti.

File di contesto

Nei file di contesto specifichi le etichette per gli oggetti.

  • file_contexts assegna etichette ai file e viene utilizzato da vari componenti dello spazio utente. Man mano che crei nuovi criteri, crea o aggiorna questo file per assegnare nuove etichette ai file. Per applicare la nuova file_contexts: ricreare l'immagine del file system o eseguire restorecon sul file rietichettare. Per gli upgrade, le modifiche a file_contexts vengono applicate automaticamente alle partizioni dei dati utente e di sistema nell'ambito upgrade. Le modifiche possono essere applicate automaticamente anche durante l'upgrade ad altre partizioni aggiungendo chiamate restorecon_recursive al file init.board.rc dopo il montaggio della partizione in modalità di lettura/scrittura.
  • genfs_contexts assegna etichette ai file system, ad esempio proc o vfat che non supportano le estensioni attributi. Questa configurazione viene caricata come parte del criterio del kernel, ma le modifiche potrebbero non essere applicate agli inode in-core, richiedendo un riavvio o smontaggio e rimontaggio del file system per applicare completamente la modifica. È possibile assegnare etichette specifiche anche a supporti specifici, ad esempio vfat utilizzando l'opzione context=mount.
  • property_contexts assegna etichette alle proprietà di sistema Android a e controllare quali processi possono impostarle. Questa configurazione viene letta Processo init durante l'avvio.
  • service_contexts assegna etichette ai servizi binder di Android per controllare quali processi possono aggiungere (registrare) e trovare (cercare) un riferimento binder per il servizio. Questa configurazione viene letta dal processo servicemanager durante l'avvio.
  • seapp_contexts assegna etichette ai processi dell'app e /data/data directory. Questa configurazione viene letta dal processo zygote a ogni avvio dell'app e da installd durante l'avvio.
  • mac_permissions.xml assegna un tag seinfo alle app in base alla firma e, facoltativamente, al nome del pacchetto. Il tag seinfo può essere utilizzato come chiave nel file seapp_contexts per assegnare un'etichetta specifica a tutte le app con questo tag seinfo. Questa configurazione viene letta da system_server durante l'avvio.
  • keystore2_key_contexts assegna le etichette agli spazi dei nomi Keystore 2.0. Questo spazio dei nomi viene applicato dal daemon keystore2. Il keystore ha sempre fornito spazi dei nomi basati su UID/AID. Keystore 2.0 applica inoltre gli spazi dei nomi definiti da sepolicy. Una descrizione dettagliata del formato e delle convenzioni di questo file è disponibile qui.

Makefile di BoardConfig.mk

Dopo aver modificato o aggiunto file di criteri e file di contesto, aggiorna /device/manufacturer/device-name/BoardConfig.mk makefile per fare riferimento alla sottodirectory sepolicy e a ogni nuovo file dei criteri. Per ulteriori informazioni sulle variabili BOARD_SEPOLICY, consulta system/sepolicy/README file.

BOARD_SEPOLICY_DIRS += \
        <root>/device/manufacturer/device-name/sepolicy

BOARD_SEPOLICY_UNION += \
        genfs_contexts \
        file_contexts \
        sepolicy.te

Dopo la ricostruzione, il dispositivo è abilitato con SELinux. Ora puoi personalizzare i criteri SELinux per includere le proprie aggiunte al Sistema operativo Android come descritto in Personalizzazione o verifica configurazione esistente, come descritto in Convalida.

Quando i nuovi file di criteri e gli aggiornamenti di BoardConfig.mk sono in atto, le nuove impostazioni dei criteri vengono integrate automaticamente nel file di criteri del kernel finale. Per ulteriori informazioni su come sepolicy è realizzato sul dispositivo, vedi Creazione di sepolicy.

Implementazione

Per iniziare a utilizzare SELinux:

  1. Attiva SELinux nel kernel: CONFIG_SECURITY_SELINUX=y
  2. Modifica il parametro kernel_cmdline o bootconfig in modo che:
    BOARD_KERNEL_CMDLINE := androidboot.selinux=permissive
    o
    BOARD_BOOTCONFIG := androidboot.selinux=permissive
    Serve solo per lo sviluppo iniziale dei criteri per il dispositivo. Dopo un criterio di bootstrap iniziale, rimuovi questo parametro in modo che dispositivo in fase di applicazione o non riesce a CTS.
  3. Avvia il sistema in modalità permissiva e controlla quali negazioni vengono rilevate all'avvio:
    Su Ubuntu 14.04 o versioni successive:
    adb shell su -c dmesg | grep denied | audit2allow -p out/target/product/BOARD/root/sepolicy
    
    Su Ubuntu 12.04:
    adb pull /sys/fs/selinux/policy
    adb logcat -b all | audit2allow -p policy
    
  4. Valuta l'output per avvisi simili a init: Warning! Service name needs a SELinux domain defined; please fix! Vedi Convalida per le istruzioni e strumenti.
  5. Identifica i dispositivi e gli altri nuovi file che devono essere etichettati.
  6. Utilizza etichette esistenti o nuove per gli oggetti. Esamina i file *_contexts per vedere come erano etichettate le risorse in precedenza e utilizza la conoscenza dei significati delle etichette per assegnarne una nuova. L'ideale è si tratta di un'etichetta esistente che rientra nelle norme, ma a volte è necessaria una nuova etichetta e le regole per accedervi sono necessaria. Aggiungi le etichette ai file di contesto appropriati.
  7. Identifica i domini/processi che devono avere i propri domini di sicurezza. Probabilmente dovrai scrivere norme completamente nuove per ognuna. Ad esempio, tutti i servizi generati da init devono avere il proprio. I seguenti comandi consentono di rilevare quelli che rimangono in esecuzione (ma TUTTI i servizi richiedono questo trattamento):
    adb shell su -c ps -Z | grep init
    
    adb shell su -c dmesg | grep 'avc: '
    
  8. Esamina init.device.rc per identificare i domini che non hanno un tipo di dominio. Assegnagli un dominio all'inizio del processo di sviluppo per evitare di aggiungere regole a init o di confondere gli accessi a init con quelli previsti dalle sue norme.
  9. Configura BOARD_CONFIG.mk in modo da utilizzare le variabili BOARD_SEPOLICY_*. Consulta le README in system/sepolicy per i dettagli sulla configurazione.
  10. Esamina i file init.device.rc e fstab.device e assicurati che ogni utilizzo di mount corrisponda a un filesystem correttamente etichettato o che sia specificata un'opzione context= mount.
  11. Esamina ogni rifiuto e crea un criterio SELinux per gestirlo correttamente. Consulta: gli esempi in Personalizzazione.

Dovresti iniziare con i criteri nell'AOSP e poi svilupparli per le tue personalizzazioni. Per ulteriori informazioni sulla strategia per le norme e su un da un'occhiata più da vicino ad alcuni di questi passaggi, Scrittura di un criterio SELinux.

Casi d'uso

Ecco alcuni esempi specifici di exploit da considerare quando crei i tuoi software e criteri SELinux associati:

Link simbolici: poiché vengono visualizzati come file, spesso sono leggi come file, il che può portare a exploit. Ad esempio, alcuni componenti privilegiati, come init, modificano le autorizzazioni di determinati file, a volte in modo eccessivamente aperto.

Gli utenti malintenzionati potrebbero quindi sostituire questi file con link simbolici al codice che controllano, consentendo loro di sovrascrivere file arbitrari. Tuttavia, se sai che la tua app non attraversa mai un link simbolico, puoi vietarlo con SELinux.

File di sistema: prendi in considerazione la classe di file di sistema che deve essere modificata solo dal server di sistema. Sempre da netd, init e vold vengono eseguiti come root; possono accedere file di sistema. Quindi, se netd fosse compromesso, potrebbe compromettere i file e potenzialmente lo stesso server di sistema.

Con SELinux, puoi identificare questi file come file di dati del server di sistema. Pertanto, l'unico dominio che ha accesso in lettura/scrittura è il server di sistema. Anche se netd fosse compromesso, non ha potuto trasferire i domini alla dominio del server di sistema e accedere a questi file di sistema anche se viene eseguito come root.

Dati dell'app: un altro esempio è la classe di funzioni che deve essere eseguito come root ma non deve avere accesso ai dati dell'app. È un aspetto incredibile utile perché è possibile fare asserzioni di ampio respiro, come alcuni domini non correlati all'accesso a internet ai dati delle app.

setattr: per comandi come chmod e chown, potresti identificare l'insieme di file in cui sono associati il dominio può condurre setattr. Al di fuori di questo ambito, proibiti da queste modifiche, anche dalla directory radice. Quindi un'app può eseguire chmod e chown rispetto a quelli etichettati app_data_files ma non shell_data_files o system_data_files.