BugTraq
[HOTFIX] setsockopt kernel vulnerability Apr 26 2004 09:46AM
nolife (nolife sigsegv cc)


Thought i publish the code so it has more use than idling on a single box. It should patch against the latest bug in setsockopt without the need of a new kernel/reboot.

It logs process and uid if someone tries to exploit the system.

I've tested it against the public POC, seems to work fine.

It can be downloaded here: http://sigsegv.cc/setsockopt.c

Or copy/paste from here:

------------------------------------------------------------------------
---

/* setsockopt hotfix by nolife.

* gcc -c -O3 -fomit-frame-pointer setsockopt.c

This is a hotfix against the latest kernel vulnerability (integer

overflow in memory size calculation)

It protects against the POC and should protect against upcoming exploits.

*/

#include <linux/autoconf.h>

#ifdef CONFIG_SMP

#define __SMP__

#endif

#define MODULE

#define __KERNEL__

#include <linux/kernel.h>

#include <linux/module.h>

#include <linux/types.h>

#include <linux/errno.h>

#include <linux/sched.h>

#include <linux/mman.h>

#include <linux/in.h>

#include <linux/net.h>

#include <asm/unistd.h>

#include <asm/uaccess.h>

#include <sys/syscall.h>

#ifdef MODULE_LICENSE

MODULE_LICENSE("GPL");

#endif

#ifndef MCAST_MSFILTER // you probably do not even have multicast

support .....

#define MCAST_MSFILTER 48

#endif

#ifndef SYS_SOCKETCALL

#define SYS_SOCKETCALL 102

#endif

#ifndef SYS_SETSOCKOPT

#define SYS_SETSOCKOPT 14

#endif

#define AL(x) ((x) * sizeof(unsigned long))

static unsigned char nargs[18]={AL(0),AL(3),AL(3),AL(3),AL(2),AL(3),

AL(3),AL(3),AL(4),AL(4),AL(4),AL(6),

AL(6),AL(2),AL(5),AL(5),AL(3),AL(3)};

#undef AL

extern void *sys_call_table[];

const int optmem_max = sizeof(unsigned long)*(2*UIO_MAXIOV + 512);

static long (*old_socketcall)(int call, unsigned long *args); static long new_socketcall(int call,unsigned long *args)

{

unsigned long a[6];

unsigned long a0,a1;

if (call == SYS_SETSOCKOPT)

{

if (copy_from_user(a, args, nargs[call]))

return -EFAULT;

a0=a[0];

a1=a[1];

//printk("setsockopt called with optlen= %d by

%s\n",(int)a[4],current->comm);

if ((int)a[2] == MCAST_MSFILTER)

{

// Multicast option

if ((int)a[4] > optmem_max)

{

printk(KERN_ALERT "setsockopt exploit halted. abused by uid %d with

process %.32s\n",current->uid, current->comm);

return(-ENOBUFS);

}

}

}

return old_socketcall(call,args);

}

int init_module()

{

unsigned long flags;

save_flags(flags);

cli();

old_socketcall = sys_call_table[SYS_SOCKETCALL];

sys_call_table[SYS_SOCKETCALL] = new_socketcall;

restore_flags(flags);

printk(KERN_NOTICE "\"setsockopt\" hotfix loaded (c)nolife\n"); return 0;

}

void cleanup_module()

{

unsigned long flags;

save_flags(flags);

cli();

sys_call_table[SYS_SOCKETCALL] = old_socketcall;

printk(KERN_NOTICE "\"setsockopt\" hotfix unloaded\n"); restore_flags(flags);

}

------------------------------------------------------------------------
---best regards,

nolife ;)

[ reply ]


 

Privacy Statement
Copyright 2010, SecurityFocus