ロウハンマー
From Wikipedia, the free encyclopedia
ロウハンマー (row hammer, rowhammer) は、ダイナミックRAM (DRAM) に起きる意図的でない副作用で、複数のメモリセルから電荷が漏れ出し、メモリセル間で電気的な相互作用が起きるために、元のメモリアドレスで指定されていない近くの行の内容が変化する可能性があるという現象(行間干渉)である。このようなメモリセル間の分離の回避は近年のDRAMのメモリセルの密度の高さに起因しており、同じ行を何回もすばやく有効にするよう特別に細工されたメモリアクセスパターンによって引き起こされることがある [1][2][3]。
ロウハンマーはコンピュータ・セキュリティで権限昇格に悪用(→エクスプロイト)されており [2][4][5][6]、 攻撃者と被害者が高速ネットワークで接続されている場合にはネットワークベースの攻撃も理論的には可能である [7][8]。
ロウハンマーを防ぐいくつかの異なるハードウェアベースの技法が存在する。これにはDRAM メモリモジュールのタイプとプロセッサによるサポートを必要とするものが含まれる。 [9][10] ロウハンマーはDDRやDDR2 SDRAMモジュールではほとんど、または全く影響しないが、多くのDDR3やDDR4 SDRAMモジュールには影響を及ぼす。

DRAMの内部では、格納されたデータの各ビットは1個のキャパシタ(コンデンサ)と1個のトランジスタで電気的に実装された独立なメモリセルを占有する。キャパシタの充電状態(充電されているかいないか)によりDRAMメモリセルが2進値"1"を持つか"0"を持つかが決まる。集積回路には膨大な数のDRAMメモリセルが、データの読み書きとリフレッシュのためにセルを編成する付加的なロジック回路と共に詰め込まれている [11][12]。
さらに、メモリセル(イラストでは青の四角)は行列に編成され、行アドレスと列アドレスによって選択される。メモリアドレスは行アドレスデコーダと列アドレスデコーダ(イラストではそれぞれ垂直と水平な緑の長方形)によって行アドレスと列アドレスに分割される。読み出し動作では行の行アドレスが選択された後(この選択は行アクティベーションとも呼ばれている)、この行のすべてのメモリセルからのビットは行バッファ(イラストでは赤い四角)を構成するセンスアンプに移されて、ここから列アドレスによって1ビットが選び出される。その際に読み出しの動作はメモリセルの内容を破壊してしまう性質を持つ。そこでDRAM の設計ではメモリセルの電荷を行バッファに移して読み出した値をその後に再びメモリセルに書き戻す動作をする。書き込み動作でも同様にしてアドレスを解釈するが、1ビットの変更であっても行全体を再書き込みする構造になっている [1]:2–3[11][12][13]。
自然放電するキャパシタを用いてデータを保持するため、DRAMのメモリセルは時間とともにデータを失っていくので、周期的にすべてのメモリセルを書き込み直す必要がある。これはメモリリフレッシュ動作(リフレッシュ)と呼ばれている。 DRAMの構造上、宇宙線その他の影響を受けて保持したデータがランダムに変化するソフトエラーと言う誤動作が起きやすい。 誤動作対策にはいくつかの技法があり、DRAMの信頼性を向上させている。よく使われるものにはECCメモリやその改良版(ロックステップメモリなど)がある [14]。
概要

DRAM集積回路の密度の向上は、電荷を少ししか蓄えられない物理的に小さなメモリセルをもたらし、結果として動作のノイズマージンは減少し、メモリセル相互間の電磁相互作用の度合いが増大し、データ損失の可能性が上昇した。 結果として外乱エラー (disturbance error) が観測された。それはメモリセルが相互の動作を妨害することにより、影響されたメモリセルに格納されたビットの値がランダムに変化することで明らかとなった。 外乱エラーについての指摘は1970年代初期にさかのぼる。初の商業的DRAM集積回路 (IC)・インテル1103以来、メモリセル間の絶縁性向上、製品検査の実施など、DRAMメーカーは種々の技術で外乱エラーを軽減してきた。 しかし研究者は2014年に、2012年・2013年に製造された商用のDDR3 SDRAMチップが外乱エラーの影響を受けることを確かめた。その中で、観測されたビット反転を導く副作用をロウハンマー (row hammer) と命名している [1][3][15]。
DDR3メモリでロウハンマーが起こる機会は、高いメモリセル密度に起因するメモリセル間相互作用の結果がもたらしたとはじめは考えられていたが、高速な DRAM 行選択動作が主な原因であると究明された[16]。 高速な行選択動作は対応する行選択線に電圧変動を引き起こし、近くの(ほとんどの場合、隣の)行(被害行 (victim row) と呼ばれる)にあるキャパシタに自然状態よりも高い放電率を誘発するのが観測された。影響されたメモリセルが電荷を一定以上失ってもリフレッシュされないとき、外乱エラーが起こる。 テストでは(キャッシュのフラッシュとともに)約139,000回のメモリ行アクセスを続けると外乱エラーが観測される可能性があり、影響を受けるメモリセルが1,700個のうち1個にのぼる恐れがあることが示されている。 また、これらのテストは外乱エラーの頻度は環境温度の上昇には実質的に影響されず、DRAMの記憶内容に依存することを示している。特定のビットパターンによって外乱エラーの頻度が大幅に高まるのである[1][2][15][17]。
両側干渉 (double-sided hammering) と呼ばれるバリエーションは、被害行を取り巻く2つの行を動作させるものである。この節のイラストでは、紫色の被害行にビット反転を誘発するねらいで両方の黄色の行を動作させる。 テストでは、この方法により被害行の片側の隣接行だけを動作させる場合に比べて外乱エラーの頻度が大きく上昇する可能性があることを示している [4][18]:19–20[19]。
緩和策
ロウハンマーの検出・予防・修正・緩和には様々な手法が存在し、効果もそれぞれである。 テストによると、単純なECCによる対策は、1ビットのエラー修正と2ビットのエラー検出能力を持つが、メモリの1ワードに3つ以上のビット反転が起きることがあり、外乱エラーのすべてを修正あるいは検出できないことを示している。 [1]:8 [15]:32 より効果的な対策は、通常の 64ms間隔よりも頻繁にリフレッシュを行うことである。 [注釈 1] しかしこの方法では消費電力と処理のオーバーヘッドが増大する。いくつかのメーカーはファームウェアの更新によってこの種の緩和策を提供している [20]。 もう少し手の込んだ方法として、カウンタに基づいて頻繁にアクセスされる行を特定し、前もって隣接する行をリフレッシュするというものがある。別の方法として、アクセスされた行の隣接行をアクセス頻度に関係なくときどきランダムにリフレッシュするというものもある。 研究は、これら2つの予防策の性能への影響は無視できる程度だと説明している [1]:10–11[21]。
Ivy Bridgeマイクロアーキテクチャのリリース以後、インテル Xeonプロセッサは疑似目標行リフレッシュ (pseudo target row refresh, pTRR) と呼ばれるものをサポートしている。pTRR対応DDR3 DIMMはロウハンマー効果を緩和するように被害行となりそうな行を自動的にリフレッシュし、メモリ性能や消費電力にほとんど影響を与えない。 pTRR非対応のDIMMが使われた場合、デフォルトでこれらのXeonプロセッサはDRAMのリフレッシュ頻度を通常の2倍にする。結果として、メモリアクセスのレイテンシが少し増え、メモリの帯域幅が最大2〜4%減少する [9]。
JEDECの発行したLPDDR4モバイルメモリ規格には [22]、 オプション回路として目標行リフレッシュ (target row refresh, TRR) と呼ばれるもののサポートが含まれている。これは性能や消費電力にほとんど影響を与えずにロウハンマー効果を予防する [10][23][24]。 さらに、JEDECの発行したDDR4メモリ規格には含まれていないにもかかわらず、一部のメーカーはDDR4製品にTRRを実装している [25][26] [27]。 内部的にTRRは行選択動作の数を数え、あらかじめ決められたチップ固有の最大動作数 (maximum activate count, MAC)・最大動作時間 (maximum activate window, tMAW) の値と比較することで、被害行となりそうな行を特定し、これらの行をリフレッシュしてビット反転を予防する。 MAC 値は、DRAM の特定の行が、その隣接行が被害行と認識されるまでの時間 tMAW と同じかそれ以下の一定時間間隔のうちに遭遇しうる行選択動作の合計数の最大値である。TRR はまた、タイミング・ウインドウ tMAW のうちに2つの隣接行の行選択動作の合計が MAC の制限に達したとき、被害行としてフラグを立てる [22][28]。
ロウハンマーの悪用は、高速なDRAM行選択動作を膨大な数で行う必要があるため多数のキャッシュされないメモリアクセスを行いキャッシュミスを引き起こすので、 ハードウェアパフォーマンスカウンタを使ってキャッシュミス発生率をモニターすることで異常なピークとして検出できる [4][29]。
2013年12月3日にリリースされたメモリ診断ソフトMemtest86 Version 5.0 には、コンピューターのRAMが外乱エラーに影響されるかどうかを検査するロウハンマーテストが追加された。これはUEFIブートのコンピュータでしか機能しない。UEFIのないコンピュータではロウハンマーテストのない古いバージョンが起動する [30]。
影響
プロセスに割り当てられていないメモリへのアクセスを防止するメモリ保護は、最新のオペレーティングシステムの背後にある概念の1つである。 プログラム(や一般にコンピュータシステム)は特定のタスクを実行するために要求される限られた権限を持つ各部分であるプロセスに分割されるが、リングプロテクションなど他のセキュリティ機構とメモリ保護を組み合わせることで、プロセス間の特権分離が達成できる。 特権分離を使うと、コンピュータセキュリティに対する攻撃の効果をシステムの特定の部分に制限することにより、潜在的な被害の範囲を小さくすることもできる [31][32]。
外乱エラー(→#概要)は、基盤にあるメモリのハードウェアを直接操作するユニークな攻撃経路を実質的に作ることで、プロセスがメインメモリの任意の部分を変更できるようになり、メモリ保護のさまざまな層をとても低いハードウェアレベルで「短絡する」ことにより効果的に打ち破ってしまう [2][4][18][33]。 これと比較して、バッファオーバーフローのような「従来の」攻撃経路は、プログラムのさまざまなミスを悪用して保護機構をソフトウェアのレベルで迂回し、他の方法ではアクセスできないメインメモリの内容を変更することを狙っている [34]。
悪用
code1a:
mov (X), %eax // read from address X
mov (Y), %ebx // read from address Y
clflush (X) // flush cache for address X
clflush (Y) // flush cache for address Y
mfence
jmp code1a
|
| ロウハンマーを誘発する x86-64 アセンブリコードの一部。メモリアドレス X と Y は同じメモリバンク上のDRAMの異なる行に置く必要がある。[1]:3[4][18]:13–15 |
ロウハンマーに関する最初の研究は2014年6月に出版され、外乱エラーの性質と潜在的な攻撃方法を示していたが、実際に動作する攻撃例は 載っていなかった [1]。 続く2014年10月の研究論文では、ロウハンマー効果に起因するセキュリティ問題の存在に触れていなかった [16]。
2015年3月9日、GoogleのProject Zeroはロウハンマー効果に基づく実際に動作する特権昇格の2つの悪用例を明らかにし、x86-64 アーキテクチャにおける脆弱性を実証した。 ひとつはサンドボックスでx86-64 機械語命令の制限されたサブセットを実行する Google Native Client (NaCl) 機構を標的にしたもので、ロウハンマー効果を悪用してサンドボックスから脱出し、システムコールを直接発行する可能性を増大させている。 [18] この NaCl の脆弱性(CVE-2015-0565)は、効果的なロウハンマー攻撃を組み立てるために必要だと以前は考えられていた clflush機械語命令(キャッシュラインをフラッシュする) [35]) を許さないように NaCl を修正することで緩和された [2][4][33]。
2つめはx86-64アーキテクチャ上のLinuxの特権を持たないプロセスとして実行され、コンピュータに実装されているすべての物理メモリに制限なくアクセスするためにロウハンマー効果を悪用した。外乱エラーとヒープスプレーを組み合わせることで、この悪用例では 仮想メモリシステムで仮想アドレスと物理アドレスのマッピングに使われるページテーブルエントリー (page table entry, PTE) [18]:35 の変更を可能にしており、結果として制限のないメモリアクセスが可能になっている [18]:34,36–57。 その性質と、clflush を特権命令にできない x86-64 アーキテクチャのため、ロウハンマーを回避する組み込みハードウェア機構を使わないコンピュータではこの脆弱性の緩和が困難である。 脆弱性のテストにおいて、Project Zero はテストした29のノートパソコンの約半数で外乱エラーが発生することを見出した。いくつかの脆弱なノートパソコンではロウハンマーを導入するコードを実行して5分以内に発生した。テストに用いられたのは、2010年から2014年に製造され、非 ECC の DDR3 メモリを使用したノートパソコンだった [2][4][33]。
2015年7月、セキュリティ研究者のグループはアーキテクチャと命令セットに依存しないロウハンマーの悪用方法についての論文を出した。 この方法ではキャッシュのフラッシュを実行するclflush命令を使う代わりに、注意深く選ばれたメモリアクセスパターンを使って非常に高い率でキャッシュの破棄を引き起こすことによりキャッシュされていないメモリアクセスを実現する。 キャッシュ置換ポリシーはプロセッサによって異なるが、このアプローチは適応型キャッシュ破棄戦略アルゴリズムを採用することによってアーキテクチャの違いを克服している [18]:64–68。 このアプローチの概念実証は、機械語による実装と Firefox 39 上で実行される純粋な JavaScript による実装の両方によって与えられた。 Rowhammer.js と呼ばれる JavaScript による実装は [36]、 大きな型付き配列を使い、内部で大きなページを割り当てられることに依存している。 結果として、非常に低いレベルの脆弱性による非常に高いレベルの悪用を実証している [37][38][39][40]。
2016年10月、VUSec Systemsの研究者とVU AmsterdamのネットワークセキュリティグルーブはDRAMMERというAndroidアプリを発表した。これはロウハンマーと他の方法を使って、いくつかの有名なモデルのスマートフォンで確実に特権を獲得する [41]。 この脆弱性はCVE-2016-6728として知られており [42]、 影響を軽減するパッチが1か月以内にGoogleからリリースされたが、攻撃の可能な実装の一般的な性質上、効果的なソフトウェアパッチを確実に実装することは難しい。 事実、2018年6月までに研究機関と産業界から出されたほとんどの提案は実施が難しいか、すべての攻撃を止めるには不十分なものだった [43]。 これらの攻撃を軽減するために、VUSec Systemsの研究者はDMAバッファを防護行で隔離することでDMAベースの攻撃を予防する軽量な防御策を提案した [43][44]。
ソフトウェアのすべての状態がロウハンマーに対して脆弱であるわけではない。ゆえに攻撃者はロウハンマーによるエラーを利用するために目標の正しい状態を見つける必要がある。実際的には、目標の状態を特定することが主な課題の1つとなる。それは通常、ドメインの専門家が行う。The mainstream fault tolerance communityはロウハンマー攻撃に対して、目標の状態とその悪用可能性を特定し、確認し、評価できる体系的な方法で対応した[45]。この仕事は欠陥の導入を基礎とする十分に確立された経験的な方法論と一般的な攻撃目標の状態に基づいており、それまで知られていなかった実際的な目標の状態をいくつか発見した。