カーネルの実行でサポートされるシステムコール


9

現在実行中のLinuxカーネルでサポートされているシステムコールの数またはリストを取得する方法はありますか?そのため、実行中のカーネルのsyscallテーブルを「読み取る」方法を見つけたいと思います。

回答:


15

このファイルに/proc/kallsymsは、実行中のカーネルのすべてのシンボルがリストされています。慣例により、システムコールの名前はで始まりますsys_。64ビットシステムでは、32ビットプログラムのシステムコールの名前はで始まりますsys32_。厳密に言えば、これはシステムコールではなく内部カーネル関数をリストしますが、対応は機能すると思います(すべてのシステムコールは内部カーネル関数を呼び出してジョブを実行し、名前は常にシステムコールの名前のsys_前に付加されていると思います)。

</proc/kallsyms sed -n 's/.* sys_//p'

システムコールの変化が非常に遅いため、通常、これは有用な情報ではありません。オプションのコンポーネントは、既存のシステムコールの機能を提供し、デバイス(ioctlを使用する場合readwriteしない場合)、ファイルシステム、ソケットなどの一般的な機能を使用します。サポートされるシステムコールのリストを決定しても、機能については何もわかりませんシステムがサポートすること。他の内部関数名もすぐに変更されるため、役に立ちません。あるカーネルバージョンにいくつかの機能を実装する関数の名前は、次のバージョンで変更される可能性があります。


+1。「私より経験のある人に答えさせましょう」と言ったのは、まさにそういうことです。また、/proc/kallsyms他のファイルと同じように操作できるため、プログラムでの使用が非常に簡単になります。
ジョンWHスミス

2
@JohnWHSmith「他のファイルと同じように操作できます」…カーネルASLRを備えたシステムでは、このファイルはrootだけが読み取り可能である必要があることに注意してください。
Gilles「SO-邪悪なことをやめなさい」2014

7

TL; DR

この回答を書いているとき、私は新しい選択肢を探し続けたので、それぞれについて少し詳細を書いて、いくつかの統計を作成しました。基本的に、次のいずれかを行うことができます。

  • Gillesの回答を読んでください。これは、クリーンで迅速な方法を提供します(に依存します/proc)。
  • ドキュメントリソースを使用します。
  • システムのCヘッダーファイルを使用します。
  • カーネルソースコード自体を使用します。
  • /sysディレクトリを使用します。

計算を行った後/sys、システムコールの数の点で最良の結果が得られるように思われるため、ファイルシステムを使用することをお勧めします(代替案の中でも)。他のトリックについて読みたくない場合は、そのセクションに直接ジャンプできます。

ドキュメントリソースの使用

それらのいくつかを見逃しているかもしれませんがapropos、セクション2(システムコール)に属するすべてのマンページをリストするために使用できます。

$ apropos -s2 . | awk '{print $1}' | column

column派手な列化された出力が必要ない場合は削除してください。

私はそれを見つけたばかりですが、システムコールに関するLinuxのmanページがあり、そのほとんどを見つけることができます。

$ man syscalls

また、興味深い2つのWebサイトに出会いました。

ヘッダーファイルの使用

編集:今、それがプログラム的に(または少なくとも、文書化された機能に依存することなく)利用可能なシステムコールを決定することになると、カーネルはそのシステムコールのテーブルを保持していません、少なくとも文字列のリスト(おそらくそれらを操作すると予想されるため)。このレベルでは、関数名ではなく、関数のアドレスとポインタについて詳しく説明しています。

私は自分の/usr/includeディレクトリを参照してgrep、いくつかのことを編集しました。以下のディレクトリが興味深いかもしれません。アーキテクチャやディストリビューションによっては、マシンによって異なるものもありますが、それらを適合させることができると確信しています。

  • / usr / include / linux
  • / usr / include / x86_64-linux-gnu
  • / usr / include / sys
  • / usr / include / asm-generic

このファイルで関数の定義を探すと、そこに完全に定義されていなくても、多くのシステムコールに遭遇します。grepこれらのディレクトリで数秒実行したところ、いくつかのシステムコールに関する記述を見つけることができました。次に例を示します。

$ grep 'sys_exit' /usr/include -R
asm-generic/unistd.h:__SYSCALL(__NR_exit, sys_exit)

だから、それらのいくつかを見つける別の方法は次のようになると思います:

$ egrep '^__SYSCALL' /usr/include -Rh | awk '{print $2}' | tr -d ')'

カーネルのソースコードとそのsyscallテーブルの使用

もう1つの解決策は、(ヘッダーだけでなく)カーネルソースコード自体を使用して、効率的に検索する方法を見つけることです。カーネルコミット303395ac3bf3e2cb488435537d416bc840438fcbなので、これは以前よりも少し簡単に感じるかもしれません。以下は、3.13(私のカーネル)の例です。

$ wget https://git.kernel.org/cgit/linux/kernel/git/stable/linux-stable.git/plain/arch/x86/syscalls/syscall_64.tbl?id=refs/tags/v3.13 -O syscall_64.tbl

実際のsyscallsテーブルを取得したので、それを参照します。

$ while read line; do awk '! /#/ {print $3}'; done < syscall_64.tbl

あなたは使用して、道を見つけることができるunameし、archダウンロードするには、tblからファイルをまっすぐにgit.kernel.orgあなたの実行中のカーネルのバージョンとアーキテクチャに基づいて、。

/sysファイルシステムの使用

Gillesの答えは私に少しインスピレーションを与えました/sys/kernel/debug/tracing/events/syscalls。このディレクトリは、システムでの各システムコールの使用を監視するために使用されます。各syscallには2つのディレクトリがあります。

  • sys_enter_ [syscall]
  • sys_exit_ [syscall]

そのため、使用してlsgrepcut...

$ ls /sys/kernel/debug/tracing/events/syscalls | grep 'sys_enter' | cut -d'_' -f3

統計

私のシステムでは:

  • manページを使用すると、440のシステムコールが明らかになりました。
  • grep__SYSCALLヘッダーファイルで-ingを実行すると、212のシステムコールが明らかになりました。
  • カーネルソースからsyscallsテーブルを読み取ると、346のシステムコールが明らかになりました。
  • /sys明らかにされた290のシステムコールの使用。

さて、すべてをまとめると...

$ apropos -s2 . | awk '{print $1}' > system_calls.txt
$ egrep '^__SYSCALL' /usr/include -Rh | awk '{print $2}' | tr -d ')' >> system_calls.txt
$ while read line; do awk '! /#/ {print $3}'; done < syscall_64.tbl >> system_calls.txt
$ ls /sys/kernel/debug/tracing/events/syscalls | grep 'sys_enter' | cut -d'_' -f3 >> system_calls.txt

$ sort < system_calls.txt | uniq | wc -l
707

707システムコールです。もちろん、この数は「システムコール」の非常に柔軟な定義を反映しています。3.13は274のシステムコールのみを提供することになっているためです(読み取り/sysが最も近い解決策のようです)。


どのシステムコールがマニュアルページに記載されているのかを知るのではなく、何らかの方法でシステムコールテーブルを「読み取る」という点で、もっと方法を探しています
Swair

カーネルがシステムコールのリストを保持しているとは思わない。少なくとも文字列のリストとしてはそうではない。回答を編集しました。これを行う実際の方法がある場合は、私よりも経験の豊富な誰かに回答させてもらいます;)
ジョンWHスミス

カーネルにシステムコールを追加し、それを使用しようとすると、「関数が実装されていません」というメッセージが表示された後、これについて疑問に思っていました。「#make install」を実行し、grubを更新して新しいカーネルを開始すると、新しいカーネルは新しいシステムコールを含む関連するインクルードファイルをどのステップで取得しますか?
2014年

1
システムコールが見つからない場合は、正しく実装されていません。私の答えは、Linuxのシステムコールを見つける方法を示していますが、自分のシステムコールをデバッグする方法を示していません(それはあなたが求めているものではないためです)。開発に問題がある場合は、具体的に質問して、XY問題を回避する必要があります
ジョンWHスミス

@swairシステムコールを追加して機能を追加することは非常にまれです。コードを提供していないため、何が問題なのかはわかりません(質問にCコードが必要な場合は、ここではトピックから外れていますが、Stack Overflowでご確認ください)。システムコールを(正しくまたは正しく)実装し、それをCプログラムから使用しようとしていること、およびシステムコールを作成するC関数を作成する手順が不足していると思います。システムコールは通常の関数呼び出しではありません。
Gilles「SO-邪悪なことをやめなさい」2014

1

すべての答えは結構です。

特定のシステムコール名を探している場合:

$ cat /proc/kallsyms | grep <sys_call_name>

すべてのシステムコールのリストを探している場合:

$ cat /proc/kallsyms
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.