From owner-freebsd-hackers@FreeBSD.ORG Thu Sep 16 21:56:13 2004 Return-Path: Delivered-To: freebsd-hackers@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 8862016A4CE for ; Thu, 16 Sep 2004 21:56:13 +0000 (GMT) Received: from vsmtp2.tin.it (vsmtp2alice.tin.it [212.216.176.142]) by mx1.FreeBSD.org (Postfix) with ESMTP id 139BB43D2F for ; Thu, 16 Sep 2004 21:56:13 +0000 (GMT) (envelope-from gerarra@tin.it) Received: from ims3a.cp.tin.it (192.168.70.103) by vsmtp2.tin.it (7.0.027) id 41499A75000309BE for freebsd-hackers@freebsd.org; Thu, 16 Sep 2004 23:56:09 +0200 Received: from [192.168.70.227] by ims3a.cp.tin.it with HTTP; Thu, 16 Sep 2004 23:56:07 +0200 Date: Thu, 16 Sep 2004 23:56:07 +0200 Message-ID: <4146316C00007764@ims3a.cp.tin.it> From: gerarra@tin.it To: freebsd-hackers@freebsd.org MIME-Version: 1.0 Content-Type: text/plain; charset="ISO-8859-15" Content-Transfer-Encoding: quoted-printable Subject: FreeBSD kernel buffer overflow X-BeenThere: freebsd-hackers@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list List-Id: Technical Discussions relating to FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 16 Sep 2004 21:56:13 -0000 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 coul= d 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_syscal= l() 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 =3D curthread; struct proc *p =3D td->td_proc; register_t orig_tf_eflags; u_int sticks; int error; int narg; int args[8]; u_int code; ... narg =3D callp->sy_narg & SYF_ARGMASK; (<- you can see it's the only on= e check) if (params !=3D NULL && narg !=3D 0) error =3D copyin(params, (caddr_t)args, (u_int)(narg * sizeof(int))); else error =3D 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 * size= of(int)) limit of args array, so it would overwrite the saved eip by syscall() (it's invoke= d 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 sysc= all to the sysent array and to do this you need to be root; I've no time to work on this vu= lnerability, but i think another way could be found. However it could give serious pro= blems (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 st= rongest check, but it's not a good solution in order to set a good flexibility. You can get proof of concept code in http://www.gufi.org/~rookie/poc.tar.= gz (all versions). greetings rookie P.S: in order to try the bug before make and link kld, later do 'make tes= t' and start ./poc exe