static char about[] = "spfx v2.1b by Justin Lesarge (nijen@mail.ru)\n"; /* note: this software is untested and may be unstable or unsafe. * The author makes no guarantee of it's stability or effectiveness. * * USE AT YOUR OWN RISK! * * spfx2 increases security by limiting the use of key system calls * to library functions. Although spfx2 does not prevent buffer-overflow * related crashes, it does make it very difficult to break security with * with a buffer-overflow attack, preventing most root compromises. * * this code may be freely distributed and modified, so long as credit * to the original author (Justin Lesarge) is left in tact. * * to load this module, use: cc -O0 -c spfx2.c -o ./spfx2.o insmod ./spfx2.o * to silence dmesg logging of rejected system calls, compile with -DNO_KMSG * for more stability, compile with -DSAFE * SAFE includes: filtering less calls and less thorough address checks * to terminate the source of blocked calls (recommended), compile with -DKILL * example with all extra options enabled: cc -O0 -DNO_KMSG -DSAFE -DKILL -c spfx2.c -o ./spfx2.o */ #define MODULE 1 #define __KERNEL__ 1 #include #include #include #include #include #include extern void *sys_call_table[]; static void *old_call_table[NR_syscalls]; #ifndef LIB_AND # define LIB_AND 0xC0000000 #endif #ifndef LIB_EQU # define LIB_EQU 0x40000000 #endif #ifndef EXE_AND # define EXE_AND 0xC0000000 #endif #ifndef EXE_EQU # define EXE_EQU 0x00000000 #endif int check_call(int nr,int i0,int i1) { int i[2] = {i0,i1}; if ((i[1]&LIB_AND)==LIB_EQU) do { #ifndef SAFE int n = 1024; do { if (!n--) break; if (copy_from_user(&i,(void *)i[0],sizeof(i))) break; } while ((i[1]&LIB_AND)==LIB_EQU); if ((i[1]&EXE_AND)!=EXE_EQU) break; #endif return(0); } while(0); #ifndef NO_KMSG printk("spfx2: syscall #%d requested from invalid source (%08lx).\n" " process=%d (%s), uid=%d, gid=%d" # ifdef KILL " -- terminating" # endif ".\n",nr,i[1],current->pid,current->comm,current->uid,current->gid); #endif return(-1); } static int (__handler__) (struct pt_regs r) { __asm__ __volatile__ ("pushf;pusha;"); if (check_call(r.orig_eax,r.ebp,r.eip)) { __asm__ __volatile__ ("popa;popf;"); #ifdef KILL __asm__ __volatile__ ("popl %%ebp;movl %0,%%eax;jmp *old_call_table(,%%eax,4);"::"i"(__NR_exit)); #endif return(-1); } __asm__ __volatile__ ("popa;popf;popl %ebp;jmp *old_call_table(,%eax,4);"); } int init_module() { int n; for(n=0;n