Fwd: FreeBSD kernel buffer overflow

Mike Tancsa mike at sentex.net
Fri Sep 17 21:09:28 PDT 2004


Can anyone provide more details about the posting below ?


>Mailing-List: contact bugtraq-help at securityfocus.com; run by ezmlm
>List-Id: <bugtraq.list-id.securityfocus.com>
>List-Post: <mailto:bugtraq at securityfocus.com>
>List-Help: <mailto:bugtraq-help at securityfocus.com>
>List-Unsubscribe: <mailto:bugtraq-unsubscribe at securityfocus.com>
>List-Subscribe: <mailto:bugtraq-subscribe at securityfocus.com>
>Delivered-To: mailing list bugtraq at securityfocus.com
>Delivered-To: moderator for bugtraq at securityfocus.com
>Date: Thu, 16 Sep 2004 23:48:21 +0200
>From: gerarra at tin.it
>Subject: FreeBSD kernel buffer overflow
>To: bugtraq at securityfocus.com
>X-Virus-Scanned: by amavisd-new at avscan1b
>
>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

--------------------------------------------------------------------
Mike Tancsa,                                      tel +1 519 651 3400
Sentex Communications,                            mike at sentex.net
Providing Internet since 1994                    www.sentex.net
Cambridge, Ontario Canada                         www.sentex.net/mike



More information about the freebsd-security mailing list