root が "/bin/rm -rf /" をしたらどうなるのか?

last modified: Feb 16, 2000

UNIX で root が "/bin/rm -rf /" をした場合の結末として、 以下のようになるという主張を実際に見たり聞いたりしたことがあるのですが、 全て明らかに誤りです。 信じてはいけません。

このページの目的は、 具体的な実験例で "rm -rf /" の結末を示すことで、 UNIX カーネルの semantics (振舞い)を確認し、 デマを払拭することにあります。

病的な例外を除けば、基本的には、"rm -rf /" すると、

以外の全てのファイルが消えます。 (POSIX 標準を見たところでは、 どれかのプロセスのカレントディレクトリになっているディレクトリが 消えない OS もあるようです。具体的なプラットフォームをご存知の方は、 お知らせ 下さい。) しかしそれは、カーネルや動作中のコマンドに致命的な衝撃を与えることを 意味しません。 in-core inode (vnode) の参照数が 0 でなければ、 on-disk inode と対応するブロックは消されないのが UNIX の semantics であるのを思い出してください。 open, mmap, execve 等は inode(vnode) の参照数を増加させ、 0 でなくしてくれます。unlink(2), rmdir(2) 自体は in-core inode の参照数に影響を及ぼさないのは自明でしょう。 加えて、カーネルのファイルについては、読むのは boot loader であり、 起動したカーネルが自分自身のファイルを参照することはありません。 (ユーザープロセスがシンボルテーブルを目当てに open 等をすることはある。)

Linux での実行例

以下に述べるのは、Slackware 3.1 on Linux 2.0.35 で実行してみた結果です。 実行後、ディスプレイのスナップショットを撮ってみたので参考にしてください。 ext247 というのは "/bin/rm -rf /" される機械のホスト名で、 sras70 というのは外部から種々の監視をしてくれた機械のホスト名です。

/bin/rm -rf / snapshot on Linux

左下の xterm の窓で、"/bin/rm -rf /" を実行してみた ら、/proc だけが残りました。

注:/usr, /var などを独立したパーティションにせず、 / 以下を単一のパーティションにしていました。 もし複数のパーティションを mount していたら、 mount point (や、そこに至るパス)も rmdir(2) されずに残っていたはずです。
右は top を実行中の窓であり、daemon 類や様々なコマンドが動作している (少なくとも終了していない)ことがわかります。 左上は、監視用の sras70 という機械で動いているシェルの窓ですが、 ことが観察できます。 ディスク上に残っている 7M 程のブロックは、 動作中のコマンドや オープンされたファイル(shared lib を含む)など、 参照数が 0 になっていないファイル(inode)に対応する分でありましょう。 それから、この snapshot を採取できたこと自体が、 X server や xterm が正常に動作しつづけていることの証左となります。 他にも、sendmail daemon にも接続できることが確認できていますが、 vrfy root などとしても User unknown で答えました。

この後、X server を終了して端末から logout すると、 コンソールにはメッセージも何も出ず、 キーを押しても無反応な状態になりました。 しかし、nfs server や daemon 類は動作し続けており、 監視している sras70 から df してみることは普通にできます。 やってみると、 終了したコマンドや close されたファイルに相当する分のブロックが 解放されて、使用中の領域が減っていました。

ちなみに、Slackware の rm は GNU fileutils 由来です。

より詳細には、以下の情報を参照してください。

FreeBSD での実行例

以下に述べるのは、FreeBSD 2.2.5-RELEASE で実行してみた結果です。 実行後、ディスプレイのスナップショットを撮ってみたので参考にしてください。 ext247 というのは "/bin/rm -rf /" される機械のホスト名で、 sras70 というのは外部から種々の監視をしてくれた機械のホスト名です。

rm -rf / snapshot on FreeBSD

結果は Linux とほとんど同じです。 左下の xterm の窓で、"rm -rf /" を実行してみた ら、/kernel と /proc だけが残りました。

注:
右は top を実行中の窓であり、daemon 類や様々なコマンドが動作している (少なくとも終了していない)ことがわかります。 左上は、監視用の sras70 という機械で動いているシェルの窓ですが、 ことが観察できます。 ディスク上に残っている 7M 程のブロックは、 動作中のコマンドや オープンされたファイル(shared lib を含む)など、 参照数が 0 になっていないファイル(inode)に対応する分です。

この後、X server を終了して端末から logout すると、 コンソールにはメッセージも何も出ず、 キーを押しても無反応な状態になりました。 それでも、監視している sras70 からは、 カーネルやデーモン類が動作し続けていることが確認できました。 df してみると、 終了したコマンドや close されたファイルに相当する分のブロックが 解放されて、使用中の領域が減っていました。

ちなみに、FreeBSD の rm は 4.4BSD Lite-2 由来です。

より詳細には、以下の情報を参照してください。

反省

追試をなさる方は以下にご注意ください。

future work

このページは、理論的な考察よりも、 実際に実験してみた結果を報告することに集中しています。 今後は、System V 系の機械での実験が望まれます。 System V 系では、 実行中のコマンドのファイルを unlink しようとすると ETXTBSY になるはずで、 多数のファイルやディレクトリが残ることが見込まれます。

参考文献

rm に関する過去のニュース記事
どうして open, mmap(dynamic lib), execve されたファイルを unlink しても ブロックはすぐには解放されないのか、 kernel を削除してもかまわないのは何故か等、 このページの実験の背景となる UNIX システムの振舞いの解説。
rm(1) のソース
実はこれをみても、UNIX システムの振舞いはあまりわからないとは思う。

文責:渡邊克宏

誤りの指摘や質問、感想あるいは関連する情報の提供を歓迎します。

katsu@watanabe.name