AMDのZen 2でRDRANDが-1を返すので最近のGNU/Linuxがブートできない問題
AMDのZen 2アーキテクチャの新製品が発売されて沸き立っているが悲しいお知らせがある。最近のGNU/Linuxディストロはブートしない。例えばUbuntu 19.04はブートしない。
理由は、ハードウェア乱数を返す命令、RDRANDに不具合があり、常に-1を返すのだという。このため、rdrandを直接使っているsystemdが失敗し、結果としてブートできなくなる。
AMDによればこの問題はBIOSアップデートで修正可能であるという。しかしこれはとても怪しい陰謀論を考えたくなる。なぜRDRANDが常に-1を返すような不具合が未然に発覚せずに製品リリースまでこぎつけてしまったのか。なぜファームウェアのアップデートで修正可能なのか。まさかバックドアなのではないか。
陰謀論はともかくとして、もう一つの問題は、なぜsystemdはRDRANDを直接使っているのかということだ。Linuxカーネルの提供する/dev/urandomではなぜだめなのか。
その理由は他ならぬsystemdのソースコードにコメントとして記載されている。
Linuxカーネルのブートの直後では、十分なエントロピープールが溜まっておらず、/dev/urandomへのアクセスすらかなり長い時間ストールする可能性がある。特に組み込みやVMといった環境では問題になる。このため、systemdはブート直後かつ、UUIDとハッシュテーブルのシードの生成のみにrdrandの値を直接使っている。
UUIDはユニーク性さえあればよく、セキュアなRNGは必要がない。
ハッシュテーブルは攻撃者が恣意的な値を多数登録することで、オーダーをO(1)ではなくすることができてしまう。そのためにハッシュ計算のシードに乱数値をつかている。
当初はsystemdはRDRANDを直接使うなんて馬鹿げたことをするものだと思っていたが、どうもこの状況を考えるに使いたくなる気持ちもわかる。systemdはRDRANDがない環境もサポートしているため、フォールバック実装はあるのだが、rdrandがあるが壊れている環境ではどうしようもない。
現在、systemdにworkaroundがコミットされているほか、ファームウェアアップデートが予定されているそうだが、問題はマザーボードベンダーがアップデートを提供するには時間がかかるため、しばらくはこの問題に悩まされそうだ。
結論としてはAMDが悪い。