Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Intercepting a system call

I have been trying to intercept the system call at the kernel level. I got the basic idea from this question . The system call I was trying to intercept was the fork(). So I found out the address of the sys_fork() from System.map and it turned out to be 0xc1010e0c.Now I wrote the module as below.

#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;
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)
{
    printk(KERN_ALERT "Module Intercept inserted");
    sys_call_table=(void *)0xc1010e0c;
    original_call=sys_call_table[__NR_open];
    set_memory_rw((long unsigned int)sys_call_table,1);
    sys_call_table[__NR_open]=our_call;
    return 0;
}
static void __exit p_exit(void)
{
    sys_call_table[__NR_open]=original_call;
    set_memory_ro((long unsigned int)sys_call_table,1);
    printk(KERN_ALERT "Module Intercept removed");
}
module_init(p_entry);
module_exit(p_exit);

However , after compiling the module and when I tried to insert it to the kernel, I got the following from the dmesg output. enter image description hereenter image description here

Of course its not intercepting the system call.Can you help me figure out the problem? I am using 3.2.0-4-686 version of Linux kernel.

like image 253
PaulDaviesC Avatar asked Jan 19 '13 14:01

PaulDaviesC


1 Answers

http://lxr.linux.no/linux+*/arch/x86/mm/pageattr.c#L874 says

            if (*addr & ~PAGE_MASK) {
                    *addr &= PAGE_MASK;
                    /*
                     * People should not be passing in unaligned addresses:
                     */
                    WARN_ON_ONCE(1);
            }

So the warning is because your sys_call_table variable is not page-aligned.

It should be said that patching the system call table is officially discouraged by the kernel maintainers, and they've put some deliberate roadblocks in your way -- you've probably already noticed that you can't access the real sys_call_table symbol, and the write protection is also deliberate. If you can possibly find another way to do what you want, then you should. Depending on your larger goal, you might be able to accomplish it using ptrace and no kernel module at all. The trace_sched_process_fork hook may also be useful.

like image 161
zwol Avatar answered Oct 13 '22 17:10

zwol