On Tue, 19 Oct 1999, Matt Chapman wrote: > On Sat, Oct 16, 1999 at 02:22:02PM +0100, Alan Cox wrote: > > > > I would certainly be interested in an example that caused this. > > #include <unistd.h> > #include <errno.h> > > #define BADPTR (char *)0x10 /* for example */ > > int main(int argc, char **argv, char **envp) > { > char *args[7]; > int i; > > args[0] = "su"; > for (i = 1; i < 6; i++) { > args[i] = BADPTR; > } > args[6] = NULL; > > execve("/bin/su", args, envp); > > printf("%s\n", strerror(errno)); > return 1; > } If you do not attempt to call su but instead another test program which just prints all its args and environment, it becomes pretty clear what is going on: % cat test.c #include <unistd.h> #include <errno.h> #define BADPTR (char *)0x01 /* for example */ int main(int argc, char **argv, char **envp) { char *args[7]; int i; for( i = 0; i < 6; ++i ) printf( "test: envp[%d]: >>>%s<<<\n", i, envp[i] ); args[0] = "t2"; for (i = 1; i < 6; i++) args[i] = BADPTR; args[3] = "smurf"; args[6] = NULL; execve("./t2", args, envp); return 1; } % cat t2.c #include <unistd.h> #include <errno.h> #include <stdio.h> int main(int argc, char **argv, char **envp) { int i; printf( "argc = %d\n", argc ); fflush( stdout ); for( i = 0; argv[i]; ++i ) { printf( "t2: argv[%d]: >>>%s<<<\n", i, argv[i] ); fflush( stdout ); /* flush it, in case we segfault... */ } for( i = 0; envp[i]; ++i ) { printf( "t2: envp[%d]: >>>%s<<<\n", i, envp[i] ); fflush( stdout ); } } % ./test test: envp[0]: >>>PWD=/Users/timof/c/test<<< test: envp[1]: >>>TMPDIR=/tmp/110<<< test: envp[2]: >>>XAUTHORITY=/usr/X11/lib/cookies/0000006E/cookies.be554794d91a8049<<< test: envp[3]: >>>WINDOWID=171966478<<< test: envp[4]: >>>PAGER=/usr/bin/less<<< test: envp[5]: >>>HZ=100<<< argc = 6 t2: argv[0]: >>>t2<<< t2: argv[1]: >>>smurf<<< t2: argv[2]: >>>PWD=/Users/timof/c/test<<< t2: argv[3]: >>>TMPDIR=/tmp/110<<< t2: argv[4]: >>>XAUTHORITY=/usr/X11/lib/cookies/0000006E/cookies.be554794d91a8049<<< t2: argv[5]: >>>WINDOWID=171966478<<< t2: envp[0]: >>>PAGER=/usr/bin/less<<< t2: envp[1]: >>>HZ=100<<< [snip] t2: envp[36]: >>>_=./test<<< t2: envp[37]: >>>OLDPWD=/Users/timof/tmp<<< t2: envp[38]: >>>./t2<<< t2: envp[39]: >>><<< t2: envp[40]: >>><<< t2: envp[41]: >>><<< It seems that the argc of the new process is based on the number of non-NULL entries in the argv passed to the execve call, but the loop in the kernel copying the strings to the stack skips over invalid pointers in argv without reliably indicating an error, and without putting anything (not even a NUL) on the stack, The ELF loader then interprets the first environment strings as args and creates a few invalid entries near the end of envp. Maybe these can cause a SIGSEGV (which I could not reproduce). Timo Felbinger -- Timo Felbinger <Timo.Felbingerat_private-potsdam.de> Quantum Physics Group <http://www.quantum.physik.uni-potsdam.de/TF> Institut fuer Physik Universitaet Potsdam, Germany
This archive was generated by hypermail 2b30 : Fri Apr 13 2001 - 15:08:08 PDT