ADR 0017: kexec por kexec_file_load, y la decisión 2 pasa de viable a costo

La diferencia entre los dos syscalls decide el frente: kexec_load pide
los segmentos armados y el purgatory (= kexec-tools entero);
kexec_file_load recibe los descriptores y hace el trabajo adentro, ~50
líneas sin dependencias.

Con recipes/linux-metal-kexec.toml (única diferencia: CONFIG_KEXEC_FILE)
queda respondida media decisión abierta nº2: kexec y Secure Boot SÍ
pueden coexistir, porque lockdown prohíbe kexec_load y acepta
kexec_file_load con imagen firmada. Lo que queda es si se firma y quién
paga el artefacto extra — decisión de coste, no de viabilidad.

Y queda anotado el diagnóstico que mandaba al lugar opuesto: EPERM no es
"falta CONFIG_KEXEC_FILE" sino falta de CAP_SYS_BOOT. Medido en el hub,
cuyo kernel trae el flag y aun así dio EPERM por no ser root. Tercera
vez en dos días que el error caro no es el mecanismo sino el mensaje que
lo explica.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HHAKWoBqof9XvsYCvDicEj
This commit is contained in:
Sergio
2026-09-12 01:05:57 +00:00
co-authored by Claude Opus 5
parent 0a9622c7b0
commit d604d850db
+36 -4
View File
@@ -77,6 +77,35 @@ ahorra son los 2030 s de POST/UEFI, que en un servidor remoto es la mitad del
portátil no es nada. Ser la distro que **no confunde las tres** ya es una posición: la confusión es
la norma del mercado.
> **ENMIENDA 2026-09-12 (2ª) — `kernel kexec` implementado, y por `kexec_file_load`.**
>
> La diferencia entre los dos syscalls es de **orden de magnitud**, y decide el frente entero:
>
> - `kexec_load` (el que traen los seis kernels sellados) recibe los **segmentos ya armados** y el
> *purgatory* —el código que corre entre los dos kernels—. Usarlo obliga a reimplementar
> kexec-tools, o a empaquetarlo.
> - `kexec_file_load` recibe los **descriptores** del kernel y del initrd y hace el trabajo adentro.
> **~50 líneas**, sin dependencias ajenas.
>
> El syscall va con `asm!` en vez de agregar la crate `libc` al workspace: es **un** syscall, su
> número y su ABI son contrato estable de Linux, y la alternativa era arrastrar una dependencia a un
> workspace que comparten dos frentes. El cmdline viaja **con su NUL** — el kernel cuenta
> `cmdline_len` incluyendo el terminador, y es el error clásico de esta llamada.
>
> **Y esto responde media decisión abierta n.º 2.** `recipes/linux-metal-kexec.toml` es una variante
> cuya única diferencia es `CONFIG_KEXEC_FILE=y`. Variante y no flag en la canónica porque el
> `.config` **es** la identidad del artefacto (SDD 22 §1) y esa decisión es del usuario; comprobado
> que la canónica **no se movió** (`b3:2ed8f54a…`, el que ya está sellado). Con ese flag, kexec y
> Secure Boot **pueden** coexistir: lockdown prohíbe `kexec_load` y acepta `kexec_file_load` con
> imagen firmada. Lo que queda por decidir es si se firma, no si es posible.
>
> **Un diagnóstico que corregí a los dos minutos de escribirlo, porque mandaba al lugar OPUESTO.**
> El primer `match` de errno decía «falta `CONFIG_KEXEC_FILE`» para **EPERM**. Medido en este mismo
> hub: el kernel de Artix trae `CONFIG_KEXEC_FILE=y` y aun así devolvió EPERM — **por no ser root**.
> EPERM es falta de `CAP_SYS_BOOT` (o lockdown, si ya sos root); **ENOSYS** es el flag que falta.
> Confundirlos manda a recompilar un kernel que estaba perfecto. Es la tercera vez en dos días que
> el error caro no es el mecanismo sino **el mensaje que explica el mecanismo**.
### 2. A/B con vuelta atrás automática — esto es lo que vale
`kexec` solo no hace fuerte a nadie: hace *rápido*. Lo que hace fuerte es que **si el kernel nuevo
@@ -189,10 +218,13 @@ mentiras de la categoría. `stage` + `kexec` + rollback automático es el techo
Si **no**: hay que escribirlo como decisión explícita, para que dentro de un año nadie lo
«arregle» encendiendo módulos en el kernel general creyendo que fue un olvido.
2. **¿`kexec` es compatible con el destino de Secure Boot?** **ABIERTA, y depende del 0018.**
Hoy no lo es: falta `KEXEC_FILE` y sobra el `kexec_load` viejo. Si el 0018 decide firmar, este
ADR necesita `CONFIG_KEXEC_FILE=y` + `KEXEC_SIG`, que **re-hashea los seis kernels**. Si el 0018
decide no firmar, `kexec` funciona como está y esto se cierra sin costo.
2. **¿`kexec` es compatible con el destino de Secure Boot?** ✅ **RESPONDIDA (2026-09-12): sí, con
`KEXEC_FILE`.** Ya no es una incógnita técnica sino un costo conocido: existe
`recipes/linux-metal-kexec.toml` con el flag, y bajo lockdown ese es justamente el syscall que el
kernel acepta. Lo que queda abierto es **si el perfil que use kexec adopta esa variante** (un
artefacto de kernel más) o si se enciende el flag en la canónica (re-hashea el kernel de todas
las imágenes). Eso sí sigue siendo decisión del usuario, pero es una decisión de *coste*, no de
viabilidad.
## Riesgos conocidos