Meltdown and Spectreの教訓
2018年最初の大ニュースといえば,
CPUというハードウェアに由来する脆弱性ゆえ,
幸か不幸か,
まずはTerminalからswift
を起動してREPLに入ります。
% swift Welcome to Apple Swift version 4.0.3 (swiftlang-900.0.74.1 clang-900.0.39.2). Type :help for assistance.
次に適当な文字列を変数に突っ込みます。
1> var str = "Hello, Swift!" str: String = "Hello, Swift!"
その文字列が実際に格納されたアドレスを入手しておきます。
2> var addr = str.withCString{$0} addr: UnsafePointer<Int8> = 0x0000000100202410
文字列を上書きします。
3> str = "Goodbye, Swift!"
ここであらかじめ入手しておいたアドレスを文字列として読んでみましょう。
4> String(cString:addr) $R0: String = "Hello, Swift!"
なんということでしょう。上書き前の文字列がそのまま入っているではありませんか!
5> str $R1: String = "Goodbye, Swift!"
念のためstrを見て見ると,
どうしてこうなった?
実は上書きなんかされていないのです。2度目の代入の際には別の場所=メモリ上に新たな文字列が作成されただけで。
- 注1)
- REPL以外だと同じ結果にならないことに留意。
データは消えず,ただ上書きされるだけ
物理的に考えると不思議なこの挙動も,
場所を無視しているだけなのです。
ガベージコレクションもファイル削除も,
つまり,
なぜそのようになっているかといえば,
仮に上書きで元データを読めなくしようとすると,
なのでたいていの場合,
しかしデータというのは必要と不要の2種類だけではありません。あるプロセスには必要かつ別のプロセスからは不要どころか見えてはいけないデータというのがあるのです。たとえばブラウザのセッション。それを表示しているタブには絶対必要で,