[12261] in bugtraq
Re: execve bug linux-2.2.12
daemon@ATHENA.MIT.EDU (Perly)
Mon Oct 18 13:10:45 1999
Mime-Version: 1.0
Content-Type: TEXT/PLAIN; charset=US-ASCII
Message-Id: <Pine.GSO.4.10.9910152156350.8709-100000@typhoon.xnet.com>
Date: Fri, 15 Oct 1999 22:07:22 -0500
Reply-To: Perly <perly@XNET.COM>
From: Perly <perly@XNET.COM>
X-To: ben@VALINUX.COM
To: BUGTRAQ@SECURITYFOCUS.COM
In-Reply-To: <199910160007.RAA04857@trill.valinux.com>
On Fri, 15 Oct 1999 ben@VALINUX.COM wrote:
> While doing some debugging, I discovered a really nasty stack smash
> bug in linux-2.2.12. The I haven't checked previous versions of the
> 2.2 kernel but bug appears to be fixed in linux-2.2.13pre17.
>
> If I am reading this correctly, the implications of this bug could be
> very dire. It may be possible to easily obtain root privilege on any
> box running this kernel.
>
> Basically the problem is that the execve system call checks that argv
> is a valid pointer but it doesn't check that all of the pointers in
> argv array are valid pointers. If you pass bad pointers into the
> execve system call you can corrupt the processes stack before it
> returns to user space. Then when the kernel hands off the process to
> the elf loader code and which begins to setup the processes it can be
> made to execute some malicious code in place of the program's main
> function.
>
> This is particularly scary because all of this occurs BEFORE the
> program begins executing its main function and AFTER the program
> returns to user space with privilege. Therefore no matter how well
> audited the program may be it can be used as to gain privilege.
>
> The thing that tipped me off to the problem was that a program that I
> exec'd was getting killed with SIGSEGV in __libc_start_main before my
> main function began running.
>
> -ben
>
I don't know about kernel 2.2.12 but 2.2.5-15 seems to be unaffected. As you
probably know, sys_execve calls do_execve after it does some checking, and
do_execve counts the number of arguments, etc., using the count()
function.
The count function does the following (see /usr/src/linux/fs/exec.c):
...
/* snip */
error = get_user(p,argv);
if (error)
return error;
if (!p)
break;
/* snip */
...
I wrote a simple program to test this thing:
...
#include <stdio.h>
int main()
{
char *prog[]={"/bin/sh", "sh"};
execve(prog[0], prog[1], (char *)0x0103, NULL);
return(0);
}
...
When i ran it nothing happened, not even a segfault. I did an strace, and
the interesting part was:
...
execve("/bin/sh", [umovestr: Input/output error
0x6873]ptrace: umoven: Input/output error
, [/* 0 vars */]) = -1 EFAULT (Bad address)
...
There you go, EFAULT, a bad address.
Therefore, I don't think that there is anything to worry about.
-------------------------------------------------------------------------------
-= Perly < perly@xnet.com > =- C maniac & BOFH
int main() { return main(); }