Unioni stabili per Linux

Ogni giorno un numero significativo di modifiche viene apportato al kernel Linux upstream. In genere non viene valutato l'impatto sulla sicurezza di queste modifiche, ma molte di esse hanno il potenziale per incidere sulla sicurezza del kernel. Valutare l’impatto sulla sicurezza di ciascuna di queste modifiche è un’operazione costosa e probabilmente irrealizzabile. Invece un approccio più sostenibile e manutenibile consiste nel sincronizzare regolarmente le modifiche con il kernel Linux upstream.

Si consiglia di aggiornare regolarmente i dispositivi con i kernel più recenti supportati a lungo termine (LTS). Gli aggiornamenti regolari di LTS possono aiutare a risolvere potenziali vulnerabilità della sicurezza non riconosciute, come questo rapporto Project Zero di inizio 2019, prima che vengano divulgate o scoperte al pubblico da parte di soggetti malintenzionati.

Prerequisiti

  • Ramo comune del kernel Android (da AOSP)
  • Un ramo di gestione temporanea dell'unione LTS per il kernel del dispositivo di destinazione
  • Ramo di rilascio del kernel del dispositivo
  • Deposito Git
  • Toolchain di creazione del kernel

Unione con modifiche LTS

Unione delle modifiche LTS
Figura 1 : Unione delle modifiche LTS

I passaggi seguenti descrivono i passaggi tipici per un'unione LTS.

  • Unisci il ramo di rilascio del kernel di destinazione nel ramo di staging -LTS
  • Unisci localmente linux-stable o Android common nel ramo di staging -LTS
  • Risolvere i conflitti di unione (consultare i proprietari dell'area/codice secondo necessità)
  • Costruisci localmente ed esegui test di integrità/unità (vedi la sezione test di seguito)
  • Carica e unisci le modifiche comuni di Android al ramo di staging LTS
  • Testare accuratamente utilizzando il ramo di staging -LTS (vedere la sezione test di seguito)
  • Esaminare i risultati dei test
  • Affronta eventuali regressioni, dividi in due l'unione secondo necessità
  • Unisci il ramo di staging -LTS nel ramo di rilascio del kernel del dispositivo principale
  • Crea una nuova build Android per i tuoi dispositivi che includa il kernel LTS di staging
  • Compila build/ROM di rilascio con il nuovo kernel

Esempio di fusione con LTS.

Unisci Android-4.9 nel main (tramite lo staging LTS) ed effettua il checkout e sincronizza il ramo di staging 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 back-merge sul telecomando di origine prima di continuare. Successivamente, unisci Android Common nello staging LTS.

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

Risoluzione dei conflitti di unione

Nella maggior parte dei casi, si verificheranno conflitti tra il kernel comune di Android e il ramo di staging -LTS. Risolvere i conflitti di unione durante le unioni LTS può essere difficile, quindi di seguito sono riportati alcuni suggerimenti utili su come risolverli.

Unione incrementale

Se è trascorso un periodo di tempo significativo da quando il kernel di un dispositivo è stato aggiornato con LTS, c'è una buona probabilità che ci siano stati molti (>50) rilasci stabili da quando l'ultimo aggiornamento unito è stato rilasciato a monte. Il modo migliore per risolvere questo problema è recuperare lentamente il ritardo unendo un numero minore di versioni alla volta (<= 5 versioni minori), testando durante ogni fase del percorso.

Ad esempio, se il sottolivello della versione del kernel del dispositivo è 4.14.100 e il sottolivello stabile upstream è 4.14.155, è meglio unire in piccoli incrementi per garantire che un volume ragionevole di modifiche possa essere adeguatamente rivisto e testato.

In generale, abbiamo riscontrato che lavorare in modo incrementale in batch di <=5 versioni minori per unione garantisce un insieme di patch più gestibile.

Test

Test di avvio rapido

Per eseguire un test di avvio rapido è necessario prima unire le modifiche LTS localmente e compilare il kernel.
I passaggi seguenti spiegano il processo di test di avvio rapido.

Collega il dispositivo di destinazione al computer utilizzando un cavo USB e invia .ko al 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 carica lateralmente l'immagine del kernel.

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

Controlla il registro /dev/kmsg per eventuali errori.

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 il file /dev/kmsg per eventuali errori e conferma che non ce ne siano prima di continuare. Testare le seguenti cose per assicurarsi che tutto funzioni come previsto.

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

Suite di test automatizzati

La verifica finale per garantire che l'immagine del prodotto non regredisca viene eseguita utilizzando le suite di test disponibili tramite la suite di test del fornitore (VTS) e gli stress test di stabilità automatizzati.