Bugtraq mailing list archives

Re: execve bug linux-2.2.12


From: perly () XNET COM (Perly)
Date: Fri, 15 Oct 1999 22:07:22 -0500


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(); }


Current thread: