Skip to content

Fix opencode TUI startup when /tmp is mounted noexec (BUN_TMPDIR override) - #41

Merged
nananek merged 4 commits into
masterfrom
fix/opencode-bun-tmpdir-noexec
Aug 11, 2026
Merged

Fix opencode TUI startup when /tmp is mounted noexec (BUN_TMPDIR override)#41
nananek merged 4 commits into
masterfrom
fix/opencode-bun-tmpdir-noexec

Conversation

@nananek

@nananek nananek commented Aug 11, 2026

Copy link
Copy Markdown
Owner

概要

opencode は Bun ランタイムで動き、起動時に埋め込み libopentui.so を TMPDIR(既定 /tmp) へ展開して dlopen する。/tmpnoexec マウントだと mmap(PROT_EXEC) が失敗し TUI 初期化で即死する (anomalyco/opencode issue #26136 / #27580 と同一問題、上流 PR #26134 は未マージ)。

ccserver 側で同等の回避を実装: ホストの TMPDIR が noexec マウント上のとき、非サンドボックス起動の opencode セッションにのみ BUN_TMPDIR=$HOME/.cache/opencode/tmp を設定する。

変更内容

  • server/ws/bunTmpdir.js(新規)
    • parseMountOptions / mountHasNoexec/proc/self/mounts 解析の純関数(最長プレフィックス一致マウント、octal エスケープ復号)
    • isTmpNoexec — linux かつ実在する絶対 TMPDIR(既定 /tmp) が noexec か。symlink は realpath 解決
    • bunTmpdirOverride / bunTmpdirEnv — 切り替え先ディレクトリを作成して返す。mkdir 失敗時は従来動作にフォールバック。ユーザーが明示的に BUN_TMPDIR を設定済みなら上書きしない
  • server/ws/sessionManager.jscreateSession() の pty env に、opencode && !useSandbox のときのみ BUN_TMPDIR を注入。サンドボックス内の /tmp は fresh tmpfs で常に exec 可であり、ホストのキャッシュディレクトリは bwrap にバインドされないため、サンドボックス起動時は何もしない
  • server/ws/bunTmpdir.test.js(新規) — 純関数の単体テスト 11 件(node --test)

テスト

npm test — 313 pass / 1 fail。fail は既知の環境依存テスト (sandbox-resolve.test.js: /usr/bin/claude がこのホストに実在するため)。

…t-aware

isTmpNoexec compared TMPDIR to /proc/self/mounts mountpoints verbatim,
so a symlinked TMPDIR (e.g. /tmp -> /var/tmp on a noexec mount) escaped
detection and Bun kept dying. Resolve with realpathSync first -- the
mount table lists real paths only.

bunTmpdirOverride's test assumed the host TMPDIR is exec and asserted
null unconditionally, which would fail on exactly the noexec hosts this
feature targets. It now derives the expectation from the live mount
table via mountHasNoexec, so it is deterministic everywhere.
bunTmpdirOverride returns ~/.cache/opencode/tmp, not the test's mkdtemp
dir, so on exactly the noexec hosts this feature targets the mount-aware
test from 3065fe8 failed. Expect the actual override path, and realpath
the mkdtemp dir first so a symlinked host TMPDIR (/tmp -> /var/tmp) is
compared the same way isTmpNoexec compares it.
bunTmpdirEnv clobbered a user-set BUN_TMPDIR whenever the host TMPDIR
was noexec. Bun prefers BUN_TMPDIR over TMPDIR, so an explicit value
already sidesteps the noexec problem -- and the override could even
turn a working configuration into a dead launch when HOME is not
writable (the fallback mkdir fails and the launch falls back to the
noexec TMPDIR). Leave an existing BUN_TMPDIR untouched.
@nananek
nananek merged commit b5833d8 into master Aug 11, 2026
4 checks passed
@nananek
nananek deleted the fix/opencode-bun-tmpdir-noexec branch August 11, 2026 17:49
nananek added a commit that referenced this pull request Aug 11, 2026
master が PR #39 で同一の repo_info facade 問題を別設計 (getGroupCwd:
group 内部を露出せず cwd のみ返す) で先行修正済みのため、マージでその
設計を採用。facade への getGroup 追加を撤去し、plan のフェーズ1を
追記更新。BUN_TMPDIR (PR #41) / notify 属性・規律 (PR #37-40) も取り込み。
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant