/* syscall.c * * 2009.09.05 * Primitive syscall module that replaces an unused system call and * prints a message to /var/log/syslog. * * Built from the Linux Kernel Module Programming Guide, Ch 8.1 example. */ #include /* kernel work */ #include /* building a kernel module */ #include /* table of system calls sys_call_table[] */ /* Prototypes */ int init_module(void); void cleanup_module(void); asmlinkage void my_syscall(void); /* We need the system call table because we're going to fill in one unused * slot or add a new slot. The system call table is initialized at module * load time with all the system call functions before we modify it. * System call numbers are in include/asm-i386/unistd.h. * The system call table sys_call_table[] with system call names is in * arch/i386/kernel/entry.S. Only 190 calls there, although the unistd.h * has more numbers. * * In this case we will usurp the __NR_ulimit system call number 58 which * is currently not implemented (sys_ni_syscall). */ extern void *sys_call_table[]; /* * The __NR_ulimit system call 58 that we will replace is actually * implemented with the void sys_ni_syscall(void) system call. */ asmlinkage void (*original_call) (void); /* * My new system call */ asmlinkage void my_syscall(void) { printk(KERN_ALERT "syscall module: entering.\n"); printk(KERN_ALERT "syscall module: leaving.\n"); } /* * Module initialization and cleanup. The LKMPG has a good discussion * in section 8.1 about the synchronization dangers of replacing and * restoring a system call when someone else could be replacing and restoring * the same system call. We'll assume that for this simple example program * that nobody else will be messing with this system call. */ /* Initialize the module - modify the sys_call_table */ int init_module(void) { printk(KERN_ALERT "syscall module: load and replace ulimit syscall 58.\n"); original_call = sys_call_table[__NR_ulimit]; sys_call_table[__NR_ulimit] = my_syscall; return 0; } /* Clean up the module - restore the sys_call_table */ void cleanup_module(void) { printk(KERN_ALERT "syscall module: unload and restore ulimit syscall 58.\n"); sys_call_table[__NR_ulimit] = original_call; }