追加読書

追加読書

次の環境のプロセスがあります。

root@a-vm:/proc/1363# hexdump -C environ
00000000  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
0000016c

私はこのようなことを見たことがありません。environnull で終わるkey=valueペアが含まれると予想されるため、この出力はさまざまな主張に違反します。既知のカーネルバグを見ていますか?それともUnix / Linuxでこれを行うための合法的な方法はありますか? (…それではなぜ?カーネルがこういうわけではないことを許すのはなぜですか?)

(Linuxでは3.13.0 / Ubuntu Trusty)

(プロセスがいくつかの一時出力を正しい場所に書き込めない理由を特定しようとしましたが、この問題に遭遇しました。一時保存に特定のディレクトリを使用している必要があり、環境変数を設定してそのディレクトリに関する情報を受け取りました。TMP; しかし、私はTMP多くのnull値ではなく、非常に平凡に見えるパスを設定しており、完全に空の環境を見たことがありません。

ベストアンサー1

たわごとではありません。 Linuxにはこれを行うための合法的な方法がありますが、あなたの期待は間違っていました。

カーネルがプログラムの開始コードに渡した引数と環境文字列は、他のプログラムデータと同様に通常のアプリケーション空間仮想メモリに格納され、他のプログラムデータ変数と同様に変更できます。プログラムがこれを修正することは完全に合法的です。

(これはカーネルの提供と強制の観点からのものです。特定のプログラミング言語の標準が必ずしも同じことを言うわけではありません。しかし、カーネルに関する限り、これは読み取り可能なアプリケーション空間領域です。プログラムデータのための書き込み可能な仮想メモリ、カーネルは機械語コードをコンパイルしたプログラミング言語には興味がありません。

この/proc/${PID}/environファイルは、アプリケーション空間の仮想メモリのウィンドウに過ぎません。 Linuxはプロセスの実際の環境データを記憶せず、プロセスが開始された環境領域の開始アドレスと終了アドレスのみを記憶し、ファイルは/proc/${PID}/environ現在メモリ内のすべてを読み込みます。このファイルに ␀ で終わる文字列のリストが含まれるとは思わないでください。これは間違った期待です。

これらの文字列を含むメモリを変更するGNU Cライブラリ関数はありません。ただし、さまざまなプログラムにはこれを行う独自の機能があります。

たとえば、OpenSSHを考えてみましょう。 OpenSSHサーバーは、psパラメータベクトルの表示内容を変更して読み込みますsshd: JdeBP [priv]

OpenSSHサーバーには、LinuxのOpenBSDでBSD Cライブラリの機能をエミュレートするコードが含まれています。 OpenBSDは、コマンドによって報告されたプロセス引数ベクトルをsetproctitle()無視できるBSD Cライブラリ関数を呼び出します。psその呼び出しはsysctl()カーネルに新しい引数ベクトルを渡し、これをps使用して読み取ることができますsysctl()。 FreeBSDにも同様の機能があります。

説明したように、Linuxでは、カーネルは実際のパラメータと環境を覚えておらず、プロセスを開始したときに元々配置されたメモリ領域の開始アドレスと終了アドレスのみを記憶します。したがって、OpenSSHのLinuxポートには、setproctitle()上記のメモリ領域を上書きする互換性機能があります。

この互換性関数は、環境領域の合計サイズを計算します。そしてパラメータ領域とオーバーライドみんな新しいパラメータ文字列を使用してください。これは、通常の状況では、呼び出し元プログラムがsetproctitle()プロセスが元々持っていたパラメータデータセットよりも長いパラメータデータを書き込もうとするためです。 sshdこれを頻繁にしなさい。したがって、新しいパラメータがパラメータ領域の後ろの環境領域を上書きできるようにして、より長いパラメータ文字列のセットを収容できるより多くのスペースをプログラムに提供します。

大事なことも未使用部分を埋めてくださいパラメータ全体と環境データの元の長さを␀sで上書きする必要はありません。

あなたが見るのはこれの正確な結果です。システムでOpenSSHサーバープロセスを見つけたら、それを見つけることができます/proc/${PID}/environ

追加読書

  • setproctitle。 FreeBSD 11.0 マニュアル。
  • setproctitle。 OpenBSD マニュアル。
  • setproctitle()。 OpenSSHポータブルバージョン。
  • environ_read()。 fs/proc/base.fs/proc/base.fs/proc/base.fs/proc/base.fs/proc/base.fs/proc/base.fs Linuxカーネル。自由電子。

おすすめ記事