holo-chroot/steamos-chroot: unguarded rmdir in the EXIT trap discards the chrooted command's exit status
Nadie ha tomado este issue todavía.
Evaluación
- Dificultad
- 2/5
- Tiempo estimado
- 1-3 horas
- Aptitud para principiantes
- 72/100
- Tipo de issue
- Error
- Claridad
- Bien especificado
- Estado de actividad
- Activo
- Stack tecnológico
- bash, linux, shell
- Área
- cli, operating-systems
Línea de trabajo
La corrección está en la función cleanup_chroot_at() de /usr/bin/holo-chroot, alrededor de la línea 246, donde el rmdir $dir final de la línea 281 no está protegido, mientras que todos los demás comandos usan || :. Reproduce el problema con un punto de montaje ocupado bajo /efi del chroot mientras se ejecuta el comando dentro del chroot, y luego confirma que el código de salida es 1 a pesar del éxito. Está terminado cuando el código de salida del comando dentro del chroot se conserva en ese caso y se imprime una advertencia opcional cuando el directorio queda sin eliminar.
Escrito por el modelo de indexación a partir del texto del issue.
Descripción
Your system information
- Steam client version: n/a — this is a defect in a shell script shipped in
steamos-customizations-jupiter, not in the client - SteamOS version: reproduced by inspection against
steamos-customizations-jupiter 20260916.1-1, the newest build injupiter-mainat time of writing. Observed in the wild on asteamdeck-oobe-repairrecovery image (linux-neptune-616, e2fsprogs 1.47.3) - Opted into Steam client beta?: No
- Opted into SteamOS beta?: No
- Have you checked for updates in Settings > System?: Yes — the affected line is unchanged in the latest package
Please describe your issue in as much detail as possible
holo-chroot (steamos-chroot) can exit 1 after the chrooted command has fully succeeded, because the final rmdir in its EXIT trap is unguarded.
/usr/bin/holo-chroot runs under set -euo pipefail (line 17) and does its teardown from an EXIT trap:
284 CHROOTDIR=$(mktemp -d)
285 trap "cleanup_chroot_at $CHROOTDIR" EXIT
286
287 prepare_chroot_at $CHROOTDIR
288 chroot $CHROOTDIR "$@"
Inside cleanup_chroot_at() (line 246) every single command is guarded with || : — all eleven umounts, the flocks, and even the other rmdir at line 263:
263 rmdir "$DEV_DIR" || :
...
270 umount $dir/var || :
271 umount $dir/esp || :
272 umount $dir/efi || :
273 umount $dir/tmp || :
274 umount $dir/sys/firmware/efi/efivars || :
275 umount -R $dir/sys || :
276 umount $dir/run || :
277 umount -R $dir/proc || :
278 umount $dir/dev || :
279 umount $dir || :
280
281 rmdir $dir # <-- the only unguarded command in the function
So if any of those mountpoints is busy at teardown time, the umounts are tolerated as intended, but $dir is then necessarily non-empty, rmdir fails, and — because the script runs under set -e — errexit fires from inside the EXIT trap. The shell exits with rmdir's status and the exit status of chroot $CHROOTDIR "$@" is discarded.
The consequence is that any caller which checks steamos-chroot's exit status sees a spurious failure for work that actually completed. Here is a real instance, where update-grub demonstrably succeeded and steamos-chroot still exited 1:
+ steamos-chroot --no-overlay --disk /dev/sdb --partset A -- update-grub
Generating grub configuration file ...
Found linux image: /boot/vmlinuz-linux-neptune-616
Found initrd image: /boot/amd-ucode.img /boot/initramfs-linux-neptune-616.img
Adding boot menu entry for UEFI Firmware Settings ...
done
Installing grub configuration file at /efi/EFI/steamos/grub.cfg
umount: /tmp/tmp.h5fd9aSs2I/efi: target is busy.
umount: /tmp/tmp.h5fd9aSs2I: target is busy.
rmdir: failed to remove '/tmp/tmp.h5fd9aSs2I': Device or resource busy
update-grub wrote its config and reported done; the only failures are in the teardown. An installer calling this in a sequence of steps aborts here, mid-install.
That set -e-inside-a-trap behaviour is easy to miss, so to be explicit about the mechanism:
$ bash -c 'set -e; cleanup() { rmdir /nonexistent; echo AFTER; }; trap cleanup EXIT; true'; echo $?
rmdir: failed to remove '/nonexistent': No such file or directory
1
AFTER never prints — errexit aborts from within the trap — and the script's status becomes 1 despite the body having succeeded. Removing set -e, or adding || :, both yield 0.
Steps for reproducing this issue
- Arrange for one of the chroot's mountpoints to be busy at teardown. Any of them will do; the simplest synthetic version is to hold a reference open while the chroot exits, e.g. run
steamos-chroot --no-overlay --disk $DISK --partset A -- update-grubwhile another process has a file open under the chroot's/efi. - Observe that the chrooted command completes and prints its normal success output.
- Observe that
steamos-chrootnonetheless exits1, with the only errors beingumount: ... target is busyfollowed byrmdir: failed to remove ...: Device or resource busy.
Suggested fix
Guard it like everything else in the function, which also keeps it consistent with line 263:
- rmdir $dir
+ rmdir $dir || :
Optionally warn so the leftover directory isn't silently abandoned:
rmdir $dir || echo >&2 "warning: left $dir behind; something is still using it"
Either way the exit status of the chrooted command is preserved, which is what callers rely on.
Note that why a mountpoint is busy is a separate question, and arguably a legitimate thing for a caller to have to deal with. This report is only about the teardown clobbering an otherwise successful exit status — a busy mountpoint shouldn't turn a completed operation into a failed one.
Found via a third-party SteamOS installer that calls steamos-chroot in sequence and checks each step: louij2/steamos_custom_install#12. Happy to supply more detail if useful.
- Lenguaje dominante
- Sin datos de lenguaje
- Estrellas
- 2.6k
- Forks
- 85
- Métricas de merge de PR
- Sin PR fusionados en 30 d
Preparar el entorno
Este proyecto no incluye contenedor de desarrollo, Dockerfile ni guía de contribución, así que la configuración corre por tu cuenta: empieza por su README y consulta nuestra guía para la primera contribución para los pasos generales.
Primeros pasos
- Lee el issue completo y luego la guía de contribución del proyecto.
- Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
- Haz un fork del repositorio y trabaja en una rama.
- Abre un pull request que haga referencia al número del issue.
Más de ValveSoftware/SteamOS
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 72/100
ValveSoftware/SteamOS#2875 · 1 comentario ·
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 72/100
ValveSoftware/SteamOS#2860 · 1 comentario · 2 reacciones ·
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 68/100
ValveSoftware/SteamOS#2856 ·
-
steam-short-session-tracker: incorrect registry backup path resets settings during automatic repairAbierto
Dificultad 2/5 1-3 horas Aptitud para principiantes 80/100
ValveSoftware/SteamOS#2829 ·
-
Dificultad 1/5 Menos de una hora Aptitud para principiantes 68/100
ValveSoftware/SteamOS#1743 · 1 comentario · 2 reacciones ·
Todos los issues de ValveSoftware/SteamOS
Issues similares
-
README for cliPosiblemente ocupada @Janvi-kapoor la tomó hoy. AbiertoOSCI'26
Dificultad 2/5 1-3 horas Aptitud para principiantes 70/100
GauravKarakoti/SecureFlow#1308 · 1 comentario ·
Los mantenedores suelen responder en 1 día
-
enhancement good first issue
Dificultad 2/5 1-3 horas Aptitud para principiantes 70/100
graygarbage/HermesKey#21 ·
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 70/100
Los mantenedores suelen responder en 1 día
-
area:tui bug has repro platform:macos
Dificultad 2/5 1-3 horas Aptitud para principiantes 62/100
anthropics/claude-code#101933 ·
Los mantenedores suelen responder en 1 día
-
enhancement good first issue
Dificultad 2/5 1-3 horas Aptitud para principiantes 68/100
Edwin-metcalf/MetCode#16 ·