- technohippy
- 760
- 0
- 0
- 0
世間を騒がせているCPUの致命的なバグ、SpectreとMeltdown。Spectreの方は初歩的なプログラミングの知識で理解できるので、4ツイートで簡単に解説してみる。
2018-01-16 18:00:59こういうArrayクラスがあったとする。 class Array { char at(unsigned i) { if (i >= length) // (a) return -1; return data[i]; // (b) } unsigned length; char* data; };
2018-01-16 18:01:09ここで、次のコードを実行する。 char mem[257]; char v = array->at(12345678); // 秘密のデータが保存されているアドレスを指定 if (v & 1) { mem[0]; } else { mem[256]; } // (c)
2018-01-16 18:01:17ここで、次のコードを実行する。 char mem[257]; char v = array->at(12345678); // 秘密のデータが保存されているアドレスを指定 if (v & 1) { mem[0]; } else { mem[256]; } // (c)
2018-01-16 18:01:17CPUの分岐予測をうまく利用すると、(a)のCPU命令が完了する前に、分岐を(b)の方に予測させて、(c)を投機的に実行させることができる。もちろん(a)が完了した時点で投機実行された(c)は捨てられるのだが、すでにCPUはmem[0]またはmem[256]を投機的にキャッシュへロードしてしまっている。
2018-01-16 18:01:27CPUの分岐予測をうまく利用すると、(a)のCPU命令が完了する前に、分岐を(b)の方に予測させて、(c)を投機的に実行させることができる。もちろん(a)が完了した時点で投機実行された(c)は捨てられるのだが、すでにCPUはmem[0]またはmem[256]を投機的にキャッシュへロードしてしまっている。
2018-01-16 18:01:27よって、mem[0]とmem[256]へのアクセス速度を測ってどっちがキャッシュに乗ったかを調べれば、狙ったアドレスのデータが0なのか1なのかがばれる。バッファオーバーフローを防ぐための範囲チェックが役に立たなくなって、好きなメモリアドレスの値を読めてしまう。。。というのがSpectreの原理。
2018-01-16 18:01:40よって、mem[0]とmem[256]へのアクセス速度を測ってどっちがキャッシュに乗ったかを調べれば、狙ったアドレスのデータが0なのか1なのかがばれる。バッファオーバーフローを防ぐための範囲チェックが役に立たなくなって、好きなメモリアドレスの値を読めてしまう。。。というのがSpectreの原理。
2018-01-16 18:01:40CPUの分岐予測に関する根本的なバグなのでソフトウェア側で対処するのは難しいのだが、Chromiumでは、if文を使わない形に範囲チェックを書き換える、(キャッシュへのアクセス速度を調べられないように)タイマーの精度を意図的に落とす、高精度タイマーが作れるAPIを無効化するなどで対処しています。
2018-01-16 18:02:12CPUの分岐予測に関する根本的なバグなのでソフトウェア側で対処するのは難しいのだが、Chromiumでは、if文を使わない形に範囲チェックを書き換える、(キャッシュへのアクセス速度を調べられないように)タイマーの精度を意図的に落とす、高精度タイマーが作れるAPIを無効化するなどで対処しています。
2018-01-16 18:02:12