2011-05-05 100 views
3

我想明白,如果我们能给予控制权交还给前内核/用户模式添加我们页面故障处理程序/异常处理程序和处理我们所引起的故障到内核​​。 任务在这里将不会修改现有的内核代码(do_page_fault FN),但增加了一个用户定义的处理程序时,页面错误或和异常触发用户自定义页面错误和异常处理

人能找到的工具,如“这将抬头kprobe“,它们在教学中提供钩子,但是看起来这样不会达到我的目的。

如果有人能够帮助我理解这一点或者指出良好的参考资料,那将会很棒。

回答

0

我不认为这是可能的 - 首先,页面错误处理程序是一个复杂的函数,需要直接访问虚拟内存子系统结构。其次,假设这不是问题,但为了在用户空间中编写页面错误处理程序,您应该能够捕获一个错误,默认情况下会强制传输到内核空间,所以至少应该防止这种情况发生。

为此,您需要一位主管来跟踪所有内存访问,但是您无法保证主管代码已经映射并存在内存中。

2

在用户空间中,您可以为SIGSEGV定义一个信号处理程序,因此只要发生无效的内存访问,就会调用您自己的函数。与mprotect()结合使用时,可以让程序管理自己的虚拟内存,全部来自用户空间。

不过,我得到的是你正在寻找一种方式来拦截所有页面错误(主要,次要,和无效),并在响应时调用任意内核功能的印象。我不知道干净的方式来做到这一点。当我在自己的研究项目中需要此功能时,我最终将代码添加到do_page_fault()。它对我来说工作得很好,但它是一种黑客攻击。如果有人知道一个干净的方法来做到这一点(即,可以在一个vanilla内核上使用一个模块),我会非常感兴趣。

+0

嗯,我认为它可以通过替换IDT中的'page_fault'处理程序来实现。除此之外,这里允许代码拼接,但这是一个非常肮脏的黑客;) – 2011-05-31 11:41:25

0

你想安装一个用户级寻呼机gnu libsegsev。我没有使用它,但它似乎只是你正在寻找的东西。

1

如果你不会改变内核处理这些错误的方式,并且只是在之前添加你的,那么kprobes将服务于你的目的。它们有点难以处理,因为你在包含寄存器和堆栈的结构中获得探测函数的参数,并且你必须知道,编译器把它们放在哪里。但是,如果你需要它的特定功能(在创建探测器时已知),那么你可以使用jprobeshere是一个很好的例子来说明如何使用两者),它需要与探测完全相同的参数进行探测的函数在寄存器/堆栈中重新编译)。

您可以动态加载内核模块并在选定的函数上安装jprobes而不必修改内核。