lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-ID: <4146316C00007745@ims3a.cp.tin.it>
Date: Thu, 16 Sep 2004 23:48:21 +0200
From: gerarra@....it
To: bugtraq@...urityfocus.com
Subject: FreeBSD kernel buffer overflow


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




Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ