From 2430528c169d62ed981b9b08f59100e08613d00b Mon Sep 17 00:00:00 2001 From: sergio Date: Thu, 30 Jul 2026 17:18:42 -0400 Subject: [PATCH] =?UTF-8?q?dbus:=20las=20pol=C3=ADticas=20de=20login1=20y?= =?UTF-8?q?=20PolicyKit1=20viajan=20en=20su=20ARTEFACTO,=20no=20en=20el=20?= =?UTF-8?q?script=20de=20imagen?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cierra un TODO que el propio script tenía escrito («esto pertenece al artefacto de arje-logind-compat, no a la imagen») y que estaba bien puesto: **un servicio que no puede adueñarse de su nombre no es un servicio**, así que su política D-Bus es parte de lo que el paquete promete, igual que el binario. Con la política en el script de UNA imagen, cualquier otra —metal, KDE, mirada— se llevaba el daemon y no podía usarlo. arje-logind-compat b3:b4795829 · arje-polkit-compat b3:6c82f44b. Radio de las dos: 0. **Y la comprobación que reemplaza a escribirlas atrapó un bug de verdad en el primer intento.** Mover algo a un artefacto sólo es una mejora si se NOTA cuando falta, así que el script pasó de ESCRIBIR los .conf a EXIGIRLOS. Falló al toque: `✗ falta org.freedesktop.login1.conf`. Causa — el script inyectaba **sólo el binario** del artefacto (`install -Dm755 .../usr/bin/...`), así que el .conf existía en el store y nunca llegaba a la imagen. Sin esa comprobación habría sido el fallo tardío de siempre: daemon que arranca, no adquiere el nombre, y 25s de espera por servicio sin decir por qué. Verificado de punta a punta con las políticas viniendo del artefacto: los cuatro nombres del bus arriba (login1, PolicyKit1, Accounts, UPower) y el audio intacto. El `zz-` de la de polkit no es decorativo y queda explicado en su receta: a diferencia de login1, ese nombre YA tiene política —la trae el artefacto de polkit— y permite `own` sólo al usuario polkitd; dbus lee system.d en orden alfabético y las reglas posteriores ganan, así que un fichero que ordene después AÑADE el permiso sin descartar el resto de upstream. ColorManager sigue sin aparecer: es lo de colord, ya diagnosticado hasta dónde llega y fuera del alcance de este cambio. Co-Authored-By: Claude Opus 5 (1M context) --- recipes/arje-logind-compat.toml | 35 +++++++++++++ recipes/arje-polkit-compat.toml | 33 ++++++++++++ scripts/gnome/qemu-desktop-image.sh | 78 ++++++++++------------------- 3 files changed, 94 insertions(+), 52 deletions(-) diff --git a/recipes/arje-logind-compat.toml b/recipes/arje-logind-compat.toml index 95a1f148..fa13dd80 100644 --- a/recipes/arje-logind-compat.toml +++ b/recipes/arje-logind-compat.toml @@ -42,3 +42,38 @@ compiler = "zig-cc" target = "x86_64-linux-musl" link = "static" flags = ["-p", "arje-compat", "--bin", "arje-logind-compat"] + +# ── La POLÍTICA D-Bus viaja con el artefacto, no con la imagen ────────────────────────────────── +# El `system.conf` de dbus trae `` por defecto: cada servicio de sistema aporta su +# propio fichero de política, y el de login1 normalmente lo instala systemd. Acá no hay systemd, así +# que hasta hoy lo escribía `scripts/gnome/qemu-desktop-image.sh` — con un TODO al lado diciendo que +# ése no era su lugar. Y no lo era: **un servicio que no puede adueñarse de su nombre no es un +# servicio**, así que la política es parte de lo que este paquete PROMETE, igual que el binario. +# Dejarla en el script de una imagen significaba que cualquier otra imagen —metal, KDE, mirada— tenía +# el daemon y no podía usarlo. +# +# `allow own` sólo a root (es quien lo lanza) y `send_destination` a cualquiera, porque mutter y el +# resto consultan login1 sin ser root. +# +# La fase `install` REPLICA el default del lab para Cargo (copiar los ejecutables de target/release a +# /usr/bin) y le agrega el fichero. Sobrescribir la fase es la única forma: el default no tiene un +# gancho para material extra. +[build.phases] +install = ''' +set -e +mkdir -p /out/usr/bin /out/usr/share/dbus-1/system.d +find target/release -maxdepth 1 -type f -perm -100 -exec cp {} /out/usr/bin/ \; +cat > /out/usr/share/dbus-1/system.d/org.freedesktop.login1.conf <<'XML' + + + + + + + + + + +XML +''' diff --git a/recipes/arje-polkit-compat.toml b/recipes/arje-polkit-compat.toml index 4a72768d..d86291d3 100644 --- a/recipes/arje-polkit-compat.toml +++ b/recipes/arje-polkit-compat.toml @@ -49,3 +49,36 @@ compiler = "zig-cc" target = "x86_64-linux-musl" link = "static" flags = ["-p", "arje-compat", "--bin", "arje-polkit-compat"] + +# ── La POLÍTICA D-Bus viaja con el artefacto ─────────────────────────────────────────────────── +# Misma razón que en arje-logind-compat: un servicio que no puede adueñarse de su nombre no es un +# servicio, así que su política es parte de lo que el paquete promete. Hasta hoy la escribía el script +# de la imagen de GNOME, con lo cual el shim existía para las otras imágenes y no servía en ellas. +# +# ⚠ EL NOMBRE `zz-` NO ES DECORATIVO. A diferencia de login1, acá el nombre YA TIENE política: la trae +# el artefacto de `polkit`, y permite `own` sólo al usuario **polkitd** — este shim corre como root, así +# que con ella sola se lo niegan. dbus lee `system.d` en ORDEN ALFABÉTICO y las reglas posteriores +# ganan, de modo que un fichero que ordene después AÑADE el permiso sin descartar el resto de la +# política de upstream (que además trae las reglas de `AuthenticationAgent`). Reescribir la de polkit +# habría sido pisar un artefacto sellado. +[build.phases] +install = ''' +set -e +mkdir -p /out/usr/bin /out/usr/share/dbus-1/system.d +find target/release -maxdepth 1 -type f -perm -100 -exec cp {} /out/usr/bin/ \; +cat > /out/usr/share/dbus-1/system.d/zz-arje-polkit-compat.conf <<'XML' + + + + + + + + + + + +XML +''' diff --git a/scripts/gnome/qemu-desktop-image.sh b/scripts/gnome/qemu-desktop-image.sh index 0f169d37..be6e68e0 100755 --- a/scripts/gnome/qemu-desktop-image.sh +++ b/scripts/gnome/qemu-desktop-image.sh @@ -99,36 +99,22 @@ if [ -n "${ALC_BIN:-}" ] && [ -x "$ALC_BIN" ]; then echo " ⚠ binario LOCAL (no sellado): $ALC_BIN" elif ALC="${ALC:-store/$(./target/release/hammer --store store hash recipes/arje-logind-compat.toml 2>/dev/null | tail -1 | sed 's/^b3://')-arje-logind-compat}"; [ -d "$ALC" ]; then install -Dm755 "$ALC"/usr/bin/arje-logind-compat "$MERGED"/usr/bin/arje-logind-compat + # …y su POLÍTICA D-Bus, que desde 2026-07-30 viaja en el artefacto. Se copia, no se escribe: el + # dueño del fichero es el paquete. Ojo — inyectar «sólo el binario» era el bug que destapó la + # comprobación de abajo: el artefacto traía el .conf y la imagen lo dejaba afuera. + install -d "$MERGED/usr/share/dbus-1/system.d" + cp -a --remove-destination "$ALC"/usr/share/dbus-1/system.d/. "$MERGED"/usr/share/dbus-1/system.d/ 2>/dev/null || true echo " ✓ $(basename "$ALC" | cut -c1-12)" else echo " ✗ falta arje-logind-compat en store/ — mutter no hallará sesión" >&2; exit 1 fi -echo "==> política D-Bus para org.freedesktop.login1" -# Segundo muro del mismo eslabón: con el bus ya visible, dbus RECHAZA que el daemon se adueñe del -# nombre — "not allowed to own the service org.freedesktop.login1 due to security policies". El -# system.conf de dbus trae `` por defecto: cada servicio de sistema aporta su propio -# fichero de política, y systemd normalmente instala el de login1. Acá no hay systemd, y el artefacto -# de arje-logind-compat es sólo el binario ⇒ nadie pone la política. La escribimos: root puede -# adueñarse del nombre, y cualquiera puede hablarle (mutter consulta login1 sin ser root). -# TODO: esto pertenece al artefacto de arje-logind-compat, no a la imagen; acá está de forma -# explícita para que se vea qué falta empaquetar del lado de arje. +# La POLÍTICA D-Bus de login1 YA NO SE ESCRIBE ACÁ (2026-07-30): la trae el artefacto de +# `arje-logind-compat`, que es su dueño. Este bloque tenía un TODO diciendo exactamente eso, y estaba +# bien puesto: un servicio que no puede adueñarse de su nombre no es un servicio, así que su política +# es parte de lo que el paquete promete. Teniéndola acá, cualquier OTRA imagen —metal, KDE, mirada— +# se llevaba el daemon y no podía usarlo. Se comprueba abajo, junto con la de polkit. install -d "$MERGED/usr/share/dbus-1/system.d" -cat > "$MERGED/usr/share/dbus-1/system.d/org.freedesktop.login1.conf" <<'XML' - - - - - - - - - - -XML -chmod 644 "$MERGED/usr/share/dbus-1/system.d/org.freedesktop.login1.conf" -echo " ✓ org.freedesktop.login1.conf" echo "==> inyectando arje-polkit-compat (el PolicyKit1 del fractal) + su política" # EL TERCER ESLABÓN DEL MISMO TIPO, y lo destapó la lista de nombres del bus: accounts-daemon y @@ -139,40 +125,28 @@ echo "==> inyectando arje-polkit-compat (el PolicyKit1 del fractal) + su políti # ⚠ El shim autoriza TODO (postura de sistema confiado ya tomada por arje) — ver su receta. if APC="${APC:-store/$(./target/release/hammer --store store hash recipes/arje-polkit-compat.toml 2>/dev/null | tail -1 | sed 's/^b3://')-arje-polkit-compat}"; [ -d "$APC" ]; then install -Dm755 "$APC"/usr/bin/arje-polkit-compat "$MERGED"/usr/bin/arje-polkit-compat + install -d "$MERGED/usr/share/dbus-1/system.d" + cp -a --remove-destination "$APC"/usr/share/dbus-1/system.d/. "$MERGED"/usr/share/dbus-1/system.d/ 2>/dev/null || true echo " ✓ $(basename "$APC" | cut -c1-12)" else echo " ✗ falta arje-polkit-compat en store/ — accounts-daemon y upowerd no adquirirán su nombre" >&2 exit 1 fi -# A DIFERENCIA de login1, acá el nombre YA tiene política: la trae el artefacto de `polkit`. Pero -# permite `own` sólo al usuario **polkitd**, y nuestro shim corre como root ⇒ dbus se lo niega. +# Su política tampoco se escribe acá: viaja en el artefacto (ver recipes/arje-polkit-compat.toml, que +# explica por qué el fichero se llama `zz-` y no reemplaza al de polkit). # -# Se agrega un fichero APARTE en vez de reescribir el de polkit, por dos razones: -# 1. dbus lee todo `system.d` en orden alfabético y las reglas posteriores ganan, así que un -# `zz-…` añade el permiso sin descartar el resto de la política de upstream (que además trae las -# reglas de `AuthenticationAgent`). -# 2. **el fichero de polkit es un HARDLINK DE SÓLO LECTURA del store** — el rootfs fundido se arma -# con hardlinks a los artefactos sellados, que están a 0444. Un `cat >` encima falla con -# `Permission denied`, y eso ya rompió un build de esta imagen. Regla para este script: nunca -# sobrescribir un fichero que venga de un artefacto; agregar al lado, o `rm -f` primero para -# romper el enlace (y entonces se está pisando algo sellado, que es una decisión, no un descuido). -cat > "$MERGED/usr/share/dbus-1/system.d/zz-arje-polkit-compat.conf" <<'XML' - - - - - - - - - - - -XML -chmod 644 "$MERGED/usr/share/dbus-1/system.d/zz-arje-polkit-compat.conf" -echo " ✓ zz-arje-polkit-compat.conf (añade own= para root sobre la política de polkit)" +# ── COMPROBACIÓN, que es lo que reemplaza a escribirlas ──────────────────────────────────────── +# Mover algo a un artefacto sólo es una mejora si se NOTA cuando falta. Sin esto, un artefacto viejo +# sin su .conf daría el mismo fallo tardío y confuso de antes: el daemon arranca, no adquiere el +# nombre, y el escritorio espera 25 s por servicio sin decir por qué. +for pol in org.freedesktop.login1.conf zz-arje-polkit-compat.conf; do + if [ -f "$MERGED/usr/share/dbus-1/system.d/$pol" ]; then + echo " ✓ $pol (del artefacto)" + else + echo " ✗ falta $pol — el artefacto que lo trae es viejo; re-sellá su receta" >&2 + exit 1 + fi +done echo "==> usuario messagebus (el system bus hace setuid a él)" for f in passwd:messagebus:x:81:81:messagebus:/dev/null:/sbin/nologin group:messagebus:x:81:; do