/* mod-syscall-xtime.c * * Replace the futex 240 system call to return xtime * as a timeval struct through a reference parameter * to user space. * Note that the replacement of futex 240 does no type checking * because we're not even replacing system calls * with compatable types. * * Derived from the no-parameter or result hello-1 example in the * Linux Kernel Module Programmer's Guide for 2.4 Kernel. * * We'll used an existing syscall entry (futex) and replace it * * Include file locations * is /usr/src/linux/include/linux * is /usr/src/linux/include/asm * is /usr/include/sys * * Source file locations * sys_call_table[] /usr/src/linux/arch/i386/kernel/entry.S */ /* kernel module programming */ #ifndef MODULE #define MODULE #endif #ifndef LINUX #define LINUX #endif #ifndef __KERNEL__ #define __KERNEL__ #endif #define MAX_BUF 80 #include /* needed by all modules */ #include /* for KERN_ALERT */ #include /* for __NR_futex & other system call numbers */ #include /* for struct timeval (we want the kernel time.h) */ #include /* for EFAULT error number */ #include /* for copy_to_user */ /* The kernel will fill in the call table at dynamic load (insmod) */ extern void *sys_call_table[]; extern struct timeval xtime; /* prototypes */ asmlinkage long my_syscall(struct timeval *, struct timeval *); int init_module(void); void cleanup_module(void); /* My module system call to return xtime through a reference parameter. * Pretty much copied from sys_gettimeofday function in kernel/time.c */ asmlinkage long my_syscall(struct timeval *tv, struct timeval *tvk) { struct timeval ktv; printk(KERN_ALERT "my_syscall: entering.\n"); do_gettimeofday(&ktv); printk(KERN_ALERT "my_syscall: xtime.tv_sec: %ld xtime.tv_usec: %ld\n", xtime.tv_sec, xtime.tv_usec); printk(KERN_ALERT "my_syscall: ktv.tv_sec: %ld ktv.tv_usec: %ld\n", ktv.tv_sec, ktv.tv_usec); if (copy_to_user(tv, &xtime, sizeof(xtime))) return -EFAULT; if (copy_to_user(tvk, &ktv, sizeof(ktv))) return -EFAULT; printk(KERN_ALERT "my_syscall: leaving.\n"); return 0; } /* Original system call for NR_futex (240) in sys.c of src/linux/kernel/sys.c * The original call is sys_ni_syscall and returns an error number. */ asmlinkage long (*original_call_240) (void); /* Initialize the module at insmod - insert the new system calls */ int init_module(void) { printk(KERN_ALERT "syscall-xtimefun module loaded\n"); /* save the original syscall entry and insert our own entry */ original_call_240 = sys_call_table[__NR_futex]; sys_call_table[__NR_futex] = my_syscall; /* A non-zero return means init_module failed; module can't be loaded */ return 0; } /* Restore the preious system call at rmmod. * Check to see if someone else tried to replace our * system calls while we were loaded. */ void cleanup_module(void) { if (sys_call_table[__NR_futex] != my_syscall ) { printk(KERN_ALERT "syscall module entry has been corrupted\n"); } /* restore the original syscall entry */ sys_call_table[__NR_futex] = original_call_240; printk(KERN_ALERT "syscall-xtimefun module unloaded\n"); } MODULE_LICENSE("GPL");