Creazione della politica di SELinux

Questo articolo spiega come viene costruita la politica di SELinux. La politica di SELinux è costruita dalla combinazione della politica AOSP di base (piattaforma) e della politica specifica del dispositivo (fornitore). Il flusso di compilazione dei criteri SELinux per Android 4.4 tramite Android 7.0 ha unito tutti i frammenti di sepolicy, quindi ha generato file monolitici nella directory principale. Ciò significava che i fornitori di SoC e i produttori di ODM modificavano boot.img (per dispositivi non A/B) o system.img (per dispositivi A/B) ogni volta che veniva modificata la policy.

In Android 8.0 e versioni successive, i criteri della piattaforma e del fornitore vengono creati separatamente. I SOC e gli OEM possono aggiornare le loro parti della policy, creare le loro immagini (come vendor.img e boot.img ), quindi aggiornare tali immagini indipendentemente dagli aggiornamenti della piattaforma.

Tuttavia, poiché i file delle politiche SELinux modularizzati sono archiviati su partizioni /vendor , il processo init deve montare prima il sistema e le partizioni del fornitore in modo che possa leggere i file SELinux da quelle partizioni e unirli con i file SELinux principali nella directory di sistema (prima di caricarli in il nocciolo).

File sorgenti

La logica per costruire SELinux è in questi file:

  • external/selinux : progetto SELinux esterno, utilizzato per creare utilità da riga di comando HOST per compilare criteri ed etichette SELinux.
    • external/selinux/libselinux : Android utilizza solo un sottoinsieme del progetto libselinux esterno insieme ad alcune personalizzazioni specifiche di Android. Per i dettagli, vedere external/selinux/README.android .
    • external/selinux/libsepol :
      • chkcon : determina se un contesto di sicurezza è valido per una determinata politica binaria (eseguibile host).
      • libsepol : libreria SELinux per la manipolazione delle politiche di sicurezza binarie (libreria host statica/condivisa, libreria statica di destinazione).
    • external/selinux/checkpolicy : compilatore di politiche SELinux (eseguibili host: checkpolicy , checkmodule e dispol ). Dipende da libsepol .
  • system/sepolicy : configurazioni di base delle politiche SELinux di Android, inclusi contesti e file delle politiche. Anche la logica di compilazione della sepolicy principale è qui ( system/sepolicy/Android.mk ).

Per maggiori dettagli sui file in system/sepolicy Implementazione di SELinux .

Android 7.0 e precedenti

Questa sezione illustra come la politica SELinux è costruita in Android 7.x e versioni precedenti.

Costruire la politica di SELinux

La politica SELinux viene creata combinando la politica AOSP di base con personalizzazioni specifiche del dispositivo. La politica combinata viene quindi passata al compilatore della politica e a vari correttori. La personalizzazione specifica del dispositivo viene eseguita tramite la variabile BOARD_SEPOLICY_DIRS definita nel file Boardconfig.mk specifico del dispositivo. Questa variabile di compilazione globale contiene un elenco di directory che specificano l'ordine in cui cercare file di criteri aggiuntivi.

Ad esempio, un fornitore di SoC e un ODM possono aggiungere ciascuno una directory, una per le impostazioni specifiche del SoC e un'altra per le impostazioni specifiche del dispositivo, per generare le configurazioni SELinux finali per un determinato dispositivo:

  • BOARD_SEPOLICY_DIRS += device/ SOC /common/sepolicy
  • BOARD_SEPOLICY_DIRS += device/ SoC / DEVICE /sepolicy

Il contenuto dei file file_contexts in system/sepolicy e BOARD_SEPOLICY_DIRS sono concatenati per generare il file_contexts.bin sul dispositivo:

Questa immagine mostra la logica di compilazione di SELinux per Android 7.x.
Figura 1 . Logica di compilazione di SELinux

Il file sepolicy è costituito da più file di origine:

  • Il testo normale policy.conf viene generato concatenando security_classes , initial_sids , file *.te , genfs_contexts e port_contexts in quest'ordine.
  • Per ogni file (come security_classes ), il suo contenuto è la concatenazione dei file con lo stesso nome sotto system/sepolicy/ e BOARDS_SEPOLICY_DIRS .
  • Il policy.conf viene inviato al compilatore SELinux per il controllo della sintassi e compilato in formato binario come sepolicy sul dispositivo.
    Questa immagine mostra i file che generano il file dei criteri SELinux per Android 7.x.
    Figura 2 . File delle politiche di SELinux

File SELinux

Dopo la compilazione, i dispositivi Android con 7.xe precedenti in genere contengono i seguenti file relativi a SELinux:

  • selinux_version
  • sepolicy: output binario dopo aver combinato i file delle politiche (come security_classes , initial_sids e *.te )
  • file_contexts
  • property_contexts
  • seapp_contexts
  • service_contexts
  • system/etc/mac_permissions.xml

Per maggiori dettagli, vedere Implementazione di SELinux .

Inizializzazione di SELinux

Quando il sistema si avvia, SELinux è in modalità permissiva (e non in modalità di applicazione). Il processo init esegue le seguenti attività:

  • Carica i file sepolicy da ramdisk nel kernel tramite /sys/fs/selinux/load .
  • Passa SELinux alla modalità di applicazione.
  • Esegue re-exec() per applicare la regola del dominio SELinux a se stessa.

Per ridurre il tempo di avvio, eseguire il re-exec() sul processo init il prima possibile.

Android 8.0 e versioni successive

In Android 8.0, la policy di SELinux è suddivisa in componenti di piattaforma e fornitore per consentire aggiornamenti indipendenti delle policy di piattaforma/fornitore pur mantenendo la compatibilità.

La sepolicy della piattaforma è ulteriormente suddivisa in parti private e platform public per esportare tipi e attributi specifici agli autori delle policy del fornitore. È garantito che i tipi/attributi pubblici della piattaforma vengano mantenuti come API stabili per una determinata versione della piattaforma. La compatibilità con i tipi/attributi pubblici della piattaforma precedente può essere garantita per diverse versioni utilizzando i file di mappatura della piattaforma.

Sicurezza pubblica della piattaforma

La piattaforma public sepolicy include tutto quanto definito in system/sepolicy/public . La piattaforma può presumere che i tipi e gli attributi definiti nella policy pubblica siano API stabili per una determinata versione della piattaforma. Ciò costituisce la parte della sepolicy che viene esportata dalla piattaforma su cui gli sviluppatori di policy del fornitore (ad es. dispositivo) possono scrivere una policy aggiuntiva specifica per il dispositivo.

I tipi hanno la versione in base alla versione della politica su cui vengono scritti i file del fornitore, definita dalla variabile di build PLATFORM_SEPOLICY_VERSION . La policy pubblica con versione viene quindi inclusa nella policy del fornitore e (nella sua forma originale) nella policy della piattaforma. Pertanto, la policy finale include la policy della piattaforma privata, la policy pubblica della piattaforma corrente, la policy specifica del dispositivo e la policy pubblica con versione corrispondente alla versione della piattaforma su cui è stata scritta la policy del dispositivo.

Privacy della piattaforma

La privacy sepolicy della piattaforma include tutto ciò che è definito in /system/sepolicy/private . Questa parte della policy forma tipi, autorizzazioni e attributi solo per la piattaforma necessari per la funzionalità della piattaforma. Questi non vengono esportati agli autori di criteri del vendor/device . Gli autori di criteri non di piattaforma non devono scrivere le proprie estensioni di criteri in base a tipi/attributi/regole definiti nella privacy sepolicy della piattaforma. Inoltre, queste regole possono essere modificate o potrebbero scomparire come parte di un aggiornamento del solo framework.

Mappatura privata della piattaforma

La mappatura privata della piattaforma include istruzioni di policy che mappano gli attributi esposti nella policy public della piattaforma delle versioni precedenti della piattaforma ai tipi concreti utilizzati nella policy public della piattaforma corrente. Ciò garantisce che la policy del fornitore scritta in base agli attributi public della piattaforma delle versioni precedenti della policy public della piattaforma continui a funzionare. Il controllo delle versioni si basa sulla variabile build PLATFORM_SEPOLICY_VERSION impostata in AOSP per una determinata versione della piattaforma. Esiste un file di mappatura separato per ogni versione precedente della piattaforma da cui questa piattaforma dovrebbe accettare la politica del fornitore. Per maggiori dettagli, vedere Compatibilità .

Android 11 e versioni successive

system_ext e product sepolicy

In Android 11 vengono aggiunti i criteri system_ext e i criteri del prodotto. Come la sepolicy della piattaforma, la policy system_ext e la policy del prodotto sono suddivise in policy pubbliche e private policy.

L'ordine pubblico viene esportato al fornitore. Tipi e attributi diventano API stabili e la policy del fornitore può fare riferimento a tipi e attributi nella policy pubblica. I tipi hanno la versione in base a PLATFORM_SEPOLICY_VERSION e la politica con versione è inclusa nella politica del fornitore. La policy originale è inclusa in ciascuna partizione system_ext e product.

La politica privata contiene i tipi, le autorizzazioni e gli attributi solo per system_ext e solo prodotto necessari per la funzionalità delle partizioni di prodotto e system_ext. La politica privata è invisibile al venditore, il che implica che queste regole sono interne e possono essere modificate.

system_ext e mappatura del prodotto

system_ext e product possono esportare i loro tipi pubblici designati al fornitore. Tuttavia, la responsabilità di mantenere la compatibilità spetta a ciascun partner. Per motivi di compatibilità, i partner possono fornire i propri file di mappatura che mappano gli attributi con versione delle versioni precedenti ai tipi concreti utilizzati nell'attuale politica di sicurezza pubblica.

  • Per installare un file di mappatura per system_ext, inserire un file cil contenente le informazioni di mappatura desiderate in {SYSTEM_EXT_PRIVATE_SEPOLICY_DIRS}/compat/{ver}/{ver}.cil , quindi aggiungere system_ext_{ver}.cil a PRODUCT_PACKAGES .
  • Per installare un file di mappatura per il prodotto, inserisci un file cil contenente le informazioni di mappatura desiderate in {PRODUCT_PRIVATE_SEPOLICY_DIRS}/compat/{ver}/{ver}.cil , quindi aggiungi product_{ver}.cil a PRODUCT_PACKAGES .
  • Fare riferimento a un esempio che aggiunge un file di mappatura della partizione del prodotto del dispositivo redbull.

    Costruire la politica di SELinux

    La politica di SELinux in Android 8.0 è realizzata combinando pezzi di /system e /vendor . La logica per configurarlo in modo appropriato è in /platform/system/sepolicy/Android.mk .

    La politica esiste nei seguenti luoghi:

    Posizione Contiene
    system/sepolicy/public L'API di sepolicy della piattaforma
    system/sepolicy/private Dettagli di implementazione della piattaforma (i fornitori possono ignorare)
    system/sepolicy/vendor File di policy e di contesto che i fornitori possono utilizzare (i fornitori possono ignorare se lo desiderano)
    BOARD_SEPOLICY_DIRS Segretezza del venditore
    BOARD_ODM_SEPOLICY_DIRS (Android 9 e versioni successive) Disciplina della privacy
    SYSTEM_EXT_PUBLIC_SEPOLICY_DIRS (Android 11 e versioni successive) API di sepolicy di System_ext
    SYSTEM_EXT_PRIVATE_SEPOLICY_DIRS (Android 11 e versioni successive) Dettagli di implementazione System_ext (i fornitori possono ignorare)
    PRODUCT_PUBLIC_SEPOLICY_DIRS (Android 11 e versioni successive) API di sicurezza del prodotto
    PRODUCT_PRIVATE_SEPOLICY_DIRS (Android 11 e versioni successive) Dettagli sull'implementazione del prodotto (i fornitori possono ignorare)

    Il sistema di compilazione prende questa politica e produce i componenti della politica di sistema, system_ext, prodotto, fornitore e odm sulla partizione corrispondente. I passaggi includono:

    1. Conversione delle politiche nel formato SELinux Common Intermediate Language (CIL), in particolare:
      1. politica della piattaforma pubblica (sistema + system_ext + prodotto)
      2. politica combinata privata + pubblica
      3. policy public + vendor e BOARD_SEPOLICY_DIRS
    2. Versione della politica fornita da public come parte della politica del fornitore. Fatto utilizzando la policy CIL pubblica prodotta per informare la policy combinata public + vendor + BOARD_SEPOLICY_DIRS su quali parti devono essere trasformate in attributi che saranno collegati alla policy della piattaforma.
    3. Creazione di un file di mappatura che collega la piattaforma e le parti del fornitore. Inizialmente, questo collega semplicemente i tipi della politica pubblica con gli attributi corrispondenti nella politica del fornitore; in seguito fornirà anche la base per il file mantenuto nelle versioni future della piattaforma, consentendo la compatibilità con i criteri del fornitore destinati a questa versione della piattaforma.
    4. Combinazione di file di criteri (descrivono soluzioni sia sul dispositivo che precompilate).
      1. Combina mappatura, piattaforma e policy del fornitore.
      2. Compila il file della politica binaria di output.

    Politica SELinux precompilata

    Prima che init attivi SELinux, init raccoglie tutti i file CIL dalle partizioni ( system , system_ext , product , vendor e odm ) e li compila in criteri binari, il formato che può essere caricato nel kernel. Poiché la compilazione richiede tempo (di solito 1-2 secondi), i file CIL vengono precompilati in fase di compilazione e posizionati in /vendor/etc/selinux/precompiled_sepolicy o /odm/etc/selinux/precompiled_sepolicy , insieme agli hash sha256 dei file CIL di input. In fase di esecuzione, init controlla se uno qualsiasi dei file delle politiche è stato aggiornato confrontando gli hash. Se non è cambiato nulla, init carica la politica precompilata. In caso contrario, init compila al volo e lo utilizza al posto di quello precompilato.

    Più specificamente, il criterio precompilato viene utilizzato se sono soddisfatte tutte le seguenti condizioni. Qui, {partition} rappresenta la partizione in cui esiste la policy precompilata: vendor o odm .

    • Sia /system/etc/selinux/plat_sepolicy_and_mapping.sha256 che /{partition}/etc/selinux/precompiled_sepolicy.plat_sepolicy_and_mapping.sha256 esistono e sono identici.
    • Sia /system_ext/etc/selinux/system_ext_sepolicy_and_mapping.sha256 che /{partition}/etc/selinux/precompiled_sepolicy.system_ext_sepolicy_and_mapping.sha256 non esistono. O entrambi esistono e sono identici.
    • Sia /product/etc/selinux/product_sepolicy_and_mapping.sha256 che /{partition}/etc/selinux/precompiled_sepolicy.product_sepolicy_and_mapping.sha256 non esistono. O entrambi esistono e sono identici.

    Se qualcuno di essi differisce, init torna al percorso di compilazione sul dispositivo. Vedere system/core/init/selinux.cpp per maggiori dettagli.