holo-chroot/steamos-chroot: unguarded rmdir in the EXIT trap discards the chrooted command's exit status
まだ誰も着手していません。
評価
- 難易度
- 2/5
- 見積もり時間
- 1〜3時間
- 初心者へのやさしさ
- 72/100
- issue の種類
- バグ
- 明瞭さ
- 明確に書かれている
- 活発さ
- 活発
- 技術スタック
- bash, linux, shell
- 領域
- cli, operating-systems
調査の方向性
修正箇所は /usr/bin/holo-chroot の cleanup_chroot_at() 関数、246行目付近です。281行目の最後の rmdir $dir だけが保護されておらず、他のすべてのコマンドは || : で保護されています。chroot の /efi 配下でビジーなマウントポイントを開いたままchroot内のコマンドを実行して再現し、成功したにもかかわらず終了ステータスが 1 になることを確認してください。その場合にchroot内コマンドの終了ステータスが保持され、ディレクトリが残されたときにオプションで警告が表示されれば完了です。
索引モデルが issue の本文から書いたものです。
説明
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.
- 主要言語
- 言語のデータがありません
- スター
- 2.6k
- フォーク
- 85
- PR マージ指標
- 30日以内にマージされた PR はありません
環境構築
このプロジェクトには開発コンテナ、Dockerfile、コントリビューションガイドがありません。まず README を読み、一般的な手順ははじめてのコントリビューションガイドを参照してください。
はじめの一歩
- issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
- 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- issue 番号を参照したプルリクエストを送ります。
ValveSoftware/SteamOS のほかの issue
-
難易度 2/5 1〜3時間 初心者へのやさしさ 72/100
ValveSoftware/SteamOS#2875 · コメント 1 件 ·
-
難易度 2/5 1〜3時間 初心者へのやさしさ 72/100
ValveSoftware/SteamOS#2860 · コメント 1 件 · リアクション 2 件 ·
-
難易度 2/5 1〜3時間 初心者へのやさしさ 68/100
ValveSoftware/SteamOS#2856 ·
-
steam-short-session-tracker: incorrect registry backup path resets settings during automatic repairオープン
難易度 2/5 1〜3時間 初心者へのやさしさ 80/100
ValveSoftware/SteamOS#2829 ·
-
難易度 1/5 1時間未満 初心者へのやさしさ 68/100
ValveSoftware/SteamOS#1743 · コメント 1 件 · リアクション 2 件 ·
ValveSoftware/SteamOS の issue をすべて見る
似ている issue
-
black --check exits 0 and prints All done when a multi file run is interrupted対応中かも @jiteshgulati が今日担当しました。 オープン
難易度 2/5 1〜3時間 初心者へのやさしさ 72/100
メンテナーはふだん 2 日以内に返信
-
README for cli対応中かも @Janvi-kapoor が今日担当しました。 オープンOSCI'26
難易度 2/5 1〜3時間 初心者へのやさしさ 70/100
GauravKarakoti/SecureFlow#1308 · コメント 1 件 ·
メンテナーはふだん 1 日以内に返信
-
bug discussion
難易度 2/5 1〜3時間 初心者へのやさしさ 70/100
medialab/xan#1201 · コメント 2 件 ·
メンテナーはふだん 1 日以内に返信
-
難易度 2/5 1〜3時間 初心者へのやさしさ 68/100
ajeetdsouza/zoxide#1323 ·
メンテナーはふだん 1 日以内に返信
-
enhancement good first issue
難易度 2/5 1〜3時間 初心者へのやさしさ 70/100
graygarbage/HermesKey#21 ·