|
|
(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;
}
|