voidzero-dev / voidzero-dev/vite-task

Cached tasks cannot spawn child processes inside a rootless bubblewrap sandbox (EPERM)

オープン
#700 コメント 2 件 リアクション 0 件 担当者 0 名 GitHub で見る

まだ誰も着手していません。

主要言語
Rust
スター
466
フォーク
42
平均マージ
1日 15時間
マージ済み PR(30日)
19

説明

Summary

Inside a rootless bubblewrap sandbox, a cache-enabled task cannot spawn child processes. Every spawn/spawnSync/execFile fails with EPERM before the child runs. Setting cache: false on the same task, with nothing else changed, makes it work.

The path is absolute and executable in both cases, so this is not PATH resolution.

Reproduction

Sandbox is entered as:

bwrap --die-with-parent --new-session \
  --unshare-user --unshare-pid --unshare-ipc --unshare-uts --unshare-cgroup --unshare-net \
  --cap-drop ALL \
  --clearenv --setenv PATH /runtime/bin \
  --ro-bind <toolchain-image> /runtime \
  --tmpfs /tmp --dev /dev --proc /proc \
  --bind <checkout> /workspace \
  -- /runtime/bin/sh -c 'cd /workspace && vp run -r test'

There is no /usr/bin, /bin or /usr/lib in the sandbox; everything is under /runtime.

Any cached task whose command spawns a child reproduces it:

execFileSync("/tmp/shell/sh", ["-n"], { input: script });
task config spawn
{ command: 'vp test' } EPERM
{ command: 'vp test', cache: false } works

In one vp run -r test over a workspace, the packages I had flipped to cache: false spawned fine while the packages still cached failed in the same run, same sandbox, same commit. Flipping two packages took the spawn failures from 74 to 0.

Observed

Error: spawnSync /tmp/shell/sh EPERM
Error: spawn EPERM

Nothing is printed by the child. git subprocesses fail the same way one level down:

fatal: cannot exec 'git-receive-pack': Operation not permitted

Environment

  • vite-plus 0.3.0
  • Linux x86_64, glibc
  • rootless bubblewrap, seccomp, unprivileged user namespaces

Notes

Not #569/#576 — 0.3.0 has both. LD_PRELOAD is unset going in, so not #340.

Guess: fspy_preload_unix has to inject into each child, and this sandbox is --cap-drop ALL with /usr/lib unmounted, so either the preload object is unreachable in the child's mount namespace or something it does on init is denied — and the exec is refused instead of tracking degrading.

Falling back to caching without file tracking would be better than failing the spawn. Today the only workaround is disabling the cache for the whole package.

Happy to run patches or a debug build against the sandbox.

コントリビューションガイド

コントリビューションガイドを開く

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

調査の方向性

提供された rootless の bubblewrap コマンドで失敗を再現し、vp run -r test を使ってキャッシュされたタスクとキャッシュを無効にしたタスクを比較します。まず fspy_preload_unix パスと子プロセスのセットアップをトレースします。この作業の完了条件は、この sandbox でキャッシュされたタスクを spawn できること、または exec をブロックせずにトラッキングが劣化することです。

索引モデルが issue の本文から書いたものです。

評価

技術スタック
linux, rust
領域
operating-systems, security, tooling
issue の種類
バグ
難易度
4/5
見積もり時間
3〜5日
活発さ
活発
明瞭さ
おおむね明確
初心者へのやさしさ
48/100

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。