x/sys/execabs: deprecate, isolate, tag, delete
要約
概要
golang.org/x/sys/execabs パッケージを非推奨にし、最終的には削除する提案です。このパッケージは2021年のセキュリティ問題への一時的な対策として作られたものですが、Go 1.19で標準ライブラリの os/exec が同じ安全な挙動を標準で持つようになったため、役目を終えています。
ステータス変更
likely_accept → accepted
2026年10月1日に likely accept となり、1週間たっても異論が出なかったため、10月8日に @aclements がレビューグループを代表して承認しました。承認された手順は次の4段階です。
//go:fixディレクティブを追加し、x/sys/execabsの利用箇所をos/execへ自動で書き換えられるようにするx/sys/execabsに Deprecated(非推奨)マークを付ける- 月次の x リポジトリのタグ付けを待ち、さらに1か月様子を見て問題が出ないか確認する
- パッケージを isolate(独立したモジュールに分離)し、tag(最終バージョンとしてタグ付け)してから、x/sys から delete(削除)する
提案は2023年11月に出されましたが、利用者がまだ多いことから「//go:fixによる自動移行の仕組みができるまで保留」となっていました。現在はその仕組みが使えるようになったため、議論が再開されて承認に至ったと考えられます。
技術的背景
現状の問題点
2021年に、Windows などで exec.Command("git") のようにパスを付けずにコマンドを実行すると、カレントディレクトリにある同名の実行ファイルが実行されてしまう脆弱性が問題になりました(#43724)。Go チームはツールチェーン内部では internal/execabs で対策し、外部のパッケージでも同じ対策を使えるように x/sys/execabs を公開しました。
その後 Go 1.19 で os/exec 自体の挙動が変わりました。PATH の検索結果が相対パスになる場合は exec.ErrDot を返すようになり、execabs と同等の安全性が標準で得られます。このため internal/execabs は削除されましたが、x/sys/execabs は os/exec の薄いラッパーのまま残っていました。
提案された解決策
execabs の各API(Command、CommandContext、LookPath、Cmd など)に //go:fix inline ディレクティブを付けます。go fix などの自動修正ツールが、呼び出し箇所を os/exec の同名APIへ機械的に書き換えられるようになります。そのうえで非推奨とし、段階を踏んで削除します。
これによって何ができるようになるか
- 依存関係の削減:
os/execだけで同じ安全性が得られるため、x/sysへの依存を一つ減らせる場合があります - 自動移行:
//go:fixによって、手作業なしで移行を進められます - 混乱の解消: 「安全にコマンドを実行するには execabs を使うべきか」という過去の推奨が、公式に「
os/execを使えばよい」に置き換わります - 既存ビルドへの配慮: isolate と tag の手順により、削除後も既存の
go.modは最終タグを参照してビルドを続けられると考えられます
コード例
// Before: セキュリティ対策として x/sys/execabs を使用
import "golang.org/x/sys/execabs"
cmd := execabs.Command("git", "status")
out, err := cmd.Output()
// After: Go 1.19 以降は os/exec で同等の安全性が得られる
import "os/exec"
cmd := exec.Command("git", "status")
out, err := cmd.Output()
if errors.Is(err, exec.ErrDot) {
// カレントディレクトリの実行ファイルに解決された場合はエラーになる
}
議論のハイライト
- @seankhliao が「非推奨にするだけか、tag・isolate・delete まで行うか」を質問しました
- @bcmills は、既存の利用者がまだ多いので、すぐに tag して削除するのは早いと指摘しました。過去に同じ手順で削除されたパッケージは、何年もほとんど使われていないものばかりだったためです。あわせて、
//go:fixインライン機能(#32816)ができるまで保留することを提案しました - @rolandshoemaker(セキュリティ担当)は「急ぐ理由はない」として、
//go:fixの完成を待つ案に賛成しました。中身は薄いラッパーなので、残しておいても保守コストは小さいという判断です - 2026年9月に @aclements が段階的な手順を示しました。「
//go:fixを付けて非推奨にする → 月次タグ付け → さらに1か月待つ → isolate・tag・delete」という流れで、これがそのまま承認された内容になりました