「root」ユーザーとして実行される親プロセスがあります。fork()
、execl()
およびそれ以降、setuid()/setgid()
子プロセスは別のオペレーティングシステムユーザー(例:user1)で始まります。
環境を印刷すると、user1でログインしたのとは異なり、ルート環境と同じであることがわかります(ルートとしてログインしたかのように)。なぜ?
子プロセスでuser1の環境を読み取る方法はありますか?
答え1
すべてのプロセスに親環境からコピーされた独自の環境。親がシェルなら概念がありますエクスポートできる変数この点を考慮する必要がありますが、直接取引する場合は適用されませんexec()
。このLOGNAME
変数は通常ログインシェルによって設定され、リセットされていない残りの値のみが表示されます。だからあなたははい子供の環境を見てください。一部のシステムでは親(または他のプロセス)環境に簡単にアクセスできませんが、Linuxではアクセスできます(制限の制限によって異なります)。渡す/proc
)
su
を試してみている効果を再現できますsu -
。後者はシェルログイン環境を初期化して(ほぼ確実に)リセットされ、LOGNAME
前者は何よりも変更されていません。
env
コマンドを使用することは、コマンドラインから新しいプロセスを開始するときにクリーンな環境を得るための1つの方法であり、execle()
同様の操作を実行する方法を知るには、システムのマニュアルを確認する必要があります。
答え2
次のコマンドを使用して、簡単にユーザーエクスペリエンスを確認できます。
su -l user_name -c "run_programm && env"
あるいは、env
その pid を使用して子プロセスを確認することもできます。
子プロセスpidが24112
次env
のように確認されたとします。
cat /proc/24112/environ
答え3
いくつかの情報:
- 環境変数を使用する
execle
か、サブアイテムに提供できます。execve
これを使用して、子プロセスに適していない親プロセスの環境変数を抑制し、子プロセスに追加の変数を提供できます。 - たとえば、 を使用して子の「ログインシェル」を起動できます
bash -l
。これにより、子孫などの環境がいっぱいになります。多くのシェル(bashを含む)の場合、バイナリ名の前にハイフンを追加すること(例-bash
:passargv[0]
)は同じ効果を持ちます。これらの違いの主な影響は、ログインシェルが実行されるか、/etc/profile
他のプロファイルシェルスクリプトを実行して多数の環境変数を設定することです。 - 認証とセッションの初期化にPAMを使用するサービスの場合、この
pam_env
モジュールは環境を適切に初期化する役割を果たします。これを使用するか、またはその動作をエミュレートするためにその設定を表示できます。
答え4
各プロセスには一連の環境変数があります(シェルexport SOMEVAR=value
などで設定できます)。これは子プロセスによって変更されることなく継承されます。これをリセットするには、を使用してextern char **environ;
渡された環境(参考資料を参照environ(7)
)を取得し、コピーされた変数値を含む新しい環境配列を使用またはexecle(3)
渡します。execve(3)
David Wheelerは、自分の本で何をすべきか、どのようにすべきかについていくつかのガイドラインを提供しています。「セキュアUnix/Linuxプログラミングガイド」