Kernel Modules and System Calls

Kernel Modules and System Calls

Creating a "Syscalls" module
by John Brodie

Creating a module for your system calls allows you to make quick changes
to your syscalls, without the need to rebuild any of the kernel, and without
the need to install/reboot your new kernel version.  

However, adding new syscalls via a module is not something supported by the
kernel although you can intercept and override existing syscalls
(http://www.linuxjournal.com/article/4378, not personally tested).

Enter function pointers...

1. Create your "wrapper" syscall:
 - Use a new file (or not):
#include <linux/linkage.h>
#include <linux/kernel.h>
#include <linux/module.h>

long (*STUB_mygetpid)(void) = NULL;
EXPORT_SYMBOL(STUB_mygetpid);

asmlinkage long sys_mygetpid(void)
{
    if(STUB_mygetpid)
        return STUB_mygetpid();
    else
        return -ENOSYS;
}
The above code creates a null function pointer, exports it for later use, and
adds a syscall that will call the function pointer if it has been set.

2. Create your module:
#include <linux/module.h>    /* Needed by all modules */
#include <linux/kernel.h>    /* Needed for KERN_INFO */
#include <linux/init.h>        /* Needed for the macros */
#include <linux/sched.h>
#include <linux/linkage.h>

extern long (*STUB_mygetpid)(void); // Get our function pointer
long mygetpid(void);

static int __init init_custom_syscalls(void)
{
    printk(KERN_INFO "Syscalls module loaded...\n");
    STUB_mygetpid=&(mygetpid); // Point to our new syscall on load.
    return 0;
}
static void __exit cleanup_custom_syscalls(void)
{
    STUB_mygetpid=NULL; // Clean up after ourselves.
    printk(KERN_INFO "Syscalls module unloaded...\n");
}

long mygetpid(void)
{
    printk(KERN_INFO "mygetpid called.\n");
    return current->tgid;
}

/* Declare init/exit functions for module. */
module_init(init_custom_syscalls);
module_exit(cleanup_custom_syscalls);
The above creates a module that gets our function pointer, and points it to
our newly created pseudo-syscall function on init.

3. Create Makefile for your new files:
obj-m += syscalls.o
obj-y += export_syscalls.o
all:
    make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules

clean:
    make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean

4. Add your wrapper syscall to syscall_table.S, unistd.h, and syscall.h, the same as you would for a normal syscall. 5. Recompile your kernel with `make`, installing it as normal. From now on, you only need to touch/recompile your module. 6. As root, use `insmod syscalls.ko` to load your module, and `rmmod syscalls` to remove it. You can tail dmesg to check that it has loaded.

From:https://www.cs.drexel.edu/~jjohnson/2012-13/fall/cs543/project/kmod.htm
posted @ 2013-01-21 17:46  Biiigfish  阅读(395)  评论(0编辑  收藏  举报