Files
AXP-Resurection/docs/009-kernel-boot-audit-20260926.md
T
sunfish-admin deaaf42caa 009: Magisk ship pack through US-S5-1 + US-S4 OpenSSH/Jelly/Gallery2.
Release-keys/AVB, CVE clean+hi batches, Yama/slabrand, Pro branding,
bundled apps, and AXP-class product surface docs/scripts.
2026-10-05 10:42:00 +02:00

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.