在拦截系统调用时无法在X处理内核分页请求

时间:2013-01-20 14:20:19

标签: c linux kernel-module kernel

  

可能重复:
  Linux Kernel: System call hooking example

我一直在尝试在内核级挂钩系统调用。我从这个question得到了基本的想法。我试图拦截的系统调用是 fork() 。所以我从System.map中找到了 sys_call_table 的地址,结果证明是0xc12c9e90。现在我编写了如下模块。

#include<linux/kernel.h>
#include<linux/module.h>
#include<linux/unistd.h>
#include<linux/semaphore.h>
#include<asm/cacheflush.h>
MODULE_LICENSE("GPL");
void **sys_call_table;
unsigned long addr;
asmlinkage int (*original_call)(struct pt_regs);
asmlinkage int our_call(struct pt_regs regs)
{
        printk("Intercepted sys_fork");
        return original_call(regs);
}
static int __init p_entry(void)
{
        struct page *pg;
        printk(KERN_ALERT "Module Intercept inserted");
        sys_call_table=(void *)0xc12c9e90;
        pg=virt_to_page(sys_call_table);
        addr=(unsigned long)page_address(pg);
        set_memory_rw(addr,1);
        original_call=sys_call_table[__NR_fork];
        sys_call_table[__NR_fork]=our_call;
        set_memory_ro(addr,1);
        return 0;
}
static void __exit p_exit(void)
{
        sys_call_table[__NR_fork]=original_call;
        set_memory_ro(addr,1);
        printk(KERN_ALERT "Module Intercept removed");
}
module_init(p_entry);
module_exit(p_exit);

我编译了模块,并尝试将其插入内核。不幸的是,dmesg输出给了我一条消息,如下所示 BUG:无法在c12c9e98上处理内核分页请求,这里是ellaborate dmesg放

enter image description here enter image description here

作为一个找出问题的实验,我只是注释掉了

 sys_call_table[__NR_fork]=our_call;

之后我重复编译,然后插入。它没有显示任何错误。所以我得出结论,将上述新函数分配给sys_call_table的上述指定行是问题所在。但是我不知道是什么导致它以及如何解决它。任何人都可以帮我解决它吗?

1 个答案:

答案 0 :(得分:0)

我希望您对set_memory_rw的调用没有生效,因为您没有使用flush_tlb,因此当您写入syscall_table时,CPU的TLB仍处于活动状态生效。你需要刷新TLB。您可以使用local_flush_tlb()