Unione stabili di Linux

Ogni giorno viene eseguito il commit di un numero significativo di modifiche al kernel Linux upstream. Queste modifiche in genere non vengono valutate per la sicurezza, ma molte possono influire sulla sicurezza del kernel. Valutare l'impatto di ciascuna di queste modifiche sulla sicurezza è un'operazione costosa e probabilmente non fattibile. Un approccio più sostenibile e manutenibile è invece quello di sincronizzare regolarmente le modifiche con il kernel Linux upstream.

È consigliabile aggiornare regolarmente i dispositivi con kernel LTS (assistenza a lungo termine) più recenti. Aggiornamenti regolari LTS possono contribuire a risolvere potenziali vulnerabilità di sicurezza non riconosciute, come questo report di Project Zero all'inizio del 2019, prima della divulgazione pubblica o del rilevamento da parte di malintenzionati.

Prerequisiti

  • Ramo del kernel comune di Android (da AOSP)
  • Un ramo di staging di unione LTS per il kernel del dispositivo di destinazione
  • Ramo di rilascio del kernel del dispositivo
  • Repository Git
  • Toolchain di creazione del kernel

Unisci con le modifiche LTS

Unisci le modifiche LTS
Figura 1: unione delle modifiche LTS

I passaggi riportati di seguito descrivono la procedura tipica per l'unione di LTS.

  • Esegui il merge inverso del ramo di rilascio del kernel di destinazione nel ramo di staging -LTS
  • Unisci localmente la piattaforma Linux stabile o Android nel ramo di gestione temporanea -LTS
  • Risolvi i conflitti di unione (consulta i proprietari di aree/codici, se necessario)
  • Esegui la compilazione in locale ed esegui test di convalida/unità (vedi la sezione sui test di seguito)
  • Carica e unisci le modifiche comuni di Android al ramo temporaneo LTS
  • Esegui test approfonditi utilizzando il ramo temporaneo LTS (vedi la sezione sui test di seguito)
  • Esamina i risultati del test
  • Risolvi le regressioni e l'unione in due parti in base alle esigenze
  • Unisci il ramo temporaneo LTS nel ramo di rilascio del kernel del dispositivo principale
  • Creare una nuova build Android per i dispositivi che include il kernel LTS di staging
  • Compila la build di release/ROM con il nuovo kernel

Esempio di unione con LTS.

Unisci android-4.9 al ramo principale (tramite il layout LTS) e esegui il checkout e la sincronizzazione del ramo LTS:

repo init -b <Device kernel LTS staging branch>  # init
repo sync
git checkout -b lts <Device kernel LTS staging branch>
git merge <Device kernel release branch>         # back-merge
git commit

A questo punto, è meglio eseguire il push della unione inversa sul tuo computer remoto di origine prima di continuare. Dopodiché, unisci Android Common alla gestione temporanea LTS.

git merge -X patience android-4.9-q            # LTS merge

Risolvere i conflitti di unione

Nella maggior parte dei casi, si verificano conflitti tra il kernel comune di Android e il ramo temporaneo -LTS. La risoluzione dei conflitti di unione durante le unioni LTS può essere difficile, quindi di seguito sono riportati alcuni suggerimenti utili per risolverli.

Unità incrementali

Se è trascorso molto tempo dall'aggiornamento del kernel di un dispositivo con LTS, è probabile che siano state rilasciate molte (più di 50) release stabili dall'ultimo aggiornamento unito rilasciato in upstream. Il modo migliore per risolvere il problema è recuperare lentamente il ritardo unendo un numero inferiore di release alla volta (<=5 versioni minori), testando a ogni passaggio.

Ad esempio, se il sottolivello della versione del kernel del dispositivo è 4.14.100 e il sottolivello stabile upstream è 4.14.155, è meglio eseguire l'unione a piccoli incrementi per garantire che un volume ragionevole di modifiche possa essere esaminato e testato adeguatamente.

In generale, abbiamo riscontrato che lavorare in modo incrementale in batch con meno di 5 release secondarie per unione assicura un set di patch più gestibile.

Test

Test di avvio rapido

Per eseguire un rapido test di avvio, devi prima unire le modifiche LTS localmente e creare il kernel. I passaggi riportati di seguito spiegano la procedura del test di avvio rapido.

Collega il dispositivo di destinazione al computer con un cavo USB e carica il file .ko sul dispositivo utilizzando Android Debug Bridge (adb).

adb root
adb disable-verity
adb reboot
(wait for device boot-to-home)
adb root
adb remount
adb push *.ko vendor/lib/modules/
adb reboot bootloader

Avvia dtbo e installa l'immagine del kernel tramite sideload.

fastboot boot --header-version=2 Image.lz4 (redo again if device rebooted)

Verifica la presenza di errori nel log /dev/kmsg.

adb shell
su
cat /dev/kmsg (inspect kernel log for obvious new errors)

Test Android

Per prima cosa, crea l'immagine -userdebug localmente con il nuovo kernel e i nuovi moduli LTS.

Controlla se sono presenti errori in /dev/kmsg e verifica che non ce ne siano prima di continuare. Verifica quanto segue per assicurarti che tutto funzioni come previsto.

  • velocità Wi-Fi
  • Browser Chrome
  • Acquisizione di immagini e video con l'app Fotocamera
  • Riproduzione di video di YouTube con altoparlanti integrati e cuffie Bluetooth
  • Chiamate sulla rete dell'operatore
  • Videochiamata tramite Wi-Fi

Suite di test automatici

La verifica finale per garantire che l'immagine del prodotto non abbia subito un regresso viene eseguita utilizzando le suite di test disponibili tramite la suite di test del fornitore (VTS) e i test di stress di stabilità automatici.