Topic: Buffer Overflow in FreeBSD Versions: All the versions of FreeBSD are broken (4.x, 5.x, 6.0) Arch: x86 Date: 16/09/2004 All discussion refers to CURRENT-6.0, for other versions some things could change (btw bugged). Discussion involves a lot of arch x32 dependant mechanisms, so, in some points, could sound a little bit dark. A buffer overflow has been found in i386/i386/trap.c syscall() function of FreeBSD official source tree. In order to rule syscalls mechanism, the 'particular' interrupt 128 (0x80) is provided in the IDT vector. To serve this interrupt, i386/i386/exception.s int0x80_syscall() function is done and, in the end, it calls syscall(). syscall() is responsible for loading arguments from a syscall and copying them in a kspace pointer in order to accessing them. The code to do that is the following: void syscall(frame) struct trapframe frame; { caddr_t params; struct sysent *callp; struct thread *td = curthread; struct proc *p = td->td_proc; register_t orig_tf_eflags; u_int sticks; int error; int narg; int args[8]; u_int code; ... narg = callp->sy_narg & SYF_ARGMASK; (<- you can see it's the only one check) if (params != NULL && narg != 0) error = copyin(params, (caddr_t)args, (u_int)(narg * sizeof(int))); else error = 0; ... and: > grep SYF_ARGMASK /usr/src/sys/sys/sysent.h #define SYF_ARGMASK 0x0000FFFF It's obvious that the amount of selectable memory is beyond the (8 * sizeof(int)) limit of args array, so it would overwrite the saved eip by syscall() (it's invoked through a call) or making an interesting pointer corruption overwriting struct proc *p . It's exploitable, but the only one way I discovered is to link a new syscall to the sysent array and to do this you need to be root; I've no time to work on this vulnerability, but i think another way could be found. However it could give serious problems (e.g. kernel crashes). A good patch could be a dinamyc memory allocation for args, but it's not a good solution in order to mantain a well performanced system; another one could be a strongest check, but it's not a good solution in order to set a good flexibility. You would get an attach containing proof of concept code (4.x, 5.x/6.0 versions). greetings rookie P.S: in order to try the code, compile and link module to the kernel, later do 'make test' and start ./poc