如何在PPC Linux上运行时挂钩syscall表?

时间:2010-08-18 22:42:34

标签: linux-kernel kernel-module system-calls powerpc hook

主题: PPC汇编语言 - Linux可加载内核模块

详细信息:在syscall表挂钩中从内核调用时如何访问本地TOC区域(r2)?

我已经为Linux编写了一个可加载的内核模块,它使用syscall表挂钩拦截系统调用并在将调用传递给原始处理程序之前记录有关它们的信息。这是安全产品的一部分。我的模块运行良好,并且运行在各种Linux内核版本和分布上的生产代码中,32位和64位内核都在x86硬件上运行。

我正在尝试将此代码移植到Linux上运行PPC处理器并遇到一些问题。使用Linux内核源,很容易看到系统调用表在PPC上的实现方式不同。我可以用我自己编译的处理程序中的函数地址替换表中的条目,没问题。

但是,这是我遇到麻烦的问题。 PPC ABI使用这种称为目录(TOC)地址的东西,该地址存储在CPU的R2寄存器中,并期望通过使用该寄存器中包含的地址(TOC地址)的偏移来寻址模块的全局和本地数据。这在正常情况下工作正常,因为编译器知道在进行调用之前将模块的TOC地址加载到寄存器中(或者它已经存在,因为通常你的函数被你自己的代码调用)。

但是,当我将自己的函数的地址(从运行时加载的内核模块)放入系统调用表时,内核调用我的处理程序,其R2值不是我编译的C代码所期望的值,所以我的代码在无法访问其数据的情况下获得控制权。

是否有人知道有任何示例代码显示如何处理这种情况?我无法重新编译内核。这应该是运行时系统调用表挂钩的简单情况,但我还没有弄明白,或找到任何特定于PPC的示例。

想法包括:

手工编写汇编语言存根,保存R2值,使用我的本地TOC地址加载寄存器,执行我的代码,然后在调用原始处理程序之前恢复旧值。我没有PPC装配经验的深度来做这件事,我也不确定它会起作用。

一些魔术gcc选项,它将在不使用TOC的情况下生成我的代码。有一个记录的gcc选项"-mno-toc"在我的PPC6 Linux上不起作用。看起来它可能只是系统V.4和嵌入式PowerPC的一个选项。

非常感谢任何帮助!

谢谢!

2 个答案:

答案 0 :(得分:1)

Linux有一个通用的系统调用审计基础结构,可以在powerpc上运行,您可以从用户空间访问。您是否考虑过使用它而不是编写内核模块?

答案 1 :(得分:0)

您需要存根才能加载r2。内核源代码中有一些例子。