Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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?

like image 887
Arvin Hsu Avatar asked Apr 17 '16 07:04

Arvin Hsu


People also ask

What does execve system call return?

RETURN VALUES As the execve() function overlays the current process image with a new process image the successful call has no process to return to. If execve() does return to the calling process an error has occurred; the return value will be -1 and the global variable errno is set to indicate the error.

What is execve used for?

Execve () The execve function is mainly used to smear(overlay) a process running because of the call to fork(). This makes the program that is currently running by the process called it to get replaced with another new program, involving a newly initialized heap, stack, and other data segments.


1 Answers

This is not a kernel issue. The kernel will run with the filename arg of execve regardless of whether argv and envp are NULL or not. It is just a Unix convention that argv[0] points to the program name.

And what you saw is just normal, i.e. nothing is wrong. Because ls is part of GNU's coreutils, and all programs in the coreutils package call set_program_name to do some setup work. You can see this in the source: it checks whether argv[0] is NULL, and it will call abort when it is.

On the other hand, /bin/sh is apparently a program that does not belong to coreutils, and does not check against argv[0]. That's why it runs 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
like image 96
fluter Avatar answered Oct 16 '22 15:10

fluter