オペレーティングシステムはDebianです。
私の質問によると:
システムコールテーブルを変更して再起動システムコールを傍受するカーネルモジュールを作成しました。
デフォルトでは、次のように古い関数ポインタを保存します。
old_reboot = (void *) *(sys_call_table + __NR_reboot);
その後、書き込み可能にし、次の操作をsys_call_table
行います。
*(sys_call_table + __NR_reboot) = (unsigned long) my_reboot;
sys_call_table
その後、読み取り専用に切り替えます。私の再起動システムコールは次のとおりです。
asmlinkage long my_reboot(int magic1, int magic2, unsigned int cmd, void __user *arg)
{
printk(KERN_INFO "Intercepted sys_reboot\n");
return old_reboot(magic1, magic2, cmd, arg);
}
次に、bashで "reboot"コマンドを実行してコードをテストしました。
ただし、dmesg / syslogにログに記録されるカスタム再起動機能は表示されませんが、モジュールがロードまたはアンロードされたときにログが表示されるため、少なくともその部分は機能します。
open
だから私はsyscallの代わりにシステムコールを使って同じことを試しましたが、うまくいきreboot
ました。したがって、パブリックシステムコールを傍受して呼び出すプロセスのpidを取得し、その情報をdmesg / syslogなどに記録できます。
この方法でオープンシステムコールを傍受できますが、再起動システムコールが傍受できないのはなぜですか?
再起動すると、実際に再起動システムコールが呼び出されますか?それとも私がここで何か間違っているのでしょうか?
編集する:
再起動システムコールを直接呼び出す小さなプログラムを書いていました。 (カーネルモジュールを介して再起動システムコールを傍受することができます)
再起動_テスト.c:
#include <unistd.h>
#include <sys/reboot.h>
int main()
{
sync();
reboot(RB_AUTOBOOT);
return 0;
}
ただし、再起動コマンドを使用して再起動しようとすると、ブロックされた再起動システムコールは記録されません。
追加のテストで以下を実行します。
strace -f reboot
再起動システムコールを表示しませんが、私の小さなCプログラムを使用すると、straceは再起動システムコールを表示します。 (再起動する前の最後の行)
systemdが再起動システムコールを使用しないのはなぜですか?
すべての再起動が再起動システムコールを使用するようにシステムをどのように設定しますか?
答え1
私はこれが完全な答えではないと確信しています。 systemdソースコードを調べてみると、緊急再起動が必要な場合(おそらく "reboot -f"コマンドのために??)、再起動(2)と同じエントリポイントに直接システムコールが行われますが、それをバイパスしているようです。 glibc、glibcライブラリでサポートされていない5番目のパラメータを追加します。通常の再起動が呼び出されると、再起動する前に少なくとも同期してファイルシステムをアンマウントする/usr/lib/systemd/systemd-shutdownを呼び出すようです。それ現れる再起動システムコールを実行しますが、ロジックはかなり複雑です。