サーバーから exec をフォークする必要があります。vfork()
サーバーのメモリ フット プリントが大きいため、 /linuxを使用する予定clone()
です。stdin
/ stdout
/のパイプも開く必要がありstderr
ます。clone()
これは/で許可されていvfork()
ますか?
2 に答える
標準から:
[..] によって作成されたプロセスが、 からの戻り値を格納するために使用される
vfork()
型の変数以外のデータを変更した場合、または が呼び出された関数から戻った場合、または呼び出しが成功する前に他の関数を呼び出した場合、動作は未定義です。関数ファミリーの1 つ。pid_t
vfork()
vfork()
_exit()
exec
setuid
orのような関数を呼び出す際の問題pipe
は、親プロセスと子プロセスの間で共有されるアドレス空間のメモリに影響を与える可能性があることです。の前に何かをする必要がある場合exec
、最善の方法は、必要なことをすべて実行する小さな shim プロセスを作成exec
し、最終的な子プロセス (おそらく を介して提供される引数argv
) に s することです。
shim.c
======
enum {
/* initial arguments */
ARGV_FILE = 5, ARGV_ARGS
};
int main(int argc, char *argv[]) {
/* consume instructions from argv */
/* setuid, pipe() etc. */
return execvp(argv[ARGV_FILE], argv + ARGV_ARGS);
}
clone()
代わりに、CLONE_VFORK|CLONE_VM
フラグを使用します。詳細については、 man2cloneを参照してください。
が設定されていないためCLONE_FILES
、子プロセスには独自のファイル記述子があり、親にまったく影響を与えることなく標準記述子を閉じたり開いたりできます。
複製されたプロセスは別個のプロセスであるため、独自のユーザーIDとグループIDがあり、およびを介してそれらを設定しますsetresgid()
(setresuid()
おそらく、追加のグループを呼び出すsetgroups()
か、initgroups()
最初に設定します。詳細については、 man 2 setresuid、man 2 setgroups、およびman 3initgroupsを参照してください)。 )親にはまったく影響しません。
CLONE_VFORK|CLONE_VM
フラグは、これがのように動作する必要があることを意味しclone()
、vfork()
子プロセスは呼び出しまで親プロセスと同じメモリ空間で実行されexecve()
ます。
このアプローチは、中間実行可能ファイルを使用する際の遅延を回避します(これは非常に重要です)が、このアプローチは完全にLinux固有です。