使用可載入核心模組向 Linux 3.2.x 添加新的系統呼叫
我想在 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.c
為sizeof(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);
另一種技術是動態查找系統呼叫表。您遍歷核心記憶體,將每個單詞與指向已知系統呼叫函式的指針進行比較。因為你知道這個知道系統呼叫在表中的偏移量,你可以計算表的起始地址。