Kernel

使用可載入核心模組向 Linux 3.2.x 添加新的系統呼叫

  • April 7, 2015

我想在 linux 核心 3.2.x 中添加一個特定的新系統呼叫,但作為一個可載入的核心模組(因為我不想一次又一次地重新編譯核心)

我閱讀了網際網路和 SO 上的許多文章,有些地方聲稱將系統呼叫實現為可載入模組是不可能的,而另一些地方則說這是可能的。

它是哪一個?如果可以的話怎麼做?

這是不可能的,因為系統呼叫表(稱為sys_call_table)是一個靜態大小的數組。它的大小在編譯時由註冊的系統呼叫的數量決定。這意味著沒有空間容納另一個。

例如,您可以在文件中檢查 x86 架構的實現arch/x86/kernel/syscall_64.c,其中sys_call_table已定義。它的大小正好__NR_syscall_max+1__NR_syscall_max定義arch/x86/kernel/asm-offsets_64.csizeof(syscalls) - 1(它是最後一個系統呼叫的數量),其中syscall是一個包含所有系統呼叫的表。

一種可能的解決方案是重用一些現有的(或不推薦使用的,如果您的體系結構有一個,請參見sys_setaltroot例如)系統呼叫號,因為這不需要更多的記憶體空間。某些體系結構的系統呼叫表中也可能存在漏洞(例如 x86 的 64 位版本),因此您也可以使用它。

如果您正在開發新的系統呼叫並且只是想避免在試驗時重新啟動,則可以使用此技術。您必須定義新的系統呼叫,在系統呼叫表中找到現有條目,然後從您的模組中替換它。

從核心模組執行此操作並非易事,因為核心不會導出sys_call_table到版本 2.6 的模組(導出此符號的最後一個核心版本是2.5.41)。

解決此問題的一種方法是更改​​核心以將sys_call_table符號導出到模組。為此,您必須添加以下兩行kernel/kallsyms.c不要在生產機器上執行此操作):

extern void *sys_call_table;
EXPORT_SYMBOL(sys_call_table);

另一種技術是動態查找系統呼叫表。您遍歷核心記憶體,將每個單詞與指向已知系統呼叫函式的指針進行比較。因為你知道這個知道系統呼叫在表中的偏移量,你可以計算表的起始地址。

引用自:https://unix.stackexchange.com/questions/47701