Linuxはインタープリタだった — kexecで自分自身を再帰的に実行するOSの話

元記事を読む
キュレーターコメント

「LinuxがLinux自身をインタープリトする」という哲学的なオチが最高。kexecを使った低レイヤの実験記事で、OSブートの仕組みを深く理解したいエンジニアに刺さる一本。

概要

「LinuxはPythonのようなインタープリタだ」と言われたら、あなたはどう反応するだろう?これは比喩でもなく冗談でもない。kexec という仕組みを使うと、Linuxは文字通り「自分自身を再帰的に呼び出すOS」になれる。この記事では、ある不思議なシェルスクリプトの解析を通じて、その仕組みをひも解いていく。

謎のワンライナーから始まる

あるブログ記事に、こんなコマンドが掲載されていた。

curl https://astrid.tech/rkx.gz | gunzip | sudo sh

「これ、本当に実行して大丈夫なの?」と思うのは当然だ。著者自身もそれを承知の上で、中身を丁寧に解説してくれている。ファイルを展開すると20MBのシェルスクリプトが現れ、その大半はBase64エンコードされたバイナリデータだった。

スクリプトの構造はシンプルだ。

  • rootで実行されているか確認
  • kexecbase64cpio コマンドの存在を確認
  • Base64をデコードして r(cpioアーカイブ)を生成
  • cpio から k(カーネルイメージ)を展開
  • kexec --load k --initrd r --reuse-cmdline で新しいカーネルをロード
  • kexec --exec で今すぐ新しいカーネルに切り替え
base64 -d <<'MARKER' > r
... (20MBのbase64データ) ...
MARKER
cpio -uidv k < r
kexec --load k --initrd r --reuse-cmdline
kexec --exec

kexec とは何か

kexec(Kernel Execute)は、Linuxカーネルが持つ「カーネルを置き換える」機能だ。通常の再起動と異なり、BIOSやブートローダーを経由せずに現在のカーネル空間から直接新しいカーネルを起動できる。クラウド環境でのカーネル更新やシステムクラッシュ時のデバッグに使われるが、今回の用途はもっと奇妙だ。

cpioアーカイブの中身を展開すると、こんな構成が見えてきた。

.
├── bin/   (398ファイル)
├── init   (シェルスクリプト)
└── k      (Linuxカーネル bzImage)

k の正体は Linux kernel x86 boot executable bzImage, version 6.18.18 (nixbld@localhost) #1-NixOS だ。そして init の中身がこちら。

#!/bin/sh
mkdir -p /proc
mount -t proc proc /proc
find / | grep -v /r | grep -v /proc | cpio -vo -H newc > /r
kexec --load /k --initrd /r --reuse-cmdline
kexec --exec

再帰するOS — これが「インタープリタとしてのLinux」

ここで全体像が見えてくる。このシステムがやっていることは:

  1. 起動する(initramfsとして)
  2. /proc をマウントする
  3. 自分自身を含む全ファイルシステムをcpioに再パックする
  4. kexecで新しいカーネル(= 自分自身の k)を起動する
  5. 1に戻る

つまり、このinitramfsは永遠に自分自身をkexecし続ける。Linuxカーネルが自分自身を「実行する」ループが生まれる。これはまるでPythonがPythonのソースコードを解釈して動くように、LinuxがLinuxを「インタープリト」しているようなものだ。

この発想は著者の以前の記事シリーズ(curl > /dev/sda でOSを書き換えるシリーズ)の延長線上にある。kexecとinitramfsを組み合わせると、「再起動なしにOSを完全に差し替える」どころか「OSが自分自身を永久に解釈し続ける」という奇妙なシステムが作れてしまう。

まとめ — 低レイヤの遊び場としてのkexec

この記事の面白さは「実害のあるマルウェア」ではなく「概念実証としての悪ふざけ」にある。kexecという地味な機能が、こんなに哲学的なユースケースに使えるとは思わなかった。NixOS をベースにしている点も、再現性のある環境をサクッと作れるNixらしさが出ていて興味深い。

kexecを実際に試したい場合は、まず kexec-tools をインストールしよう(Ubuntu系なら apt install kexec-tools)。ただし、本番環境での実験は当然ながらおすすめしない。仮想マシンの中で遊ぶのが吉だ。元記事には過去シリーズへのリンクもあり、「curl > /dev/sda でOSを置き換える」「リブートをまたいでシークレットを渡す」などの実験記録が読める。低レイヤ好きなら必読だ。