[12267] in bugtraq
Re: execve bug linux-2.2.12
daemon@ATHENA.MIT.EDU (security@XIRR.COM)
Mon Oct 18 14:42:36 1999
Message-Id: <19991016221319.5559.qmail@securityfocus.com>
Date: Sat, 16 Oct 1999 22:13:19 -0000
Reply-To: security@XIRR.COM
From: security@XIRR.COM
X-To: bugtraq@securityfocus.com
To: BUGTRAQ@SECURITYFOCUS.COM
In-Reply-To: <199910160007.RAA04857@trill.valinux.com>
Caveat: I am running linux-2.2.12ow6 which contains
many security fixes, yet I believe my comments are still
valid. Also I am not a kernel guru.
> 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.
The kernel copies each argv[i] into a contiguous chunk
of the (soon to be) stack. Thus it must dereference each
argv[i]. Check out linux/fs/exec.c line 261 for an almost
explicit dereference of argv[i] (memcpy(str,argv+i) except
kernel to user space version).
This is confirmed by a small test program:
#include "nolibc.h"
main(int argc, char** argv,char **envp) {
int i;
char buf[32];
argv[1]=2;
i=execve("/bin/sh",argv,envp);
/* we should never reach this point, but print
out errno in hexadecimal */
i=htonl(i);
i=itoh(&i,buf);
buf[i]='\n';
write(1,buf,i+1);
}
This program does not run /bin/sh but istead prints out the
message 0000000e representing errno=14, EFAULT.
This means the kernel got a segfault while copying the
argv[i]'s to the stack, and thus failed the syscall.
This program is linked with
'gcc -O -fno-builtin -nostdlib test.c'
nolibc.h is ugly but available by request under GPL. It
defines ntohl,itoh,write,execve, and _start.
Note execve, htonl, itoh, and write are macros. Execve/write
are direct system calls. (itoh converts 4 bytes to 8byte
hex representation and returns 8, htonl byte swaps so
the bytes come out in the right order).
> 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.
I'm not really sure if this is a widespread problem, but
ANYTIME libc gets hosed (malloc(-1) for example) gdb reports
the problem occuring in a function called from
__libc_start_main and does not ever mention main.
I'll study this a wee bit more, since the references I'm
using for the startup state don't seem to jive with my
experience. (Namely I never see an array of pointers
being setup in the docs, and my programs definately
do not do so, yet they function and dereference argv
as if it were an array of pointers).
Another remark: If I misunderstood the bug (like argv[1]=2
obviously is not valid, and is not what you meant) please
let me know.