ロード可能なカーネルモジュールを使用したLinux 3.2.xへの新しいシステムコールの追加

ロード可能なカーネルモジュールを使用したLinux 3.2.xへの新しいシステムコールの追加

Linuxカーネル3.2.xに特定の新しいシステムコールを追加したいのですが、ロード可能なカーネルモジュールとして追加したいです(カーネルを再コンパイルしたくないからです)。

私はインターネットとSOで多くの記事を読んでいますが、ある場所ではシステムコールをロード可能なモジュールとして実装することは不可能だと主張していますが、他の場所では可能だと言います。

何ですか?可能であればどのように達成できますか?

ベストアンサー1

システムコールテーブル(システムコールテーブルと呼ばれるsys_call_table)が静的にサイズ指定された配列であるため、これは不可能です。サイズは、登録されたシステムコールの数によってコンパイル時に決定されます。これは他人のためのスペースがないことを意味します。

arch/x86/kernel/syscall_64.csys_call_tableファイルで定義されているx86アーキテクチャの実装を確認できます。そのサイズは正確に次のように__NR_syscall_max+1定義されます(最後のシステムコールの番号)。ここでは、すべてのシステムコールを含むテーブルがあります。__NR_syscall_maxarch/x86/kernel/asm-offsets_64.csizeof(syscalls) - 1syscall

sys_setaltroot考えられる解決策の1つは、既存の(または廃止されたsyscall番号、アーキテクチャにある場合は例を参照)、syscall番号を再利用することです。これにより、より多くのメモリ領域が不要になります。また、一部のアーキテクチャ(x86の64ビットバージョンなど)のシステムコールテーブルに脆弱性がある可能性があるため、これを使用することもできます。

新しいシステムコールを開発していて実験中に再起動したくない場合は、この手法を使用できます。新しいシステムコールを定義し、システムコールテーブルで既存のエントリを見つけてモジュールで置き換える必要があります。

バージョン2.6以降、カーネルがモジュールにエクスポートされないため、カーネルモジュールでこれを行うのは簡単ではありませんsys_call_table(このシンボルをエクスポートする最後のカーネルバージョンは2.5.41)。

この問題を解決する1つの方法は、シンボルをモジュールにエクスポートするようにカーネルを変更することですsys_call_table。これを行うには、次の2行をkernel/kallsyms.c本番マシンではこれを行わないでください。):

extern void *sys_call_table;
EXPORT_SYMBOL(sys_call_table);

別の技術は、システムコールテーブルを動的に検索することです。カーネルメモリを見て、各単語を既知のシステムコール関数へのポインタと比較します。このシステムコールに対するテーブルのオフセットを知っているので、テーブルの開始アドレスを計算できます。

おすすめ記事