/* Woef Waf Waf - Toby the barking Kernel Module
 * (LINUX) NETRIC SECURITY 2003 @
 *  Netric [dot] org
 *
 *  written by sacrine
 *  sacrine@netric.org
 *
 * Intercept setuid,setreuid,setresuid SYS_CALL from
 * normal user.
 * !! This is a modified version of an earlier written LKM "suidshow.c" !!
 *    Credits are also for: CyberPsychotic from K.A.L.U.G.
 * I hacked in a setresuid function and some other changes.
 *
 *  compile:
 *  gcc -c toby.c -I/lib/modules/$(uname -r)/build/include
 *  then /sbin/insmod toby.o
 *
 *  If everything went right you'll get something like this
 *  in your /var/log/messages:
 *  Jan  7 12:23:25 voldemort kernel: Toby_sec 0.1 kernel module started [pid=766]
 */


#define MODULE
#define LINUX
#define __KERNEL__

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/dirent.h>
#include <linux/sched.h>
#include <linux/types.h>
#include <linux/slab.h>
#include <linux/fs.h>
#include <linux/tty.h>
#include <sys/syscall.h>

#define VERSION         "0.1"

int (*o_setuid)   (uid_t);                              // 23  SYS_setuid
int (*o_setreuid) (uid_t ruid, uid_t euid);             // 70  SYS_setreuid
int (*o_setresuid)(uid_t ruid, uid_t euid, uid_t suid); // 164 SYS_setresuid

extern void* sys_call_table[];

int toby_setuid(uid_t uid)
{
        uid_t o_uid;
        int it;

        if (current -> uid && ! uid)
        {
                printk("Warning: SETUID SYS_CALL tried\n"
                       "pid=%i current uid=(%i) -> uid=(%i)\n",
                      current->pid,
                     current->uid,
                    uid);
        o_uid=current->uid;
        it=(* o_setuid)(uid);
        if (o_uid && ! uid)
        {
                printk("%i\n",it);
        }
        console_print("You are not allowed to perform a SETUID SYS_CALL\n");
        return(0);
        }
}
int toby_setreuid(uid_t ruid, uid_t euid)
{
        uid_t o_uid;
        int it;

        if (current->uid && ! ruid || ! euid)
        {
                printk("Warning: SETEUID SYS_CALL tried\n"
                       "pid=%i current uid=(%i) -> ruid=(%i)\n",
                      current->pid,
                     current->uid,
                    ruid);
        o_uid=current->uid;
        it=(* o_setreuid)(ruid,euid);
        if (o_uid && ! ruid || ! euid)
        {
                printk("%i\n",it);
        }
        console_print("You are not allowed to perform a SETREUID SYS_CALL\n");
        return(0);
        }
}
int toby_setresuid(uid_t ruid, uid_t euid, uid_t suid)
{
        uid_t o_uid;
        int it;

        if (current->uid && ! ruid || ! suid || ! euid)
        {
                printk("Warning: SETRESUID SYS_CALL tried\n"
                       "pid=%i current uid=(%i) -> suid=(%i)\n",
                      current->pid,
                     current->uid,
                    suid);
        o_uid=current->uid;
        it=(* o_setresuid)(ruid,euid,suid);
        if (o_uid && ! ruid || ! suid || ! euid)
        {
                printk("%i\n",it);
        }
        console_print("You are not allowed to perform a SETRESUID SYS_CALL\n");
        return(0);
        }
}
int init_module(void)
{
        o_setuid=sys_call_table[SYS_setuid];
        sys_call_table[SYS_setuid]=toby_setuid;

        o_setreuid=sys_call_table[SYS_setreuid];
        sys_call_table[SYS_setreuid]=toby_setreuid;

        o_setresuid=sys_call_table[SYS_setresuid];
        sys_call_table[SYS_setresuid]=toby_setresuid;

        printk("Toby_sec %s kernel module started [pid=%i]\n"
                        ,VERSION
                        ,current->pid);
        return(0);
}
void cleanup_module(void)
{
        sys_call_table[SYS_setuid]=o_setuid;
        sys_call_table[SYS_setreuid]=o_setreuid;
        sys_call_table[SYS_setresuid]=o_setresuid;

        printk("Toby_sec %s kernel module ended   [pid=%i]\n"
                        ,VERSION
                        ,current->pid);
}


