この記事は Chrome セキュリティ チーム、Adrian Taylor、Andrew Whalley、Dana Jansens、Nasko Oskov による Google Online Security Blog の記事 “An update on Memory Safety in Chrome” を元に翻訳・加筆したものです。詳しくは元記事をご覧ください。
セキュリティは、いたちごっこのようなものです。攻撃者が新しい手法を生み出せば、ブラウザは一歩先を行くために新たな防御策を講じ続けなければなりません。そのため、Chrome は、サンドボックスとサイト分離をベースとした今までにない強固なマルチプロセス アーキテクチャを構築してきました。これらは、ファジングとともに、現在も私たちの主要な防衛線であり続けています。しかし、それも限界に近づきつつあり、この戦略だけに頼って実際に出回っている攻撃に対処することはできなくなっています。
昨年、Google は、重大なセキュリティ バグの 70% 超がメモリの安全性の問題であることを明らかにしました。つまり、C 言語や C++ 言語のポインタのミスによって、メモリが誤解釈されてしまうのです。
メモリの安全性は、世界のソフトウェア エンジニアリング コミュニティが真剣に受け止める必要がある問題です。しかし、これは同時にチャンスでもあります。なぜなら、多くのバグに同じような根本原因があるということは、1 つの対策で相当のバグを撲滅できる可能性があるからです。
Chrome では、このチャンスを活かすため、大まかに次の 3 つの方法を検討しています。
- ポインタが正しいことをコンパイル時にチェックすることで、C++ の安全性を向上
- ポインタが正しいことを実行時にチェックすることで、C++ の安全性を向上
- メモリ安全な言語をコードベースの一部に使うことについて調査
「コンパイル時にチェック」とは、Chrome が皆さんのデバイスにインストールされる前の、ビルドプロセスの段階で安全性を保証することを指します。「実行時」とは、Chrome が皆さんのデバイスで実行されている間にチェックを行うことを指します。
実行時チェックには、パフォーマンスのコストが伴います。ポインタが正しいかどうかをチェックする操作は、メモリや CPU 時間にとっては微少なコストです。しかし、ポインタの数は膨大なので、そのコストは積み重なります。莫大な数のユーザーを持つ Chrome にとって、パフォーマンスは重要です。ユーザーの多くはメモリの少ない低電力モバイル デバイスを使っているため、こういったチェックが増加すれば、ウェブが遅くなってしまいます。
つまり、選択肢 1、コンパイル時に C++ を安全にする方法を選ぶのが理想です。しかし、この言語はそのような設計にはなっていません。この領域で Google が取り組んできたことを詳しく知りたい方は、借用の問題 : C++ の Borrow-Checker の難しさをご覧ください。
そのため、ほとんどは選択肢 2 と 3、つまり C++ の安全性を向上させる(ただし遅くなる)か、別の言語を利用する方法をとらざるをえません。Chrome のセキュリティでは、この両方のアプローチを試しています。
C++ の安全性ソリューションに向けた主な取り組みには、MiraclePtr や ABSL/STL 強化モードなどがあります。どちらも、悪用できるセキュリティ バグの大半を解消することを目指していますが、ある程度のパフォーマンス低下も想定されます。たとえば MiraclePtr は、参照されているメモリを隔離することで解放後の使用に関するバグを防ぎますが、多くのモバイル デバイスではメモリはとても貴重なため、隔離用の領域を割り当てるのは難しくなっています。それでも、MiraclePtr は、ブラウザのプロセスで解放後の使用に関するバグを 50% 以上解消できる可能性を秘めています。今のところ、これは Chrome のセキュリティにとって大きなメリットです。
それと並行して、将来的に Chrome の一部でメモリ安全な言語を使えないかを検討しています。その第一候補は、Mozilla にいる私たちの友人が開発した Rust です。Rust は(ほとんどが)コンパイル時に安全です。つまり、Rust コンパイラは、コードが皆さんのデバイスにインストールされる前にポインタのミスを見つけます。そのため、パフォーマンスが低下することはありません。しかし、C++ と Rust を十分に連携して使えるかどうかという未解決の問題が残されています。また、たとえ明日から Rust で新しい大型コンポーネントを書き始めたとしても、セキュリティ脆弱性の大部分を解消できるのは、おそらく何年も後になるはずです。さらに、既存のコンポーネントの一部を Rust で書けるほど言語の境界を十分にクリーンにできるかという問題もあります。この点は、まだ明らかではありません。Google は、Chromium ソースコード ツリーのユーザーが触れることのない限られた部分で、Rust の実験を始めています。しかし、製品版の Chrome にはまだ含まれておらず、試験運用版のフェーズにとどまっています。
以上の理由から、Google は両方の戦略を並行して追求しています。C++ の安全性向上、Chrome での新しい言語の試行というこの領域の最新情報にぜひご注目ください。
Reviewed by Eiji Kitamura – Developer Relations Team