Combinaciones estables para Linux

Todos los días, se confirma una cantidad significativa de cambios en el kernel de Linux upstream. Por lo general, estos cambios no se evalúan en función del impacto en la seguridad, pero muchos de ellos pueden afectar la seguridad del kernel. Evaluar cada uno de estos cambios en cuanto al impacto en la seguridad es una operación costosa y, probablemente, inviable. En cambio, un enfoque más sostenible y mantenible es sincronizar los cambios con el kernel de Linux upstream de forma periódica.

Se recomienda actualizar los dispositivos periódicamente con kernels más recientes con compatibilidad a largo plazo (LTS). Las actualizaciones de LTS periódicas pueden ayudar a abordar posibles vulnerabilidades de seguridad no reconocidas, como este informe de Project Zero de principios de 2019, antes de la divulgación pública o el descubrimiento por parte de agentes maliciosos.

Requisitos previos

  • Rama de kernel común de Android (de AOSP)
  • Una rama de compilación de preparación de LTS para el kernel del dispositivo de destino
  • Rama de actualización del kernel del dispositivo
  • Repositorio de Git
  • Cadena de herramientas de compilación del kernel

Combinación con cambios de LTS

Cómo combinar cambios de LTS
Figura 1: Combinación de cambios de LTS

En los siguientes pasos, se describen los pasos típicos para una combinación de LTS.

  • Combina la rama de lanzamiento del kernel de destino en la rama de preparación de -LTS.
  • Combina localmente linux-stable o Android común en la rama -LTS staging.
  • Resuelve los conflictos de combinación (consulta a los propietarios del área o del código según sea necesario)
  • Compila de forma local y realiza pruebas de estado o de unidades (consulta la sección de pruebas a continuación)
  • Sube y combina los cambios comunes de Android en la rama de preparación de LTS
  • Realiza pruebas exhaustivas con la rama de preparación -LTS (consulta la sección de pruebas a continuación)
  • Revisa los resultados de la prueba
  • Soluciona las regresiones y realiza la combinación de biseccionamiento según sea necesario.
  • Combinación de la rama de etapa de pruebas de LTS con la rama de la versión del kernel del dispositivo principal
  • Crea una nueva compilación de Android para tus dispositivos que incluya el kernel LTS de etapa de pruebas
  • Compila la compilación de lanzamiento/ROM con el kernel nuevo

Ejemplo de combinación con LTS

Combina android-4.9 en la principal (a través de la etapa de pruebas de LTS) y en la rama de la etapa de pruebas de LTS, en la confirmación de la compra y la sincronización:

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

En este punto, es mejor enviar la combinación inversa a tu control remoto de origen antes de continuar. Después de eso, combina Android común en la etapa de pruebas de LTS.

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

Cómo resolver conflictos de combinación

En la mayoría de los casos, hay conflictos entre el kernel común de Android y la rama de preparación de -LTS. Resolver conflictos de combinación durante las combinaciones de LTS puede ser un desafío, por lo que a continuación se incluyen algunas sugerencias útiles para solucionarlos.

Combinación incremental

Si pasó un tiempo considerable desde que se actualizó el kernel de un dispositivo con LTS, es probable que haya habido muchas (más de 50) versiones estables desde que se lanzó la última actualización combinada en upstream. La mejor manera de abordar este problema es ponerte al día combinando una cantidad menor de versiones a la vez (menos de 5 versiones secundarias), mientras realizas pruebas en cada paso del proceso.

Por ejemplo, si el subnivel de la versión del kernel del dispositivo es 4.14.100 y el subnivel estable ascendente es 4.14.155, es mejor realizar la fusión en incrementos pequeños para garantizar que se pueda revisar y probar de manera adecuada un volumen razonable de cambios.

En general, descubrimos que trabajar de forma incremental en lotes de <=5 versiones secundarias por combinación garantiza un conjunto de parches más manejable.

Prueba

Prueba de inicio rápido

Para realizar una prueba de inicio rápido, primero debes combinar los cambios de LTS de forma local y compilar el kernel. En los siguientes pasos, se explica el proceso de prueba de inicio rápido.

Conecta el dispositivo de destino a la computadora con un cable USB y envía el archivo .ko al dispositivo con 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

Inicia dtbo y transfiere la imagen del kernel.

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

Revisa el registro /dev/kmsg en busca de errores.

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

Pruebas de Android

Primero, compila la imagen -userdebug de manera local con los módulos y el kernel de LTS nuevos.

Revisa /dev/kmsg para ver si hay errores y confirma que no haya ninguno antes de continuar. Prueba lo siguiente para asegurarte de que todo funciona según lo esperado.

  • Velocidad de Wi-Fi
  • Navegador Chrome
  • Captura de imagen y video con una app de cámara
  • Reproducción de videos de YouTube con bocinas integradas y auriculares Bluetooth
  • Llamadas a través de la red del operador
  • Videollamada por Wi-Fi

Paquetes de pruebas automatizadas

La verificación final para garantizar que la imagen del producto no tenga regresión se realiza con los paquetes de pruebas disponibles a través del conjunto de pruebas del proveedor (VTS) y las pruebas de esfuerzo de estabilidad automatizadas.