Pentium F0 バグ


Intel社 の Pentium, MMX Pentium に存在する "ロック付き CMPXCHG8B (コンペア アンド エクスチェンジ8バイト) 命令の無効オペランドエラッタ"、通称 "F0バグ" (F00Fバグ) が発生すると、プロセッサが停止しコンピュータシステムがダウンします。 このエラッタについて調べました。


"F0バグ" の概要

Pentium "ロック付き CMPXCHG8B 命令の無効オペランドエラッタ" は、一般的な PC が搭載している Intel社 の "Pentium", "MMX Pentium" プロセッサ、およびその ODP が、ある特定の命令シーケンスを実行したときに発生します。

この無効命令エラッタが発生すると、プロセッサがロックされたままとなり、PC のシステム全体がフリーズします。 フリーズ状態になると、キーボードやマウスからの入力は一切受け付けません。 復旧にはシステム (PC 本体) の再起動 (リセット) が必要です。 その際、ディスクに保存していない作業中のデータや仮想記憶上のデータなどは失われます。

一般に、UNIX などのサーバー向け OS はユーザーの実行権限を制限できます。 しかし、ユーザー権限でも、この無効命令エラッタを引き起こすコードを含むプログラムを実行すると、システムがフリーズします。

ソフトウエアを制作する一般的なコンパイラは、このエラッタを引き起こすコードを生成しません。 したがって、この無効命令エラッタは、人為的に制作、内包されない限り、一般的なソフトウエアに含まれることはありません。

しかし、インターネットには Pentium, MMX Pentium プロセッサを搭載した PC も数多く接続されています。 悪意を持った人が Web のセキュリティー上の欠陥を利用して無効命令エラッタを発生させ、何も知らない一般人 (それはあなたかもしれません) の PC をフリーズさせることも技術的に可能です。


技術的解説

CMPXCHG8B 命令の概要

CMPXCHG8B 命令は、レジスタ (EDX と EAX) に格納されている64ビット (8バイト) 値と、メモリに格納されている64ビット値 (デスティネーション) を比較する命令です。 この命令は Pentium 以降のプロセッサがサポートしています。 メモリ上にある8バイトデータとプロセッサ内部のレジスタとを比較し、その結果によってメモリの内容を更新します。

本来、デスティネーション オペランドはメモリのみで、内部レジスタを使うことはできません。 これは、CMPXCHG8B 命令が、64ビット単位で実行されるため、32ビットレジスタには合わないからです。

もし、デスティネーション オペランドがレジスタであった場合、プロセッサは無効命令例外 (Invalid Opcode Exception) を発生し、 CMPXCHG8B 命令の実行を止めます。 そして、無効オペランドが使われたことを OS に通知し、無効オペランド用のエラーハンドラを実行します。

ロック プリフィックス

システムの同期をとるために、命令の実行終了まで、他の命令の実行に割り込まれないようにする命令をロック プリフィックスといいます。

エラッタの発生条件

"ロック付 CMPXCHG8B 命令の無効オペランドエラッタ" は、CMPXCHG8B 命令がレジスタをデスティネーション オペランドとして指定され、かつロックプリフィックスが付けられていたときに発生します。 このとき、プロセッサはエラーの発生を通知することはできますが、バスがロック (Lock) されているために、プロセッサが無効命令例外ハンドラを実行することができません。 その結果システムが停止し、再起動が必要になります。

エラッタを引き起こす命令シーケンス

"F0 0F C7 C8" というバイトシーケンスを実行すると、"ロック付 CMPXCHG8B 命令の無効オペランドエラッタ" が発生します。

エラッタの対象となるプロセッサ

このエラッタの対象となるプロセッサは、Intel社 の Pentium, MMX Pentium またはその ODP です。 i486 やそれ以前の製品、Pentium Pro, Pentium II 以降の製品では発生しません。 AMD社 や Cyrix社 などの互換製品も影響を受けません。


各 OS のエラッタへの対応

Microsoft の状況

Windows 3.1/95, MS-DOS

Intel系 PC の代表的な OS である Windows 3.1/95, MS-DOS で、このエラッタの発生を確認しています。 キーボードからの入力も受け付けなくなるので [CTRL]+[ALT]+[DEL] によるリセットも動作しません。

Windows 98

「システム設定ユーティリティ」→「全般」→「詳細設定 (アドバンス トラブルシューティングの設定)」において、「Pentium F0 (Lock CmpXchg) の障害対処を使用可能にする」を有効にする事により、エラッタの発生を抑えることができます。 エラッタを引き起こすコードを含んだプログラムを実行すると、エラーメッセージを表示しプログラムは強制終了されますが、システム全体はフリーズしません。

上記設定が無効の場合は、Windows 95 と同様にエラッタが発生し、システム全体がフリーズします。

Linux の状況

カーネルバージョン 2.0.32 及び 2.1.64 以降で対策が取られています。

FreeBSD の状況

FreeBSD 2.2.6-RELEASE 以降のリリースで対策が取られています。

BSDI の状況

BSD/OS 用のパッチが公開されています。


エラッタの確認

DEBUG.EXE によるエラッタの発現

DOS 上の DEBUG.EXE を使用して "ロック付CMPXCHG8B命令の無効オペランドエラッタ" を発生させることができます。

C:\>debug
-a100
1292:0100 db f0 0f c7 c8
1292:0104 ret
1292:0105
-g

エラッタの対策が取られていない場合、システムがフリーズします。

"F0バグ" 発現プログラムによるエラッタの発現

Pentium "ロック付き CMPXCHG8B 命令の無効オペランドエラッタ" を発生させるプログラムを tmk氏と私で制作しました。 使用する前に付属のドキュメントをよく読んで下さい。

ダウンロードはこちらから : F00F05.lzh (2.81KB) - (更新日 : Oct 13, 1998)
PGP 署名 [F00F05.lzh.sig]
MD5 : 607370d46bccc94df528f05b09190c51

Intel社の公式情報

1998/04/10 に存在する公式サイト



Kei1's Laboratory
(C) 1998-1999 K.Yamamoto, All rights reserved.
Comment to: webmaster@kei1.homeunix.org
Created : Apr 10, 1998.
Updated : Aug 01, 1999.