書いて覚えるSwift入門

第35回 Meltdown and Spectre

この記事を読むのに必要な時間:およそ 3 分

Meltdown and Spectreの教訓

2018年最初の大ニュースといえば,本誌Software Designの読者には毎号おなじみの結城浩さん,ではなくてMeltdown and Spectre。実際に悪用するのは困難とはいえ,CPU,それも単一ではなく複数のアーキテクチャにまたがる脆弱性というのは実に稀です。

CPUというハードウェアに由来する脆弱性ゆえ,一見Swiftには関係なさそうに見えますが,しかしその根底にある原理というのはSwiftどころが現代のソフトウェアであればいたるところに存在します。それだけにMeltdownとSpectreの教訓は,プログラムする者であればすべての人が知っておくべきことだと筆者は考えます。

幸か不幸か,高級言語でありながらメモリへの直接アクセスの手段が用意されているSwiftはそれを学ぶのに向いた言語でもあります。実際に見てみましょう。

まずは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を見て見ると,確かに上書きされています。

どうしてこうなった?注1

実は上書きなんかされていないのです。2度目の代入の際には別の場所=メモリ上に新たな文字列が作成されただけで。

注1)
REPL以外だと同じ結果にならないことに留意。

データは消えず,ただ上書きされるだけ

物理的に考えると不思議なこの挙動も,論理的に考えると実に自然です。⁠データを消す」と我々はよく言いますが,データというのは実は消去不可能なのです。メモリのどこを読んでもそこには必ず0か1が入っているのですから。我々ができるのは0を1に,1を0にするだけ。では我々が「消す」と呼んでいる行為はいったいなんなのか?

場所を無視しているだけなのです。

ガベージコレクションもファイル削除も,実際には何も「消し」てないんです。⁠消す」べき領域を「上書きOK」としているだけで。だから数GB単位の動画ファイルも数十数百GB単位の仮装マシンインスタンスも一瞬で「消せる」んです。いや,消したように見えるんです。⁠上書きOKフラグ」を立てるだけなのですから。

つまり,それがどこに書かれていたかすら知ることができれば,⁠消した」はずのデータを読むことができる。まだ上書きされていなければ。

なぜそのようになっているかといえば,たいていの場合「わざわざ読めなくするまでもない」から。どうせいつか上書きされるのであれば,わざわざその場で上書きするまでもない,と。

仮に上書きで元データを読めなくしようとすると,必要な時間はざっくり元データの大きさに比例することになります。4GBの動画ファイルを消すには,4KBのテキストファイルの100万倍。8TB級のHDDいっぱいに詰まった全データを消そうとしたら1日でも終わらない!

なのでたいていの場合,不要なデータは「その場で無視していずれ上書きされるのを待つ」のが流儀だったわけです。

しかしデータというのは必要と不要の2種類だけではありません。あるプロセスには必要かつ別のプロセスからは不要どころか見えてはいけないデータというのがあるのです。たとえばブラウザのセッション。それを表示しているタブには絶対必要で,しかし別のタブやプロセスからは読めてはならない。もし読めてしまったら開いただけでユーザの秘密を盗むWebページが簡単にできてしまいます。そういう情報はどうやって扱えばいいでしょうか?

著者プロフィール

小飼弾(こがいだん)

1969年生まれ,東京都出身。元ライブドア取締役の肩書きよりも,最近はPokemon GOのガチトレーナーのほうが有名になりつつある……かもしれない永遠のエンジニアオヤジ。

活躍の場はIT業界だけでなく,サブカルからアカデミックまで多方面にわたり,ネットからの情報発信は気の向くまま毎日毎秒! https://twitter.com/dankogai,ニコニコチャンネルは,http://ch.nicovideo.jp/dankogai,blogはhttp://blog.livedoor.jp/dankogai/

当社刊行書籍は『小飼弾のアルファギークに逢ってきた』『小飼弾のコードなエッセイ』など。他にも著書多数。