I am confused with the syscall of __NR_execve
. When I learn linux system call. The correct way that I know to use execve
is like this:
char *sc[2];
sc[0]="/bin/sh";
sc[1]= NULL;
execve(sc[0],sc,NULL);
Then the function execve
will call syscall()
to get into system kernel with putting the arguments on Registers EAX
, EBX
, ECX
and EDX
. However, It still succeed if I use
execve("/bin/sh",NULL,NULL);
But if I replace "/bin/sh"
with "/bin/ls"
,it fail with:
A NULL argv[0] was passed through an exec system call.
I wonder why "/bin/sh"
can be executed successfully without enough parameters while "/bin/ls"
fail?
This is not a kernel issues, kernel will run
filename
arg of execve regardless ofargv
andenvp
areNULL
or not, it is just a unix convention thatargv[0]
points to the program name.And what's you saw is just normal, nothing is wrong. Because
ls
is part of GNU's coreutils, and all programs in the coreutils package callset_program_name
to do some setup work, you can see in the source, it checks whetherargv[0]
if NULL, and it will callabort
when it is. On the other hand,/bin/sh
is apparently a program that does not belong to coreutils, and does not check againstargv[0]
, that's why it run without the problem.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