holo-chroot/steamos-chroot: unguarded rmdir in the EXIT trap discards the chrooted command's exit status
Nessuno ha ancora preso questa issue.
Valutazione
- Difficoltà
- 2/5
- Tempo stimato
- 1-3 ore
- Idoneità per principianti
- 72/100
- Tipo di issue
- Bug
- Chiarezza
- Specificata chiaramente
- Stato di attività
- Attiva
- Stack tecnologico
- bash, linux, shell
- Ambito
- cli, operating-systems
Direzione di ricerca
La correzione si trova nella funzione cleanup_chroot_at() in /usr/bin/holo-chroot, intorno alla riga 246, dove l'ultimo rmdir $dir, alla riga 281, non è protetto mentre tutti gli altri comandi usano || :. Riproduci il problema con un mountpoint occupato sotto /efi del chroot mentre viene eseguito il comando nel chroot, quindi verifica che lo stato di uscita sia 1 nonostante il successo. È completato quando, in quel caso, lo stato di uscita del comando eseguito nel chroot viene preservato e, facoltativamente, viene stampato un avviso quando la directory rimane presente.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Descrizione
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.
- Lingua principale
- Nessun dato sulla lingua
- Stelle
- 2.6k
- Fork
- 85
- Metriche di merge delle PR
- Nessuna PR unita negli ultimi 30g
Preparare l'ambiente
Questo progetto non fornisce container di sviluppo, Dockerfile né guida per i contributori, quindi l'ambiente è a tuo carico: parti dal suo README e consulta la nostra guida al primo contributo per i passaggi generali.
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Altre issue di ValveSoftware/SteamOS
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 72/100
ValveSoftware/SteamOS#2875 · 1 commento ·
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 72/100
ValveSoftware/SteamOS#2860 · 1 commento · 2 reazioni ·
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 68/100
ValveSoftware/SteamOS#2856 ·
-
steam-short-session-tracker: incorrect registry backup path resets settings during automatic repairAperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 80/100
ValveSoftware/SteamOS#2829 ·
-
Difficoltà 1/5 Meno di un'ora Idoneità per principianti 68/100
ValveSoftware/SteamOS#1743 · 1 commento · 2 reazioni ·
Tutte le issue di ValveSoftware/SteamOS
Issue simili
-
needs triage
Difficoltà 2/5 1-3 ore Idoneità per principianti 72/100
topgrade-rs/topgrade#2419 ·
I maintainer di solito rispondono entro 1 giorno
-
area: watch bug priority: low
Difficoltà 2/5 1-3 ore Idoneità per principianti 88/100
I maintainer di solito rispondono entro 1 giorno
-
bug good first issue
Difficoltà 2/5 1-3 ore Idoneità per principianti 82/100
eugenioenko/ttt#919 · 1 commento ·
I maintainer di solito rispondono entro 1 giorno
-
Standalone Unix updater reports success when curl fails (`curl | sh` masks the exit status); Windows path is unaffectedForse già presa @akhil9tiet l’ha presa oggi. Apertabug CLI windows-os
Difficoltà 2/5 1-3 ore Idoneità per principianti 72/100
openai/codex#54465 · 1 commento ·
I maintainer di solito rispondono entro 1 giorno
-
bug
Difficoltà 2/5 1-3 ore Idoneità per principianti 68/100
jbacalso24/mimry#291 ·
I maintainer di solito rispondono entro 1 giorno