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