Release-keys/AVB, CVE clean+hi batches, Yama/slabrand, Pro branding, bundled apps, and AXP-class product surface docs/scripts.
230 lines
13 KiB
Markdown
230 lines
13 KiB
Markdown
# Auditoría de los fallos de arranque del kernel — 2026-09-26
|
|
|
|
Revisión de documentación local, scripts, fuentes y artefactos de `rom-dev01`.
|
|
No se ha compilado, flasheado, reiniciado ni modificado el servidor o los teléfonos.
|
|
Este documento registra evidencias y un punto de reanudación; no cambia requisitos.
|
|
|
|
## Conclusión
|
|
|
|
**Hallazgo prioritario posterior: los bisect cambian TARGET_RELEASE de bp4a
|
|
a bp2a.** La comparación binaria y el log demuestran que no se está aislando
|
|
el hardening. Ver la sección siguiente antes de construir o probar más boots.
|
|
|
|
Hay errores verificables en la preparación de los experimentos y en su trazabilidad.
|
|
Todavía no hay una traza que identifique la causa exacta del fallo de arranque.
|
|
El siguiente paso debe recuperar un experimento controlado, no volver a aplicar
|
|
todo el hardening/CVE/deblob desde cero.
|
|
|
|
## Hallazgo principal: cambio accidental de release Android en los bisect
|
|
|
|
Tras confirmar el dueño que GOODMAKE también arranca, se han desempaquetado
|
|
GOODMAKE y el boot mild y extraído sus configuraciones IKCONFIG y ramdisks.
|
|
[Evidencia y diff de configuración](009-kernel-boot-image-comparison-20260926.txt).
|
|
|
|
- GOODMAKE: cabecera con parche `2026-09`; ramdisk declara
|
|
`ro.build.version.security_patch=2026-09-01`, SDK completo `36.1`.
|
|
- MILD: cabecera con parche `2025-08`; ramdisk declara
|
|
`ro.build.version.security_patch=2025-08-05`, SDK completo `36.0`.
|
|
- DTB idéntico. Ramdisk diferente, incluyendo bibliotecas y propiedades.
|
|
- Configuración del kernel: además de DMESG/SLAB cambian VT/fbcon, watchdog
|
|
y PANIC_TIMEOUT (de 0 a 5), entre otros cambios derivados. La base buena
|
|
conservaba configuración de depuración y el bloque Kconfig de KernelSU,
|
|
aunque CONFIG_KSU estaba desactivado.
|
|
|
|
Origen confirmado en el servidor:
|
|
|
|
- `scripts/009-bacon-axp.sh:87` usa `breakfast sunfish userdebug`.
|
|
- `vendor/lineage/build/envsetup.sh` hace que breakfast lea
|
|
`vendor/lineage/vars/aosp_target_release`, cuyo valor actual es `bp4a`.
|
|
- Los bisect fuerzan `lunch lineage_sunfish-bp2a-userdebug`.
|
|
- El log `detach-009-bisect-dc-20260921T180802Z.log:53` registra literalmente
|
|
`TARGET_RELEASE ("bp4a" -> "bp2a")`.
|
|
- `build/release/flag_values/bp2a/RELEASE_PLATFORM_SECURITY_PATCH.textproto`
|
|
contiene `2025-08-05`.
|
|
- Los dos scripts nuevos del 26 de septiembre, `009-bisect-dmesg-only.sh`
|
|
y `009-bisect-slab-only.sh`, también fuerzan **bp2a en la línea 32**.
|
|
No se han detenido ni modificado sus procesos desde esta auditoría.
|
|
|
|
**Defecto demostrado:** los experimentos denominados «solo una/dos opciones»
|
|
cambian también la release Android y metadatos de seguridad del boot.
|
|
Que GOODMAKE arranque no valida la equivalencia del entorno que los recompila.
|
|
|
|
**Hipótesis causal prioritaria, aún no confirmada en LAB:** el retroceso del
|
|
nivel de parche o su inconsistencia con el sistema instalado puede interferir
|
|
con Keymaster y las claves necesarias para montar datos. AOSP documenta
|
|
[version binding](https://source.android.com/docs/security/features/keystore/version-binding):
|
|
las claves están vinculadas a versiones/niveles de parche y no se pueden
|
|
degradar libremente. Los flags AVB que desactivan verificación no constituyen
|
|
una prueba de compatibilidad de esas claves. Falta traza o prueba controlada;
|
|
no afirmar que esto explique también todos los OTA Stage1 anteriores.
|
|
|
|
**Corrección del experimento:** recuperar la release y metadatos efectivos
|
|
del build bueno; verificar cabecera, propiedades y AVB del resultado antes de
|
|
flashear. Cambiar simplemente a bp4a no basta como verificación: el archivo
|
|
bp4a actual declara `2025-12-05`, mientras GOODMAKE declara `2026-09-01`, por
|
|
lo que hay que localizar/reproducir sus overrides y no inventar una fecha.
|
|
Usar salida aislada y empezar con un control recompilado sin hardening nuevo.
|
|
No hacer factory reset como método de validación. Después aislar kernel y
|
|
módulos sin variar simultáneamente ramdisk, release o metadatos.
|
|
|
|
## Historial aportado por el dueño después de la revisión
|
|
|
|
El 26 de septiembre el dueño aporta una conversación previa:
|
|
|
|
- «Tanto con uno como el otro» el teléfono reinicia en recovery y muestra
|
|
«Try again / Factory data reset». El fragmento no identifica inequívocamente
|
|
los dos archivos por nombre/hash; no asignar este resultado a mild.
|
|
- Tras restaurar el boot GOOD de `20260918T143547Z`, confirma «estoy en el
|
|
sistema». No se relata un borrado de datos. Es evidencia de recuperación
|
|
con el boot conocido, no una prueba de corrupción permanente de `/data`.
|
|
- El agente anterior informa ADB `unauthorized` en recovery; después, ya en
|
|
sistema, informa ausencia de `su`, depuración root desactivada y ningún log
|
|
útil obtenido. No hay salidas originales que permitan verificar qué rutas
|
|
pudo leer: «no pude obtener evidencia» no equivale a «no se generó evidencia».
|
|
- La conversación termina proponiendo mild como prueba pendiente. No aporta
|
|
una respuesta posterior que confirme su ejecución ni su resultado.
|
|
|
|
Este historial matiza el registro «nunca recovery/Android»: al menos en los
|
|
intentos relatados sí se llega a recovery tras el fallo. No demuestra que el
|
|
kernel del arranque normal alcanzara una fase concreta, porque recovery es
|
|
un arranque posterior. Preparar acceso diagnóstico en el sistema GOOD antes
|
|
de otro ensayo, sin completar Magisk únicamente para obtener logs ni mezclar
|
|
su activación con el cambio de kernel. No interpretar el menú de recovery
|
|
como una indicación de que sea necesario hacer factory reset.
|
|
|
|
## 1. Imagen antigua dentro del ensayo nuevo (confirmado por SHA-256)
|
|
|
|
Raíz de artefactos remota: `/srv/rom/artifacts/009-axp-los23-port/`.
|
|
|
|
Estos dos archivos tienen el mismo SHA-256, recalculado el 26 de septiembre:
|
|
|
|
- `20260921T185024Z-bisect-defconfig-only/boot.img`
|
|
- `20260918T231654Z-axp-kh-full/boot.img`
|
|
|
|
SHA-256: `3715f9f20c8823e5a23323792600b5d76d9f25e73eed3492c28f457a751d3c51`.
|
|
|
|
El script remoto `scripts/009-bisect-defconfig-only.sh` ejecuta `mka bootimage`
|
|
y luego busca el primer `target_files_intermediates/.../IMAGES/boot.img`.
|
|
Ese segundo archivo pertenece al empaquetado anterior: el ensayo termina
|
|
conteniendo dos imágenes con kernels distintos.
|
|
|
|
El `boot-make.img` del ensayo tiene SHA-256 registrado
|
|
`f52405c6b39a14d3357efd59441c9a28128bbce982186b1d86c71b01da8846b1`.
|
|
El README sí indica usar ese archivo. No he encontrado en lo revisado un
|
|
registro de flasheo con hash que permita confirmar cuál se probó. Por tanto,
|
|
la identidad equivocada está demostrada; que se flashease la imagen equivocada,
|
|
no. El script posterior `009-bisect-defconfig-mild.sh` ya evita esta copia.
|
|
|
|
## 2. «Solo defconfig» también cambia código de FORTIFY (confirmado)
|
|
|
|
El mismo script añade a `lib/string.c` definiciones exportadas de
|
|
`__read_overflow`, `__read_overflow2`, `__read_overflow3` y `__write_overflow`,
|
|
todas con cuerpo `BUG()`. El log
|
|
`/srv/rom/artifacts/detach-009-bisect-dc-20260921T180802Z.log` confirma
|
|
`added fortify stubs`.
|
|
|
|
En las fuentes LOS inspeccionadas, `include/linux/string.h:241` y siguientes
|
|
declaran los helpers de lectura con `__compiletime_error`. Proporcionarles
|
|
un cuerpo permite resolver símbolos que impedían enlazar, pero no demuestra
|
|
que las llamadas sean correctas ni que no se ejecuten. Si se alcanza uno de
|
|
esos cuerpos se ejecuta `BUG()`. Falta investigar los sitios de llamada y su
|
|
relación con Clang/LTO; no atribuir el bootloop a ellos sin traza.
|
|
|
|
La conclusión previa «defconfig extras alone are enough to kill boot» es
|
|
demasiado fuerte: el ensayo incluye cambios C, varias opciones simultáneas y
|
|
la ambigüedad de imágenes anterior. Además cambia `SLAB_HARDENED` de Stage1
|
|
por `SLAB_FREELIST_HARDENED`, por lo que tampoco reproduce exactamente su config.
|
|
|
|
## 3. Se avanzó de etapa sin validar arranque (confirmado documentalmente)
|
|
|
|
`docs/009-kernel-hardening-map.md` ordena diferir los CVE hasta que Stage1
|
|
arranque, pero registra tres builds el 18 de septiembre: Stage1, Stage1 con
|
|
unos 500 CVE, y hardening ampliado. Los tres fallaron en LAB según el registro
|
|
del 21. Compilar correctamente no cumplía esa condición.
|
|
|
|
Stage1 ya agrupaba 30 parches y varias opciones; también se documentan restos
|
|
de modificaciones SusFS en el árbol inicial. El script de bisect posterior
|
|
sí limpia las fuentes hasta `28f9290ae067`; no confundir ambos estados.
|
|
|
|
## 4. Aplicación de parches y reparaciones no reproducibles
|
|
|
|
El `apply_stage1.sh` local usa `patch --batch` sin exigir fuzz cero. Ya existe
|
|
un caso documentado de aplicación en la función equivocada: `slab/0014` entró
|
|
en `is_root_cache` en vez de `slab_equal_or_root`.
|
|
|
|
El listado sigue incluyendo ese parche. Las correcciones de slab y FORTIFY
|
|
se describen en `BUILD-FIXES.md`, pero no están implementadas por el aplicador
|
|
local. Ejecutar la receta publicada no reproduce por sí solo el árbol corregido.
|
|
|
|
Otros defectos visibles del aplicador:
|
|
|
|
- Si falta un archivo, incrementa `fail` y continúa; al acabar puede devolver
|
|
éxito porque el último comando es `echo`.
|
|
- Ante fallo elimina `.rej` y `.orig`, perdiendo evidencia; no revierte los
|
|
hunks que se hayan aplicado antes del fallo.
|
|
- `--dry-run` prueba cada parche sobre el mismo árbol sin aplicar sus
|
|
predecesores: no valida fielmente una serie con dependencias.
|
|
|
|
En el servidor, `scripts/009-cve-compile-fix.sh` intenta seleccionar parches
|
|
para excluir por tokens extraídos del mensaje del compilador y registra el
|
|
código de salida de su reversión sin exigir que sea cero. Esto no verifica
|
|
dependencias ni garantiza que el árbol coincida con la denylist. Son defectos
|
|
del método; esta revisión no establece qué rondas concretas los ejercitaron.
|
|
|
|
## 5. Kernel y módulos: compatibilidad pendiente de demostrar
|
|
|
|
Los dos scripts de bisect generan y guardan únicamente imágenes de arranque;
|
|
sus instrucciones reutilizan la ROM `20260918T143547Z-axp-full` instalada.
|
|
No guardan ni indican desplegar un conjunto correspondiente de módulos vendor.
|
|
|
|
El código actual `include/linux/slub_def.h:120` añade el campo `random` a
|
|
`struct kmem_cache` bajo `CONFIG_SLAB_FREELIST_HARDENED`. La `.config` generada
|
|
actual contiene esa opción y `CONFIG_MODVERSIONS=y`.
|
|
|
|
Esto justifica comprobar ABI/CRC de los módulos realmente cargados y los que
|
|
van en el ramdisk/vendor antes de interpretar un ensayo de solo boot. No prueba
|
|
por sí solo incompatibilidad ni explica necesariamente los primeros tres OTA.
|
|
La misma precaución ya consta en `docs/007-susfs-source-audit.md`.
|
|
|
|
## 6. Faltan observabilidad y continuidad entre sesiones
|
|
|
|
El logo de Google no identifica por sí solo la fase exacta del bloqueo.
|
|
El pstore vacío tampoco demuestra que no hubiera traza: la auditoría de `007`
|
|
documenta un error de descifrado de ramoops en LAB. Es evidencia histórica;
|
|
no se ha vuelto a medir el estado actual del teléfono en esta revisión.
|
|
|
|
El mapa local acaba proponiendo el ensayo mild, pero este ya fue compilado:
|
|
|
|
- Artefacto: `20260921T192533Z-bisect-defconfig-mild/boot-make.img`.
|
|
- SHA-256 registrado en su log:
|
|
`6ed0351edb762bdf4bfe2dd96d7e4e2fa43ccf0ad497d7fce35ab88cd722f4f2`.
|
|
- Estado del proceso: `exit=0`, finalizado el 21 a las 19:25:33 UTC.
|
|
- Resultado de arranque: **no encontrado en los registros revisados**.
|
|
- Árbol remoto actual: HEAD `28f9290ae067d3e7857126eb6312720dbe9c7c80`;
|
|
único archivo modificado según Git: `sunfish_defconfig`, con KSU desactivado,
|
|
`SECURITY_DMESG_RESTRICT=y` y `SLAB_FREELIST_HARDENED=y`.
|
|
- `.config` actual: FORTIFY e INIT_ON_ALLOC/FREE desactivados. No sustituye
|
|
a una configuración archivada de cada build anterior.
|
|
|
|
## Punto de reanudación propuesto
|
|
|
|
1. Conservar como referencia el build `20260918T143547Z-axp-full`, cuyo
|
|
arranque está confirmado por el dueño en el mapa. Identificar por hash el
|
|
boot realmente probado en cada bisect y aclarar el resultado de mild.
|
|
2. Reproducir un control sin hardening nuevo con fuentes, herramienta de
|
|
compilación, salida aislada y módulos identificados. Validar arranque en LAB.
|
|
3. Separar las variables: una opción por ensayo. Tratar FORTIFY más sus
|
|
modificaciones C como una investigación propia; no ocultar errores de enlace
|
|
bajo la etiqueta «solo config».
|
|
4. Para cambios que afecten ABI, comprobar o desplegar un conjunto compatible
|
|
de kernel y módulos. Registrar slot, particiones, hashes y resultado.
|
|
5. Recuperar diagnóstico del fallo antes de atribuirlo a un subsistema.
|
|
No borrar datos, alternar slots o añadir parches como sustituto de evidencia.
|
|
6. Congelar cada estado probado: revisión y diff de fuentes, parches y sus
|
|
hashes, `.config` efectiva, compilador, imágenes/módulos, log y resultado.
|
|
No avanzar a CVE ni deblob hasta aceptar la etapa anterior.
|
|
|
|
Deblob no es una causa demostrada en estos ensayos: el registro de `009`
|
|
lo declara pendiente, y la retirada de IPA se omitió expresamente. No se ha
|
|
realizado aquí una auditoría exhaustiva del contenido de todos los payloads.
|