Rust版cp、UbuntuのISOビルドを壊す。再びGNUへ

Rust版cp、UbuntuのISOビルドを壊す。再びGNUへ

Rust版coreutilsのcpコマンドが、フラグの優先順位処理の不具合でUbuntuのライブメディアISOビルドを破壊した。Ubuntuはcpを再びGNU版へ差し戻した。26.04 LTSのリリースから2ヶ月、互換性の問題はまだ出続けている。


-afLが通らない

Rust版cp-afLを渡すと、ディレクトリのコピーが失敗する。GNU版では通る組み合わせだが、Rust版は-r not specified; omitting directoryを返す。

UbuntuのライブメディアISOを構築するスクリプトlivecd-rootfsは、設定ファイルの複製にこのフラグの組み合わせを使っていた。ビルドは止まり、ISOは生成されなくなった。

cp -afL 実行時の処理フロー
cp -afL を実行-a を -dR --preserve=all に展開-L との排他処理GNU版コピー成功-d のみ上書き、-R は残るRust版 (overrides_with_all)コピー失敗-a 全体を無効化、-R も消える
※GNU版cpは-aの構成要素(-d)のみ-Lで上書きし、-Rと--preserve=allは保持する。Rust版はclapのoverrides_with_allにより-a全体が無効化される

Launchpad上のバグ報告は「重大」に分類されている。

原因は、Rustの引数解析ライブラリclapのoverrides_with_all機能にある。cp-a-L-H-P-dはシンボリックリンクの扱いを決める排他的なフラグ群だ。従来のRust版実装では、clapのoverrides_with_allで後から指定されたフラグが前のフラグを上書きする仕組みにしていた。

問題は、-aが単なるフラグではなく-dR --preserve=allの複合フラグである点にある。overrides_with_all-aを丸ごと無効化してしまい、再帰コピー(-R)と属性保持(--preserve=all)まで消える。-afLを指定しても-Rが消えた状態になり、ディレクトリをコピーできない。

リバートか、スクリプト側の修正か

バグ報告の中では、ビルドスクリプト側を修正してRust版cpとの互換性を維持すべきだという意見も出た。cp -afLcp -RL --preserve=allに書き換えれば動作する、という提案だ。

一理ある。リバートを繰り返せば、Rust版が抱えるエッジケースは表面化しないまま残る。ビルドが失敗して初めてバグが見つかったように、実際に使わなければ互換性の欠落は検出できない。

Ubuntuはcoreutils-fromパッケージのアップデートでcpをGNU版に差し戻した。cpmvrmの3コマンドは、Ubuntu 26.04 LTSのセキュリティ監査でTOCTOU(検査時点と使用時点の競合)の問題が残っていたため、4月のリリース時点からGNU版が据え置かれていた。今回のリバートはそれとは別の経路で、フラグ処理の互換性問題による対応だ。

上流での修正は提出済み、未マージ

uutils/coreutilsにはプルリクエスト#13258が提出されている。修正の方針は、clapのoverrides_with_allによる排他処理をやめ、全フラグをclapのマッチ結果に共存させた上で、独自の優先順位ロジックで最後に指定されたフラグを判定する形に変更するものだ。

報告されたイシュー#13207は、Ubuntu 26.04上でcoreutils-from-uutilsバージョン0.0.0~ubuntu27を使用した際に確認されている。GNU版のcpでは同じフラグの組み合わせで問題は起きない。

このプルリクエストは現地時間7月2日に提出されたが、記事執筆時点で未マージだ。

移行は前に進んでいるのか

Canonicalは、Ubuntu 26.10で「100% Rust coreutils」を目指すと表明している。4月のセキュリティ監査で113件の問題が見つかり、cpmvrmの3コマンドはGNU版のままUbuntu 26.04 LTSに入った。

Rust版coreutils Ubuntu移行の経緯
2025年10月
Ubuntu 25.10リリース
Rust版coreutilsをデフォルトに採用
2026年4月
Ubuntu 26.04 LTSリリース
セキュリティ監査で113件の問題。cp・mv・rmはGNU版据え置き
2026年7月
-afLバグ発覚
Rust版cpがISOビルドを破壊。cpを再びGNU版にリバート
2026年10月
Ubuntu 26.10(目標)
Canonicalは「100% Rust coreutils」を目指すと表明

今回の-afLバグは、TOCTOUとは性質が異なる。セキュリティ上の構造的課題ではなく、引数解析という基本的な処理に互換性の欠落が残っていた。

Ubuntu 25.10でRust版coreutilsをデフォルトに据えてから約9ヶ月。上流のuutilsプロジェクトは0.9.0をリリースし、GNUテストスイートの合格率は伸び続けている。

それでも、ISOビルドスクリプトで踏むまで見つからないバグが残っている。GNUが30年かけて固めてきた引数処理には、文書化されていない振る舞いがある。テストスイートの合格率が示すのは、文書化された振る舞いとの一致度だ。

文書化されていない振る舞いに依存するスクリプトがいくつあるのか、誰にもわからない。

関連記事

この記事を共有する