Why does the execve system call launch "/ bin / sh" without any argv arguments, but not "/ bin / ls"?

I am confused about syscall __NR_execve . When I recognize the linux system call. The correct way to use execve as follows:

 char *sc[2]; sc[0]="/bin/sh"; sc[1]= NULL; execve(sc[0],sc,NULL); 

The execve function then calls syscall() to get into the system kernel by placing the arguments in the EAX , EBX , ECX and EDX ECX . However, this still works if I use

 execve("/bin/sh",NULL,NULL); 

But if I replaced "/bin/sh" with "/bin/ls" , the failure:

 A NULL argv[0] was passed through an exec system call. 

I wonder why "/bin/sh" can be successfully executed without sufficient parameters, while "/bin/ls" does not work?

+6
source share
1 answer

This is not a kernel problem, the kernel will run filename arg execve regardless of argv and envp are NULL or not, it's just a unix convention that argv[0] points to the program name.

And what you saw is just normal, nothing happened. Since ls is part of GNU coreutils, and all programs in the coreutils package call set_program_name to perform some configuration steps, you can see in the source that it checks if argv[0] is NULL, and it will call abort when it is. On the other hand, /bin/sh apparently a program that does not belong to coreutils, and does not check it against argv[0] , so it works without problems.

Refer to the source code:

http://git.savannah.gnu.org/cgit/coreutils.git/tree/src/ls.c#n1285

http://git.savannah.gnu.org/cgit/gnulib.git/tree/lib/progname.c#n51

+5
source

All Articles