2016-04-17 4 views
5

Ich bin verwirrt mit dem Syscall von __NR_execve. Wenn ich Linux-Systemanruf lerne. Die richtige Art und Weise, die ich kenne execve zu verwenden, ist wie folgt:Warum kann der Execve-Systemaufruf "/ bin/sh" ohne argv-Argumente, aber nicht "/ bin/ls" ausführen?

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

Dann ist die Funktion execvesyscall() nennen mit setzt die Argumente auf Register in Systemkern erhalten EAX, EBX, ECX und EDX. Es ist noch jedoch erfolgreich sein, wenn ich

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

verwenden Aber wenn ich "/bin/sh" mit "/bin/ls" ersetzen, es nicht mit:

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

Ich frage mich, warum "/bin/sh" erfolgreich ohne genügend Parameter während "/bin/ls" nicht ausgeführt werden?

+0

Ich würde nicht darauf verlassen, 'NULL' überhaupt dort zu arbeiten; die 'execve'-man-Seite sagt, dass das' argv' ein Array von Argument-Strings ist; Ein 'NULL'-Zeiger ist kein gültiger Zeiger auf ein Array. (Auch die Verwendung von 'NULL' für' env' sieht nicht gut aus, sondern 'execv' oder' execvp' oder ein Zeiger auf 'char * p = NULL'.) –

+0

Arrays sind Zeiger auf ihr erstes Element, wenn sie als übergeben werden Funktionen Argumente, so NULL ist hier sicherlich gültig. – fluter

Antwort

4

Dies ist kein Kernel-Probleme, Kernel filename arg von execve unabhängig von argv und envp sind NULL oder nicht ausgeführt wird, ist es nur eine Unix-Konvention, dass argv[0] Punkte auf den Programmnamen.

Und was Sie gesehen haben, ist nur normal, nichts ist falsch. Da ls Teil von GNUs Coreutils ist und alle Programme im Paket coreutils set_program_name aufrufen, um einige Setup-Arbeiten durchzuführen, können Sie in der Quelle sehen, ob argv[0] if NULL ist, und es wird abort aufgerufen, wenn dies der Fall ist. Auf der anderen Seite, /bin/sh ist offenbar ein Programm, das nicht zu Coreutils gehört, und nicht gegen argv[0], weshalb es ohne das Problem läuft.

Siehe Quelltext:

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

+0

@ArvinX. froh zu wissen, dass es hilft. – fluter

+0

Und hier ist ein minimales Beispiel ohne argv: http://stackoverflow.com/a/42290873/895245 –

Verwandte Themen