web-dev-qa-db-ja.com

現在実行中のLinuxカーネルがkexecでロードされているかどうかを確認する方法は?

チェックすることで、私はかなり堅実なものを意味します。たとえば、ローダーの構成または使用可能なカーネルファイルを分析し、unameの出力と一致させることはオプションではありません。

7
poige

一般的な場合、いいえ、それは不可能です。以前の状態は信頼できず、通常の再起動と区別できないためです。

例として、ブート時にRAM=をワイプしないシステムがあるとします(一部のセキュアブート仕様では、ブート時のメモリワイプが必要です));最初のブートプロセスとすべての通常の再起動は通常、同じオフセットで発生し、時間の経過とともに前回のブートからすべてを消去しますカーネル自体はほとんど常に同じアドレスにロードされます。

ここで、通常の再起動の代わりにkexecを検討し、すべてが同じオフセットで終了し、ほとんど区別がつかないことを理解します。

Kexecを検出できる特別なケースはありますか?はい!

  • Kdumpは、新しいカーネルを別のアドレスに明示的にロードし、エラー状態をキャプチャするために前のカーネルのメモリを保持することを望んでいます。
  • BIOSとカーネルがハードウェアを異なる方法で初期化する場合、スイッチ "usual/kexec"を使用してブートするたびに変更が発生するため、(明らかに)注意される場合があります。
  • この具体的な例として、EFIフレームバッファーは、ブート中にカーネルによって確実に変更され、kexecで元の状態に戻ることはありません。
  • これの当然の結果として、kexecされたカーネルのブートを制御せず、それがハードウェアに接触した場合、それがであったかどうかを後で判断する方法はほとんどありません。 realブートまたはkexecブート。

デモとして、カーネルを使用してVMを起動し、dmesgをキャプチャし、すぐにハードkexecを実行して、dmesgを再度キャプチャしました。dmesgの2つの実行の違いは次のとおりです。 https://Gist.github.com/robbat2/7609be2715591eac8ace3f46e852c549

7
robbat2

コードで答えを見つけたので、共有したいと思います。

実行中のカーネルをロードするために使用されたブートローダーを確認するには、以下を確認します。

/proc/sys/kernel/bootloader_type

次に、bootloader_typeを取得するために4ビット右シフトする必要があります。これは、x86の次のファイル(カーネルツリー内)に記述されています。Documentation/ x86/boot.rst [0]

Kexecローダーはシフト後に0xDを表示します(kexec-toolsコードから、#define LOADER_TYPE_KEXEC 0x0Dとして定義されていることがわかります)。

残念ながら、これはx86のみのトリックです!!!それが役に立てば幸い。

[0] www.kernel.org/doc/Documentation/x86/boot.rst

2
guipy