Crea il criterio SELinux

Questa pagina spiega come viene creato il criterio SELinux. Il criterio SELinux viene creato dalla combinazione del criterio AOSP di base (piattaforma) e del criterio specifico del dispositivo (fornitore). Il flusso di compilazione dei criteri SELinux per Android 4.4 fino ad Android 7.0 univa tutti i frammenti di sepolicy e poi generava file monolitici nella directory principale. Ciò significava che i fornitori di SoC e i produttori ODM modificavano boot.img (per i dispositivi non A/B) o system.img (per i dispositivi A/B) ogni volta che i criteri venivano modificati.

In Android 8.0 e versioni successive, le norme della piattaforma e del fornitore vengono create separatamente. I SOC e gli OEM possono aggiornare le proprie parti del criterio, creare le proprie immagini (ad esempio vendor.img e boot.img) e poi aggiornarle indipendentemente dagli aggiornamenti della piattaforma.

Tuttavia, poiché i file delle norme SELinux modularizzate sono archiviati nelle partizioni /vendor, il processo init deve montare prima le partizioni di sistema e del fornitore per poter leggere i file SELinux da queste partizioni e unirli ai file SELinux di base nella directory di sistema (prima di caricarli nel kernel).

File di origine

La logica per la compilazione di SELinux è in questi file:

  • external/selinux: progetto SELinux esterno, utilizzato per compilare le utilità a riga di comando HOST per compilare i criteri e le etichette SELinux.
    • external/selinux/libselinux: Android utilizza solo un sottoinsieme del progetto libselinux esterno, oltre ad alcune personalizzazioni specifiche per Android. Per maggiori dettagli, vedi external/selinux/README.android.
    • external/selinux/libsepol:
      • chkcon: determina se un contesto di sicurezza è valido per un determinato criterio binario (eseguibile host).
      • libsepol: libreria SELinux per la manipolazione dei criteri di sicurezza di file binari (libreria statica/condivisa dell'host, libreria statica di destinazione).
    • external/selinux/checkpolicy: compilatore delle norme SELinux (eseguibili host: checkpolicy, checkmodule e dispol). Dipende da libsepol.
  • system/sepolicy: configurazioni di criteri SELinux di Android di base, inclusi contesti e file di criteri. Anche la logica di compilazione della maggior parte delle sepolicy è qui (system/sepolicy/Android.mk).

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

Android 7.x e versioni precedenti

Questa sezione spiega come viene creato il criterio SELinux in Android 7.x e versioni precedenti.

Processo di compilazione per Android 7.x e versioni precedenti

Il criterio SELinux viene creato combinando il criterio AOSP di base con personalizzazioni specifiche del dispositivo. Il criterio combinato viene poi passato al compilatore delle norme e a vari controlli. La personalizzazione specifica del dispositivo viene eseguita tramite la variabile BOARD_SEPOLICY_DIRS definita nel file BOARD_SEPOLICY_DIRS specifico del dispositivo.Boardconfig.mk 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 potrebbero 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

I contenuti dei file file_contexts in system/sepolicy e BOARD_SEPOLICY_DIRS vengono concatenati per generare il file_contexts.bin sul dispositivo:

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

Figura 1. Logica di compilazione SELinux.

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

  • Il testo normale policy.conf viene generato concatenando i file security_classes, initial_sids, *.te, genfs_contexts e port_contexts in quest'ordine.
  • Per ogni file (ad esempio security_classes), i contenuti sono la concatenazione dei file con lo stesso nome in system/sepolicy/ e BOARDS_SEPOLICY_DIRS.
  • Il file 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 delle norme SELinux
                per Android 7.x.

    Figura 2. File di criteri SELinux.

File SELinux

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

  • selinux_version
  • sepolicy: output binario dopo la combinazione dei file di criteri (ad esempio security_classes, initial_sids e *.te)
  • file_contexts
  • property_contexts
  • seapp_contexts
  • service_contexts
  • system/etc/mac_permissions.xml

Per maggiori dettagli, consulta Implementazione di SELinux.

Inizializzazione di SELinux

All'avvio del sistema, SELinux è in modalità permissiva (e non in modalità di applicazione). Il processo init esegue le seguenti attività:

  • Carica i file sepolicy dal 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, esegui il processo re-exec() su init il prima possibile.

Android 8.0 e versioni successive

In Android 8.0, i criteri SELinux sono suddivisi in componenti della piattaforma e del fornitore per consentire aggiornamenti indipendenti dei criteri della piattaforma/del fornitore mantenendo la compatibilità.

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

Processo di compilazione per Android 8.0

Il criterio SELinux in Android 8.0 è costituito dalla combinazione di elementi di/system e /vendor. La logica per configurare questa opzione in modo appropriato è disponibile in /platform/system/sepolicy/Android.mk.

Le norme si trovano nelle seguenti posizioni:

Posizione Contiene
system/sepolicy/public L'API sepolicy della piattaforma
system/sepolicy/private Dettagli sull'implementazione della piattaforma (i fornitori possono ignorarli)
system/sepolicy/vendor File di criteri e contesto che i fornitori possono utilizzare (se lo desiderano possono ignorarli)
BOARD_SEPOLICY_DIRS Sepolicy del fornitore
BOARD_ODM_SEPOLICY_DIRS (Android 9 e versioni successive) Sepolicy ODM
SYSTEM_EXT_PUBLIC_SEPOLICY_DIRS (Android 11 e versioni successive) API sepolicy di System_ext
SYSTEM_EXT_PRIVATE_SEPOLICY_DIRS (Android 11 e versioni successive) Dettagli di implementazione di System_ext (i fornitori possono ignorarli)
PRODUCT_PUBLIC_SEPOLICY_DIRS (Android 11 e versioni successive) API sepolicy del prodotto
PRODUCT_PRIVATE_SEPOLICY_DIRS (Android 11 e versioni successive) Dettagli sull'implementazione del prodotto (i fornitori possono ignorarli)

Il sistema di compilazione prende questo criterio e produce componenti di criteri system, system_ext, product, vendor e odm nella partizione corrispondente. I passaggi includono:

  1. Conversione dei criteri nel formato CIL (Common Intermediate Language) di SELinux, nello specifico:
    1. norme della piattaforma pubblica (system + system_ext + product)
    2. Norme pubbliche e private combinate
    3. Norme relative a public, vendor e BOARD_SEPOLICY_DIRS
  2. Versionamento delle norme fornite dal pubblico nell'ambito delle norme del fornitore. Viene eseguita utilizzando le norme CIL pubbliche prodotte per indicare le norme pubbliche + fornitore + BOARD_SEPOLICY_DIRS combinate relative alle parti che devono essere trasformate in attributi che verranno collegati alle norme della piattaforma.
  3. Creazione di un file di mappatura che colleghi le parti della piattaforma e del fornitore. Inizialmente, questo collega solo i tipi delle norme pubbliche agli attributi corrispondenti nelle norme del fornitore. In seguito, fornirà anche la base per il file gestito nelle versioni future della piattaforma, consentendo la compatibilità con le norme del fornitore che hanno come target questa versione della piattaforma.
  4. Combinazione di file di criteri (descrivi sia le soluzioni on-device che quelle precompilate).
    1. Combina i criteri di mappatura, della piattaforma e del fornitore.
    2. Compila il file di criteri binari di output.

Sepolicy pubblico della piattaforma

Il file sepolicy pubblico della piattaforma include tutto ciò che è definito in system/sepolicy/public. La piattaforma può presumere che i tipi e gli attributi definiti ai sensi delle norme pubbliche siano API stabili per una determinata versione della piattaforma. Questa costituisce la parte di sepolicy esportata dalla piattaforma su cui gli sviluppatori di norme del fornitore (ovvero del dispositivo) possono scrivere norme aggiuntive specifiche per il dispositivo.

I tipi sono versionati in base alla versione del criterio in base alla quale vengono scritti i file del fornitore, definita dalla variabile di compilazione PLATFORM_SEPOLICY_VERSION. Le norme pubbliche con versione vengono poi incluse nelle norme del fornitore e (nella loro forma originale) nelle norme della piattaforma. Pertanto, le norme finali includono le norme della piattaforma privata, le norme sepolicy pubbliche della piattaforma corrente, le norme specifiche del dispositivo e le norme pubbliche con versione corrispondente alla versione della piattaforma in base alla quale sono state scritte le norme del dispositivo.

Sepolicy privato della piattaforma

Il file sepolicy privato della piattaforma include tutto ciò che è definito in /system/sepolicy/private. Questa parte del criterio definisce i tipi, le autorizzazioni e gli attributi solo per la piattaforma necessari per la funzionalità della piattaforma. Questi elementi non vengono esportati nei generatori di vendor/device norme. Gli autori di norme non della piattaforma non devono scrivere le proprie estensioni di norme in base a tipi/attributi/regole definiti in sepolicy privato della piattaforma. Inoltre, queste regole possono essere modificate o potrebbero scomparire nell'ambito di un aggiornamento solo framework.

Mappatura privata della piattaforma

La mappatura privata della piattaforma include istruzioni di criteri che mappano gli attributi esposti nelle norme pubbliche della piattaforma delle versioni precedenti della piattaforma ai tipi concreti utilizzati nelle norme sepolicy pubbliche della piattaforma corrente. In questo modo, le norme del fornitore scritte in base agli attributi pubblici della piattaforma delle versioni precedenti di sepolicy pubblico della piattaforma continueranno a funzionare. Il controllo delle versioni si basa sulla variabile di compilazione 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 le norme del fornitore. Per maggiori dettagli, consulta Compatibilità.

Android 11 e versioni successive

system_ext e sepolicy del prodotto

In Android 11 vengono aggiunti i criteri system_ext e del prodotto. Come le norme sepolicy della piattaforma, le norme system_ext e le norme dei prodotti sono suddivise in norme pubbliche e norme private.

Le norme pubbliche vengono esportate al fornitore. I tipi e gli attributi diventano API stabili e le norme del fornitore possono fare riferimento a tipi e attributi nelle norme pubbliche. I tipi sono sottoposti a versionamento in base a PLATFORM_SEPOLICY_VERSION e il criterio sottoposto a versionamento è incluso nelle norme del fornitore. Il criterio originale è incluso in ogni partizione system_ext e product.

Le norme private contengono tipi, autorizzazioni e attributi solo per system_ext e solo per il prodotto necessari per la funzionalità delle partizioni system_ext e del prodotto. Le norme private sono invisibili al fornitore, il che implica che queste regole sono interne e possono essere modificate.

system_ext e mappatura dei prodotti

system_ext e product possono esportare i tipi pubblici designati in vendor. Tuttavia, la responsabilità di mantenere la compatibilità è di ciascun partner. Per la compatibilità, i partner possono fornire i propri file di mappatura che mappano gli attributi con versione delle versioni precedenti a tipi concreti utilizzati nell'attuale sepolicy pubblico.

  • Per installare un file di mappatura per system_ext, inserisci un file cil contenente le informazioni di mappatura desiderate in {SYSTEM_EXT_PRIVATE_SEPOLICY_DIRS}/compat/{ver}/{ver}.cil, quindi aggiungi 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.

Consulta un esempio che aggiunge un file di mappatura della partizione del prodotto del dispositivo Redbull.

Norme SELinux precompilate

Prima che init attivi SELinux, 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.init 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 dei file delle norme è stato aggiornato confrontando gli hash. Se non è cambiato nulla, init carica il criterio precompilato. In caso contrario,init lo compila dinamicamente e lo utilizza al posto di quello precompilato.

Nello specifico, i criteri precompilati vengono utilizzati se sono soddisfatte tutte le seguenti condizioni. Qui, {partition} rappresenta la partizione in cui esiste il criterio precompilato: 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.
  • /system_ext/etc/selinux/system_ext_sepolicy_and_mapping.sha256 e /{partition}/etc/selinux/precompiled_sepolicy.system_ext_sepolicy_and_mapping.sha256 non esistono. In alternativa, entrambi esistono e sono identici.
  • /product/etc/selinux/product_sepolicy_and_mapping.sha256 e /{partition}/etc/selinux/precompiled_sepolicy.product_sepolicy_and_mapping.sha256 non esistono. In alternativa, entrambi esistono e sono identici.

Se uno di questi valori è diverso, init torna al percorso di compilazione sul dispositivo. Per ulteriori dettagli, consulta system/core/init/selinux.cpp.