この質問は少しばかげているように見えるかもしれませんが、Unixベースのシステムでは、実行可能ファイルのイメージの置き換えは、関数呼び出しexecve
(および派生物)で、現在実行中のプロセスを置き換える単一のステップで行われるため、質問は:
置換プロセスをSudo
する前に、デフォルトでexecve
fork()
が実行されるのはなぜですか?
前にフォークすることにより、追加のカーネル要素を初期化する必要があります。フォークは一部のユニスで完全に最適化されていますが、初期化する必要のある避けられない要素がいくつかあります。 fork()
がデフォルトで発生しなかった場合、PIDスペースの増分は遅くなります。
興味がある場合は、次のようなコマンドを発行することで、このデフォルトの動作を調べることができます。
Sudo sleep 30
現在のコード[ 1 ]は、それ以降多くの機能が追加されているため、従うのが非常に複雑です。しかし、Apple [ 2 ]によってホストされているバージョンでは、それが何をするのかは非常に明確です。
#ifndef PROFILING
if ((Sudo_mode & MODE_BACKGROUND) && fork() > 0)
exit(0);
else
EXEC(safe_cmnd, NewArgv); /* run the command */
#else
/* Complicated code when profiling is enabled, but we don't care */
私は現在Sudoバージョン1.8.11p2を実行していますが、-b
スイッチの有無にかかわらず、どちらの方法でもスリープを生成するため、現在のコードはより複雑になっているようです。
なぜがこれがデフォルトの動作であり、それが私たちにもたらすことができる利点もカバーする答えを探しています。
LinuxのPIDスペースは2に上げることができます22 単純なsysctlを使用します。それは本当に問題ではありません...
最近のほとんどのLinuxディストリビューションはPAMを使用しており、Sudo
は通常PAMサポートも使用してコンパイルされています。特に、プログラムを実行する前にpam_open_session()
を呼び出すため、プログラムはそれを実行する必要があることを認識しないため、同じプロセス内からもpam_close_session()
を呼び出す必要があります(そしておそらくそうではないでしょう許可されたそれをするために)。
フォークの理由は、マニュアルページのProcess model
セクションに記載されています。関連するコンテンツは次のとおりです。
この追加のプロセスにより、たとえば、コマンドを一時停止および再開することができます。これがないと、コマンドはPOSIXで「孤立したプロセスグループ」と呼ばれるものになり、ジョブ制御シグナルを受信しません。特別な場合として、ポリシープラグインがclose関数を定義せず、ptyが必要ない場合、Sudoは最初にfork(2)を呼び出す代わりに、コマンドを直接実行します。 sudoersポリシープラグインは、I/Oロギングが有効になっている場合、ptyが必要な場合、またはpam_sessionまたはpam_setcredオプションが有効になっている場合にのみ、閉じる関数を定義します。 PAMを使用するシステムでは、pam_sessionとpam_setcredがデフォルトで有効になっていることに注意してください。