システムコールを実行するカーネルコードが見つかりました。しかし、それは許可されていないと思いますか?

システムコールを実行するカーネルコードが見つかりました。しかし、それは許可されていないと思いますか?

コンテキスト:linux-5.0/Documentation/process/adding-syscalls.rst#do-not-call-system-calls-in-the-kernel

まず、カーネルコードは呼び出し規則が間違っているため、「sys_xyzzy()」などの関数を呼び出すことはできません。

しかし、第二に、「データへのアクセス方法はカーネルデータとユーザーデータの間で異なる可能性があります。」

これで、以前の "sys_xyzzy()" 呼び出しを直接置き換える関数があります。例: ksys_mount().

ksys_mount() __usersys_mount() を呼び出すのと同様に、メモリへのポインタを取得します。したがって、カーネルメモリへのポインタを渡すと失敗するはずです。具体的には、copy_from_user() 呼び出し時に失敗します。ゲームをプレイするためにset_fs()を使用しない限り

それでは...カーネルの別の場所でksys_mount()を何度も呼び出すのはなぜですか?これらのどれがどのように機能するのですか? set_fs() への呼び出しは含まれていません。

https://elixir.bootlin.com/linux/v5.0/ident/ksys_mount

  • ドライバ/ベース/devtmpfs.c
  • 初期化/do_mounts.c
  • ...

答え1

devtmpfs現在、カーネルスレッドで実行中です。カーネルスレッドではaddr_limit効果的に無効になります。少なくともx86の場合はそうです。これはアーキテクチャ固有のコードです。

init/do_mounts.cとても似ています。カーネル初期化プロセスはカーネルスレッドのように起動し、効果addr_limit的に無効にする必要があります。その後、do_execve()ユーザー空間初期化プログラムを呼び出して実行を開始します。コア必ず「set_fs(USER_DS)」を呼び出してください。、ユーザー空間プログラムを実行する前に。

関連情報