メディア

Google「メモリ安全ではないコードを放置」の理由 なぜスマホが安全になるのか

GoogleはAndroidにおける脆弱性を大幅に引き下げることに成功した。これはプログラミング言語についての「ある決断」の結果だという。Googleは何を決断したのだろうか。

» 2024年10月28日 07時00分 公開
[Matt KapkoCybersecurity Dive]
Cybersecurity Dive

 Googleは2024年9月25日「ここ6年間でAndroidにおけるある脆弱(ぜいじゃく)性の割合を76%から24%に引き下げた。これは、新機能の開発においてプログラミング言語を変更した結果だ」と発表した(注1)。

Googleが実現する安全なスマホ 実は言語が問題だった

 なぜプログラミング言語が脆弱性を減らす役に立つのだろうか。

 先ほどのGoogleの発言を正確に表現すると、「新機能の開発においてメモリ安全性の高いプログラミング言語への移行を段階的に進めた結果、メモリ安全性に関する脆弱性の割合を引き下げた」となる。

メモリ安全性の高いプログラミング言語とは

 プログラミング言語によっては、PCやスマホのメモリを扱う方法に問題がある。すでに使わなくなったメモリ領域を廃棄したり、新しく使うメモリ領域をゼロクリアしたりする機能が備わっていないと、バグはもちろん、攻撃者に利用される脆弱性を生み出してしまうからだ。

 それではメモリ安全性の高いプログラミング言語にはどのような特徴があるのだろうか。

(1)メモリ管理の自動化と保護機構

 メモリ安全なプログラミング言語は自動化されたメモリ管理機構を備えている。これによって、開発者がメモリを操作するコードで意図せずにミスを起こすことを防げる。「Java」や「C#」「Go」「Ruby」「Swift」などの言語は、不要になったメモリ領域を廃棄するガベージコレクションやその他のメモリ保護機構を含んでいる。

(2)バッファオーバーフローやメモリリークの防止

 メモリ安全なプログラミング言語はサイバー攻撃で利用されやすいバッファオーバーフローやユーズアフターフリー、レースコンディションなどのメモリ関連のバグを防止するためのメカニズムを備える。例えばRustではコンパイル時にこれらのバグを検出して防止する。

(3)型の安全性

 メモリ安全なプログラミング言語は厳格な型システムを持ち、ランタイムでの型エラーを防ぐ。GoogleがAndroidの開発で採用したRustでは型システムがコンパイル時に不正なデータアクセスを検出し、バグを排除する。

(4)並列処理の安全性

 並列処理プログラミングは問題を起こしやすい。あるメモリ領域を複数のプロセスがランダムにアクセスするようなコードを書くとバグを生み出しやすい。メモリ安全なプログラミング言語は、並行処理においても安全性を確保できる。Rustでは厳密なルールに基づく変数の「借用システム」が存在し、データ競合やデッドロックを未然に防ぐ。

(5)所有権と借用の概念を備える

 (4)で触れた「借用システム」とは何だろうか。Rustは特にメモリについて「所有権」と「借用」の概念を導入しており、メモリの多重解放や不正なデータアクセスを防止できる。Rustの所有権システムでは、各値には常に1つの所有者が存在し、コンパイル時に不正なデータアクセスを防止する仕組みが組み込まれている。

 以上のような特徴により、メモリ安全性の高いプログラミング言語は、サイバーセキュリティの向上とソフトウェアの信頼性を確保するために重要な役割を果たす。(文責:キーマンズネット編集部)


Googleは古いコードを放置

 Androidの開発者は既存のコードには焦点を当てなかった。その代わり、2019年から新しいコードを書く際にメモリ安全性の高い言語を優先的に使用し、メモリ安全性に関する脆弱性を減少させた。Googleによると、この6年間で、Androidにおけるメモリ安全性の高いコードの総行数はこれまで以上のペースで増加した。その結果、メモリ安全性に関する新しい脆弱性の総量は減少したという。

 Androidのコードの大部分は依然としてメモリ安全ではない。だが、Googleは「全ての新しい開発にメモリ安全性の高い言語を使うことで、一見すると直感に反する結果を達成した」と述べた。

 Googleは脆弱性の修正以外で既存のコードにほとんど手を加えないという決定を下した。これが良い結果を生んだということは、ソフトウェア開発者を長年苦しめているセキュリティの問題、つまりメモリ安全性にどうすれば対応できるかという指針になるだろう。

古いコードを放置しても脆弱性が減る理由

 Googleは脆弱性の修正以外で既存のコードにほとんど手を加えなかった。なぜこの方法がうまくいくのだろうか。

 Googleによれば数学によって説明できるという。脆弱性は指数関数的に減衰する性質があり、脆弱性には半減期がある。つまり、脆弱性の寿命の分布は、平均的な脆弱性の寿命λが与えられた場合、指数分布に従うという。

 これは2022年に『Usenix Security』誌に発表された脆弱性の寿命に関する大規模な研究の結論だ。研究者によれば、脆弱性の大部分が新しいコードや最近修正されたコードに存在する。

 研究の結論は2点にまとめられる。

問題は圧倒的に新しいコードにあり、新しいコードの開発方法を根本的に変える必要がある

コードは時間とともに成熟し、指数関数的に安全になる

 平均的な脆弱性の寿命に基づくと、5年前のコードは新しいコードよりも脆弱性の密度が3.4倍(研究による寿命を使用)から7.4倍(AndroidとChromiumで観測された寿命を使用)低い。Googleの方針がうまくいったのは古いコードよりも新しいコードを優先し、いわば「予防は最善の治療」を実現したためだ。


メモリ安全性はGoogleだけにとどまらない

 サイバーセキュリティ・インフラストラクチャセキュリティ庁(CISA)をはじめとする連邦サイバー当局は、メモリ安全性の低い言語の使用が、脆弱性に関連する最悪の危機の一因だと一貫して指摘している。

 2024年の初め、ホワイトハウス(米連邦政府)の国家サイバーディレクター室は、テクノロジー業界に対し、製品にメモリ安全性の高い言語を広く採用するよう呼びかけた(注2)。

 政府関係者は、ソフトウェアベンダーがメモリ安全性の高い言語に移行することで、脆弱性の発生件数を大幅に減らすことができると主張している。

 以前、CISAは「メモリ安全性の低い言語に関連する脆弱性の3分の2は、メモリ安全性の問題が原因だ」と述べた(注3)。

 連邦捜査局(FBI)とCISAは2024年6月の報告書で、重要なオープンソースプロジェクトの半数以上がメモリ安全性の低い言語で書かれていると指摘した(注4)。

 Googleは次のように述べた。

 「問題の大部分は新しいコードにあり、コードの開発方法を根本的に変える必要がある。時間がたつにつれてコードは成熟し、安全性も向上する。そのためコードが古くなると再度の書き直しなどによる投資効果は次第に小さくなる」

© Industry Dive. All rights reserved.

会員登録(無料)

製品カタログや技術資料、導入事例など、IT導入の課題解決に役立つ資料を簡単に入手できます。