|
(view this code in a separate window) /* * logsetuid kernel module. * * Log all attempts to run the setuid or setreuid * system calls, unless the user is root. * * To compile: * gcc -o logsetuid.o -c logsetuid.c * * Then copy logsetuid.o into one of the default * insmod directories, such as /lib/modules/misc. * * Load it into the running kernel with 'insmod logsetuid'. * * Copyright 2001, Bri Hatch * Released under the GPL. See COPYING file * for more information. */ #define __KERNEL__ #define MODULE #include <linux/config.h> #include <linux/module.h> #include <linux/version.h> #include <sys/syscall.h> #include <linux/sched.h> #include <linux/types.h> int (*real_setuid) (uid_t); int (*real_setreuid) (uid_t, uid_t); int new_setuid (uid_t); int new_setreuid (uid_t, uid_t); extern void *sys_call_table[]; int init_module() { /* Save a pointer to the old setuid functions */ real_setuid = sys_call_table[ SYS_setuid ]; real_setreuid = sys_call_table[ SYS_setreuid ]; /* point to our new setuid function in sys_call_table */ sys_call_table[ SYS_setuid ] = (void *)new_setuid; sys_call_table[ SYS_setreuid ] = (void *)new_setreuid; printk(KERN_INFO "logsetuid module installed\n"); return 0; } int cleanup_module() { /* reset the pointers back to the actual functions */ sys_call_table[ SYS_setuid ] = (void *)real_setuid; sys_call_table[ SYS_setreuid ] = (void *)real_setreuid; printk(KERN_INFO "logsetuid module uninstalled\n"); return 0; } /* The replacement functions */ int new_setuid(uid_t uid) { int status; /* no warnings if we're already root */ if ( ! current->uid || uid == current->uid ) return (*real_setuid)(uid); printk("logsetuid: uid:%d euid:%d dest_uid:%d pid:%d proc:%s ", current->uid, current->euid, uid, current->pid, current->comm); printk("status:%s\n", (status = (*real_setuid)(uid) ) ? "failed" : "succeeded" ); return status; } int new_setreuid(uid_t uid, uid_t euid) { int status; /* no warnings if we're already root */ if ( ! current->uid || (uid == current->uid && euid == current->euid) ) return (*real_setreuid)(uid,euid); printk("logsetreuid: uid:%d euid:%d dest_uid:%d dest_euid:%d " "pid:%d proc:%s ", current->uid, current->euid, uid, euid, current->pid, current->comm); printk("status:%s\n", (status = (*real_setreuid)(uid,euid)) ? "failed" : "succeeded"); return status; }
|