2016-04-17 4 views
5

__NR_execveのシステムコールと混同しています。私はLinuxのシステムコールを学ぶとき。なぜexecveシステムコールは "/ bin/ls"ではなくargv引数なしで "/ bin/sh"を実行できますか?

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

次に機能execveはレジスタEAXEBXECXEDXに引数を置くことで、システムのカーネルに入るためにsyscall()を呼び出します:私はexecveを使用することを知って正しい方法は、このようなものです。しかし、それはまだ成功し、私は

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

を使用しかし、私は"/bin/ls""/bin/sh"を交換した場合、それはで失敗した場合:

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

"/bin/ls"が失敗しながら"/bin/sh"が十分なパラメータなしで正常に実行することができますなぜ私が疑問に思いますか?

+0

。 'execve'のmanページは、' argv'が引数文字列の配列であることを示しています。 'NULL'ポインターは配列への有効なポインターではありません。 ( 'env'には' NULL'を使用しないでください。 'execv'や' execvp'を使うか、 'char * p = NULL'へのポインタを渡してください) –

+0

配列は、渡されたときの最初の要素へのポインタです関数の引数は、NULLが確かにここで有効です。 – fluter

答えて

4

これは、カーネルの問題ではありません、カーネルは関係なく、argvのはexecveのfilename引数を実行するとenvpNULLかではありません、それはプログラム名にargv[0]ポイントということだけで、UNIXの慣例です。

あなたが見たのはちょうど正常です、何も間違っていません。 lsはGNUのcoreutilsの一部であり、coreutilsパッケージのすべてのプログラムがset_program_nameと呼んでいくつかの設定作業を行うので、ソースではargv[0]がNULLかどうかを確認し、そうであればabortを呼び出します。 一方で、/bin/shは明らかにcoreutilsに属していないプログラムであり、に対してチェックしていないので、問題なく実行されます。

ソースコードを参照してください。私は `NULL`が全く働いに依存しないと思います

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​​。それが助けてくれることをうれしく思います。 – fluter

+0

そして、ここにargvのない最小限の例があります:http://stackoverflow.com/a/42290873/895245 –

関連する問題