Rustの導入で「Android」のセキュリティバグが低減か――Googleが報告深刻な脆弱性も減少

Googleは公式ブログで、モバイルOS「Android」の開発にメモリ安全なプログラミング言語「Rust」を導入する取り組みを進めてきた2019〜2022年の間に、同OSにおけるメモリ安全性の脆弱性が大幅に減少し、それに伴って深刻な脆弱性も減少していることを報告した。

» 2022年12月07日 08時00分 公開
[@IT]

この記事は会員限定です。会員登録(無料)すると全てご覧いただけます。

 Googleは2022年12月1日(米国時間)に公式ブログで、モバイルOS「Android」の開発にメモリ安全なプログラミング言語「Rust」の導入を進めたことで、同OSにおけるメモリ安全性の脆弱(ぜいじゃく)性が大幅に減少し、それに伴って深刻な脆弱性も減少していることを報告した。Rust導入によるセキュリティ上の影響や、Rustの使用に関する今後の展望も解説した。

 メモリ安全性の脆弱性は10年以上にわたって、製品全体、そして業界全体において、脆弱性全体の65%以上を占めてきた。10年以上にわたって、メモリ安全でない言語(C/C++など)の改善に多大な投資をしてきたにもかかわらず、メモリ安全性の脆弱性が毎年数多く見つかってきた。

 だが、Android Security Bulletinの報告を見ると、Androidのメモリ安全性に関する脆弱性の年間報告件数は、2019年には223件だったが、2022年には85件と大幅に減少している。Androidの全脆弱性に占めるメモリ安全性の脆弱性の割合も、2019年の76%から、2022年には35%に低下している。2022年はメモリ安全性の脆弱性が、Androidにおける全脆弱性の半数以下となった初めての年だ。

Androidにおけるメモリ安全性の脆弱性の年間報告件数(提供:Google) Androidにおけるメモリ安全性の脆弱性の年間報告件数(提供:Google)

 こうした変化は、Android開発に使用するプログラミング言語が、メモリ安全でない言語からメモリ安全な言語へと徐々にシフトしてきたことと軌を一にしている。2022年8月に正式リリースされた「Android 13」は、新たに追加されたコードの5割以上が、メモリ安全な言語(Rust、Java、Kotlin)で作成された初のAndroidバージョンだ。

Android 13で追加された新しいコードの作成に使われた言語(提供:Google) Android 13で追加された新しいコードの作成に使われた言語(提供:Google)

 相関関係は必ずしも因果関係を意味しないが、メモリ安全性の問題に起因する脆弱性の割合が、新しいコードに使用される開発言語とかなり密接に相関しているように見えるのは興味深いと、Googleは報告している。

 ただし、Googleは、Android開発でメモリ安全な言語にシフトしてきただけではない。C/C++の安全性を高めるツールへの投資、既存のコードベースに対するファジングのカバー範囲も拡大してきた。

 だが、こうした重要なツールや取り組みだけでは、メモリ安全性の脆弱性の大幅な減少を説明することはできない。これらの技術を導入している他のプロジェクトでは、脆弱性の構成比に大きな変化が見られないためだ。Googleは、Androidがメモリ安全でない言語からメモリ安全な言語への移行を進めていることが、メモリ安全性の脆弱性が減少してきた大きな要因だと考察している。

ネイティブコード向けのRust

 GoogleはAndroid 12で、C/C++に代わるメモリ安全な言語として、AndroidプラットフォームにおけるRustのサポートを発表して以来、Android Open Source Project(AOSP)でRustの経験と利用を拡大してきた。既存のC/C++コードをRustベースに転換することではなく、新しいコードの開発を、時間をかけてメモリ安全な言語に移行させることを目指している。

 Android 13では、新しいネイティブコード(C/C++/Rust)の内、約21%がRustで記述されている。AOSPには、Keystore2、新しいUltra-Wideband(UWB)スタック、DNS-over-HTTP3、Androidの仮想化フレームワーク(AVF)などの新機能やコンポーネントおよびそのオープンソース依存関係など、合計約150万行のRustコードが含まれている。これらは低レベルのコンポーネントであり、従来なら、C++で実装されていたとしている。

セキュリティへの影響

 2022年12月時点で、AndroidのRustコードにおいてメモリ安全性の脆弱性は全く見つかっていないという。2つのAndroidバージョンにおける新しいRustコードの量と、Rustが使用されているセキュリティ上重要なコンポーネントを考えると、重要な結果だとしている。Androidの最も一般的な脆弱性の原因を防ぐという、Rustの所期の目的が達成されていることを示しているからだ。過去の脆弱性密度は、AndroidのC/C++コンポーネントの多く(メディア、Bluetooth、NFCなど)で1/kLOC(コード1000行につき1つの脆弱性)以上だった。

「unsafe Rust」についてはどうか

 OSの開発では、コンパイラが推論できないリソースにアクセスする必要がある。これは、メモリ安全な言語では、システムプログラミングのためにエスケープハッチが必要なことを意味する。Javaの場合、「JNI」(Java Native Interface)を使用して低レベルのリソースにアクセスする。JNIを使用する場合、安全でない振る舞いを導入しないように注意する必要があるが、AndroidのJavaコードでは、メモリ安全性の脆弱性はごくまれだ。

 Rustにも「unsafe{}」というエスケープハッチがあり、システムリソースや非Rustコードとのやりとりを可能にする。JavaとJNIの組み合わせと同様に、このエスケープハッチを使用すると、Rustコードの精査が必要になる。だが、Javaと同様にRustコードも、純粋なC/C++実装よりも格段に安全であることが実証されてきている。

 一般的に、AndroidのRustにおけるunsafeの使用は、意図した通りに機能しているようだ。使われることはほとんどないが、使われる場合は、動作をカプセル化することで、安全性に関する推論やレビューを容易にしている。

メモリ安全でない言語は、安全対策でパフォーマンスが低下

 モバイルデバイスのリソースは限られており、Googleは常にそのリソースを有効活用し、ユーザーにより良い体験を提供しようと努めている。メモリ安全でないコードを使用すると、サンドボックス、サニタイザ、ランタイムのリスク軽減、ハードウェア保護を追加することなどが必要になり、セキュリティとパフォーマンスの間でトレードオフが発生することはよくある。残念ながら、これらの追加は、コードサイズ、メモリ、パフォーマンスに悪影響を及ぼす。AndroidでRustを使用すれば、より少ない妥協でセキュリティとシステムの健全性の両方を最適化できる。

メモリ安全性以外の脆弱性

 メモリ安全性の脆弱性が大幅に減少しているにもかかわらず、Android Security Bulletinで報告される脆弱性の数は過去4年間、毎月20件程度でほぼ安定的に推移している。それはなぜか。

深刻度の低下

 2022年にメモリ安全性の脆弱性がAndroidの全脆弱性に占める割合は35%となっている。ところが、メモリ安全性の脆弱性は、深刻度が重大な脆弱性(Androidの深刻度評価システムで最も危険なレベルに当たる)の86%、リモートで悪用可能な脆弱性の89%を占めている。さらに、Androidデバイスで実際に悪用されていることが確認された脆弱性の78%を占めている。

深刻度が高い脆弱性の大半はメモリ安全性の脆弱性(提供:Google) 深刻度が高い脆弱性の大半はメモリ安全性の脆弱性(提供:Google)

 多くの脆弱性は、その影響範囲が明確に定義されている。例えば、権限バイパスの脆弱性は一般的に、特定の情報またはリソースへのアクセスを許可する。一般的に、コードがデバイス上で実行されている場合にのみ到達可能だ。

 これに対し、メモリ安全性の脆弱性は、汎用(はんよう)性が高い傾向にある。あるプロセスでコードが実行されると、特定のリソースだけでなく、そのプロセスがアクセスできる全ての対象へのアクセスを許可し、その中には、他のプロセスに対する攻撃対象領域も含まれる。メモリ安全性の脆弱性は、複数の脆弱性を連鎖させてしまうほど柔軟であることが多い。

 だが、メモリ安全性の脆弱性の減少に伴い、脆弱性の深刻度も全体的に低下している。

深刻度が重大な脆弱性とリモートで悪用可能な脆弱性が減少(提供:Google) 深刻度が重大な脆弱性とリモートで悪用可能な脆弱性が減少(提供:Google)

 ただし、最も深刻な脆弱性が減少する一方で、深刻度の低い脆弱性の報告件数は増加している。メモリ安全性の脆弱性を発見して悪用することが難しくなったため、セキュリティ研究者は、他の種類の脆弱性に焦点を移していると、Googleは説明している。

 Googleは、「発見される脆弱性の総数は、脆弱性の発見に費やされる研究者の総時間の影響を受けているのではないか」との見方を示し、セキュリティ研究者のコミュニティーが発見する、強力で汎用性の高い脆弱性の数が減っているのであれば、同じことが攻撃者にも当てはまることを願うとしている。

攻撃対象領域

 Androidの既存コードのほとんどはC/C++だが、AndroidのAPIの大部分はJavaで実装されている。つまり、アプリが到達可能なOSの攻撃対象領域は、Androidコードに占める割合に反して、Javaが多いということだ。これは、「アプリが到達可能な攻撃対象領域の大部分が、メモリ破壊バグの影響を受けない」という、セキュリティ上重要な特性につながっている。

今後の展望

 C/C++からの移行は困難だが、AOSPは前進している。AndroidプラットフォームにおけるRustの利用は引き続き拡大されていく。Android 全体でセキュリティ、安定性、品質を向上させるという目標を達成するには、コードベース内のネイティブコードが必要な場所で、Rustを使用できるようにする必要がある。

 AOSPは、ユーザー空間のHAL(Hardware Abstraction Layer)をRustで実装している。トラステッドアプリケーションにおけるRustのサポートも追加している。AVFのVM(仮想マシン)ファームウェアもRustに移行している。

 Googleは、AndroidがC/C++からJava/Kotlin/Rustに移行するにつれて、メモリ安全性の脆弱性の数はますます減少し続けると予想した上で、Androidでメモリ破壊バグがほとんど発生しなくなることを願っている。

Copyright © ITmedia, Inc. All Rights Reserved.

スポンサーからのお知らせPR

注目のテーマ

Microsoft & Windows最前線2025
AI for エンジニアリング
ローコード/ノーコード セントラル by @IT - ITエンジニアがビジネスの中心で活躍する組織へ
Cloud Native Central by @IT - スケーラブルな能力を組織に
システム開発ノウハウ 【発注ナビ】PR
あなたにおすすめの記事PR

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。