Rustの開発者は、不正なライフタイム関係を持つコードがコンパイルを通過する可能性がある、型システムの欠陥を調査している。この欠陥は、安全なRustコードではメモリ安全性が損なわれないという言語の保証を揺るがすものだ。型の単一化とフィールドへの代入の際に、構造体に課されたライフタイムの要件が回避されることに関係している。
Rustプロジェクトの公開課題追跡システムに寄せられた報告には、コンパイルは通るものの、データの有効なスコープが終了した後にそのデータを読み出せるコード例が含まれている。AddressSanitizerを有効にすると、実証例の一つでstack-use-after-scope、つまりスコープ終了後のスタック領域の使用というエラーが発生する。別の形では、クラッシュしたり、解放済みメモリの内容が露出したりする可能性がある。報告者は、関連するコード例が、何年も前にさかのぼるRustの安定版リリースでもコンパイルできることを確認した。
Types Teamは、このバグにP-highの優先度を付けた。プロジェクトのメンテナーは、この種の問題が新たに持ち込まれたものであれば、通常は最も深刻な分類に相当すると説明している。Rustの型システムは、明示的なunsafe操作を使わないコードでメモリ安全性を損なう挙動が起きないように設計されているためだ。今回は、それより低い優先度となった。この欠陥が約11年間発見されずに存在していたことを示す証拠から、偶然この問題に遭遇するケースは少ないと考えられるためである。
長年見つからなかったからといって、この欠陥が無害なわけではない。実際に悪用につながる経路が限られているということだ。プロジェクトの説明によれば、報告されたパターンでメモリ安全性を損なうには、RustのDrop機構を意図的に悪意ある形で実装する必要がある。Dropは、値がスコープを抜けるときに後処理を実行する仕組みだ。メンテナーは、最小限に絞った実証コードは単純に見えても、このような組み合わせが偶然生まれる可能性は低いと述べている。
差し迫ったリスクを評価する利用者にとって、この区別は重要だ。課題追跡システムの報告が示しているのは、コンパイラーがコードを受け入れる際の健全性のバグであり、実際に悪用されている証拠でも、既存のRustアプリケーションが広く侵害された証拠でもない。報告には、通常のプログラムが突然安全でなくなったとする主張はない。影響を受けるパターンは、欠けているライフタイム検査を利用するように作り込む必要がある。
Rustの安全性モデルは、借用やライフタイムの規則に違反し得るプログラムをコンパイラーが拒否することに依存している。そのため、遭遇しにくいものであっても、健全性の欠陥は重要な問題だ。プロジェクトは、型システムの基盤を強化し、未知の欠陥が生じる可能性を減らす取り組みの一環として、次世代のトレイトソルバーに関する継続的な作業、リージョン制約の変更、より広範なProject Zeroの取り組みに言及した。
この課題は広く注目を集めた後、スパムを抑えるためにロックされた。課題追跡システムでは、集約型の格納領域にある問題のあるハンドルを拒否する予防的な作業にも言及している。修正とリリースに関する案内が正式に文書化されるまでは、開発者は、オンライン上の概念実証コードの断片を、任意のRustソフトウェアに対する実用的な攻撃の証拠とみなすべきではない。報告から確認できる結論は、もっと限定的だ。高優先度のコンパイラーバグによって、巧妙に作られた一見安全なコードがライフタイムの保証に違反できる、というものである。



