Files
AXP-Resurection/docs/009-fortify-diag-capture-plan.md
T
sunfish-adminandCursor 2d145c2878 009: Polish bacon fixes, OTA host scripts, and migration docs.
Restore disable_configstore, EuiccDisabler and thermal CDEV guards, branding
and rebuild/sync helpers; document device roles, laptop migration, and Gitea.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-16 21:06:45 +02:00

11 KiB
Raw Blame History

Status: historical. Do not use as execution order. Resume: 009-handoff-20261008.md.

Plan: captura verificable del fallo FORTIFY

Revisión posterior: auditoría del diagnóstico del 27/09. El «canal VERIFICADO» de abajo solo demuestra parte de la persistencia: SysRq-x puede dejar la misma marca que se observa tras SysRq-c. Además, el escritor no funciona antes de ramoops_probe. La ausencia de AXPDIAG1 tras fortify-diag no descarta fortify_panic, ni demuestra watchdog. Se conserva abajo el historial original de las pruebas.

Parte de docs/009-fortify-bounds-boot-failure-20260927.md. Referencia LAB: combo4 #16 (sin FORTIFY). No flashear diagnóstico hasta tener canal de captura comprobado en esa referencia.

Hallazgos en combo4 (2026-09-27, solo lectura)

Señal Valor
boot_completed 1
pstore montado sí, vacío
last_kmsg / debugfs no accesibles como shell
Magisk / su no activos (virgin AXP)
cmdline console=null, androidboot.ramdump=disabled
config CONFIG_PSTORE=y, PSTORE_RAM, PSTORE_CONSOLE, ACCESS_RAMOOPS
bootreason tras recover reboot / bootloader (no identifica el panic FORTIFY)

Conclusión: el kernel tiene pstore/ramoops, pero LAB no entrega traza útil tras el reboot a fastboot. Cambiar más CONFIGs sin canal de evidencia repite el bucle anterior.

Objetivo del arranque de diagnóstico

Distinguir, con registro persistente o serial:

  1. fortify_panic (caller + backtrace)
  2. fallo CFI
  3. watchdog / softlockup
  4. fallo de carga de módulos / ABI

Sin eso, no atribuir el logo Google a audio/WLAN ni a FORTIFY genérico.

Pasos (orden)

  1. Canal de captura en combo4 (sin FORTIFY)

    • Confirmar cómo Pixel 4a/sunfish expone ramoops tras panic (ACCESS_RAMOOPS, partición klog/logfs, ramdump=disabled).
    • Probar un panic controlado mínimo en un boot solo diagnóstico (no ship) y verificar que shell/root puede leer /sys/fs/pstore/console-ramoops* tras el siguiente arranque bueno.
    • Alternativa: UART/serial o androidboot.console no-null si el lab lo permite. Si el canal falla, no flashear FORTIFY otra vez.
  2. Instrumentar fortify_panic (solo en árbol de ensayo)

    • Antes del BUG(): pr_emerg con %pS del return address + stack.
    • Mantener el panic (no convertir en no-op).
    • Misma receta ksync (GOODMAKE + kernel FORTIFY+POS0+bounds).
  3. Marcas CFI / módulos

    • Si el log muestra CFI: seguir esa vía.
    • Si aparece durante insmod/init de vendor: comparar CRC/ABI de módulos (requiere root o dump desde recovery).
    • Si watchdog sin fortify/CFI: otra clase de hang.
  4. Empaquetador

    • Quitar el || true que traga el SIGILL de magiskboot en VERIFY, o verificar el header en el laptop con el mismo SHA. Defecto de script, no causa del reboot (imagen unpack OK en laptop).
  5. Solo después de una traza atribuible: cambio mínimo (call site, excepción justificada, o más port). No stubs. No ship FORTIFY.

Estado 2026-09-27 (tras Rooted debugging)

  • adb root OK.
  • vendor.ramoops.decryption.error=1 en boot normal.
  • Causa 1: /vendor/bin/ramoops hardcodea /sys/devices/soc/.../size pero el kernel expone /sys/devices/platform/soc/... (y vía /sys/class/misc/.../size). Binario parcheado en /data/local/tmp/ramoops.fix para class paths.
  • Causa 2: tras eso, kernel log ramoops: Failed to set key, -22 (EINVAL) al escribir AES en sysfs. pstore sigue vacío. Remount pstore denegado por SELinux.
  • Claves RSA sí existen en /data/vendor_ce/0/ramoops/{priv,pub}.pem.
  • boot_debug/crash.txt es basura userspace antigua, no kernel FORTIFY.
  • Build fortify-diag (panic instrumentado) sigue en curso.

Captura post fortify-diag (2026-09-27 ~01:36)

Tras flash diag → fallo → recover combo4 #16 + adb root:

  • pstore vacío; boot_debug/kernel.txt vacío; sin FORTIFY_DIAG en claro.
  • Dump /dev/access-ramoops (4 MiB): entropía alta (cifrado); 0 strings útiles.
  • Decrypt sigue fallando (Failed to set key, -22).

Prueba de canal con SysRq-c en combo4:

  • Bootloader registró androidboot.bootreason=kernel_panic (panic real).
  • Aun así pstore vacío y alt cifrado sin plaintext.

Conclusión: en este LAB un kernel_panic no produce traza legible vía pstore hasta arreglar el pipeline AES/ramoops. El síntoma FORTIFY (antes del SysRq) había dejado bootreason=reboot/bootloader, no kernel_panic — hipótesis abierta: reset/wdog distinto de fortify_panic, o el bootloader reescribe el motivo al pasar por fastboot.

Siguiente trabajo de captura: diag sin cifrado (pstore/ramoops plaintext) o arreglo del setkey; no más flashes FORTIFY hasta tener canal verificado con SysRq → fichero legible en pstore.

Captura plaintext (2026-09-27 ~01:45)

Hallazgos en combo4 tras Rooted debugging + reboot sin unlock:

Señal Valor
dumpsys user RUNNING_LOCKED, Unlock time unknown
sys.user.0.ce_available vacío
/data/vendor_ce/0/ramoops Required key not available
mount | grep pstore vacío tras on boot umount
Remount manual pstore + use_alt=0 monta OK, sigue sin ficheros
/dev/pmsg0 + reboot no aparece pmsg-ramoops-*
SysRq-c bootreason=kernel_panic, alt cifrado, primary vacío

Causa de sistema (no solo FORTIFY):

  1. init-ramoops.rc hace umount /sys/fs/pstore en on boot y solo remonta cuando vendor.ramoops.decrypted=true (tras CE unlock + ramoops -D).
  2. Binario /vendor/bin/ramoops usa paths sysfs pre-platform/ → size=-1; con binario parcheado a class paths, CE locked → sin priv.pem.
  3. Writes de pstore van al primary; el carveout que sobrevive/lee userspace tras decrypt es el alt cifrado (/dev/access-ramoops).
  4. ramoops_init_prz hace persistent_ram_zap(primary) tras save_old en console/pmsg — el pipeline asume encrypt-on-shutdown a alt.

Canal de evidencia (sin CE / sin AES): patch diag ramoops_axp_plaintext_alt — en DMESG oops/panic escribe magic AXPDIAG1 + cuerpo en claro al alt (ioremap). Verificación LAB:

dd if=/dev/access-ramoops bs=1M count=4 | strings | grep -E 'AXPDIAG1|Kernel panic'

Build canal (sin FORTIFY): scripts/009-bisect-ksync-pstore-alt-plain.sh (PSTORE_ALT_PLAIN=1). Probar SysRq → magic legible antes de otro flash FORTIFY.

Iteración 2 (ioremap en panic)

  • Alt carveout sí persiste: write userspace AXPUSER1 → reboot → sigue ahí.
  • Build 20260927T001522Z con mirror vía ioremap_wc en ramoops_pstore_write (contexto panic/atomic): SysRq → bootreason=kernel_panic pero sin AXPDIAG1 (ioremap no es safe ahí; write silencioso no-op).
  • Fix: pre-map en ramoops_probe (axp_alt_va) + solo memcpy_toio/wmb en panic. Rebuild: job 009-bisect-ksync-pstore-alt-plain2.
  • plain2: map OK + SysRq kernel_panic, sin AXPDIAG1 (aliasing WC vs ioremap).
  • plain3: AXPDIAG0-probe legible tras boot (kernel→alt OK). Tras SysRq solo AXPDIAG0 — el hook DMESG pstore no corre en este panic path.
  • plain4: panic_notifier + AXPDIAG1-panic-notifier, pero el boot siguiente reescribía AXPDIAG0 encima. Fix: no clobber si head=AXPDIAG1. Rebuild: pstore-alt-plain5.

Canal VERIFICADO (plain7, 20260927T024949Z)

Prueba Resultado
echo x > /proc/sysrq-trigger (sin panic) AXPDIAG1-sysrq-fixed en /dev/access-ramoops
sysrq-x + adb reboot AXP alt keeps prior AXPDIAG1 capture
sysrq-x + sysrq-c → bootreason=kernel_panic magic AXPDIAG1 sobrevive (cuerpo a veces truncado por reset)
Metadata /dev/access-metadata tras panic reescrita (claves AES); no usar

Lectura post-fallo (root, no hace falta unlock CE):

adb root
dd if=/dev/access-ramoops bs=1M count=4 | strings | grep AXPDIAG
dmesg | grep AXP

v4 canal (post review v3 2026-09-27)

Ver docs/009-fortify-diag-v3-review-20260927.md. v3 obsoleto: ioremap tras paging_init (antes de slab/vmalloc) puede tumbar el control sin FORTIFY; attrs early cached vs IO; milestones compartían slots con el fallo.

apply_fortify_diag.py v4:

  • Early: early_ioremap (FIXMAP_PAGE_IO) antes de parse_early_param; se mantiene hasta después de mm_init. Permanente: ioremap solo tras mm_init. Handler nunca mapea.
  • Layout página 0: fallo @0 (+ mirrors); milestones @2048 (zonas separadas).
  • Adoptar fallo previo solo si registro completo (header + \\n + mirror).
  • Ciego residual: pre-early_map; ventana breve al cambiar early→perm si el VA se publica mal (v4 publica permanente antes de retirar early).

Validación control (sin FORTIFY) — media/tardía; no prueba pre-early_map:

  1. Wipe zona fallo: dd if=/dev/zero of=/dev/access-ramoops bs=4K count=1
  2. Flash pstore-alt-plain v4, boot, adb root.
  3. Milestones: strings | grep AXPDIAG0 → ...,early_map / perm_map / mm_init (offset distinto; pueden coexistir con un AXPDIAG1).
  4. Solo SysRq-c (sin x).
  5. Recover combo4 → AXPDIAG1,C,<attempt>,0x...,sysrq-c completo.
  6. Solo entonces fortify-diag v4.

Review resultados v4

Ver docs/009-fortify-v4-capture-results-review-20260927.md, docs/009-fortify-v4-clean-tests-verification-20260927.md, y artefactos:

  • .local-artifacts/009-v4-clean-c-20260927T190738Z/
  • .local-artifacts/009-v4-x-persist-20260927T191143Z/
  • .local-artifacts/009-v4-twophase-x-then-c-20260927T191809Z/ (adb readback then panic: pre-verified X lost by P3)

LAB 2026-09-27 (plain-v4 20260927T084531Z) — hechos vs hipótesis

Demostrado

  • Writer de first-failure en vivo: SysRq-x → AXPDIAG1,X,20260927T084531Z,0x...,sysrq-x @0 (+ mirrors).
  • Milestone slot @2048 recibe AXPDIAG0,M,...,panic_reg (último stage; sobrescribe stages previos en el mismo offset).
  • Tras SysRq-c (arranque sin x previo) + recover combo4: no hay AXPDIAG1 en ninguno de los 8 slots de fallo; @0 es opaco.

No demostrado / correcciones

  • No hay, en el código revisado, una rutina de cifrado del alt al entrar en panic. Sí hay camino de descifrado del alt. «Desactivar encrypt en el kernel» no apunta aún a una función identificada; no usar eso como siguiente paso.
  • Que panic_reg aparezca @2048 tras combo4 no prueba zona segura ni supervivencia al panic: combo4 no escribe AXPDIAG*, pero un arranque intermedio de v4 regenera el mismo panic_reg con el mismo attempt id. Hace falta attempt id distinto por boot, o wipe + leer sin otro boot v4, antes de atribuir persistencia.
  • El latch axp_first_latch es solo RAM: un wipe del dump no lo resetea. Si en el mismo arranque se hace SysRq-x y luego SysRq-c, c no escribe. Las pruebas c-only válidas requieren wipe y reboot (o imagen nueva) sin x previo en ese boot.
  • Causa de @0 opaco tras c (sobrescritura, fallo de escritura, otro productor): abierta.