Dies ist kein Unsinn, es gibt unter Linux einen legitimen Weg, dies zu erreichen, und Ihre Erwartungen sind falsch.
Die Argument- und Umgebungszeichenfolgen, die vom Kernel an den Startcode eines Programms übergeben werden, werden wie alle anderen Programmdaten im normalen virtuellen Speicher des Anwendungsbereichs gespeichert. und wie alle anderen Programmdatenvariablen können sie geändert werden. Es ist durchaus legitim, dass Programme sie ändern.
(Beachten Sie, dass dies unter dem Gesichtspunkt erfolgt, was der Kernel bereitstellt und erzwingt. Was die Standards für bestimmte Programmiersprachen möglicherweise aussagen, ist nicht unbedingt dasselbe. Was den Kernel betrifft, ist dies nur ein Bereich des Anwendungsbereichs virtueller Speicher für Programmdaten, die lesbar und beschreibbar sind. Dem Kernel ist es egal, aus welcher Programmiersprache Sie Ihren Maschinencode kompiliert haben.)
Die /proc/${PID}/environDatei ist nur ein Fenster zu diesem virtuellen Speicher im Anwendungsbereich. Anstatt sich an die tatsächlichen Umgebungsdaten des Prozesses zu erinnern, merkt sich Linux nur die Start- und Endadressen des Umgebungsbereichs, mit dem der Prozess gestartet wurde, und die /proc/${PID}/environDatei liest nur das aus, was sich gerade in diesem Speicher befindet. Sie sollten nicht erwarten, dass diese Datei eine Liste von ␀-terminierten Zeichenfolgen enthält. Das ist eine falsche Erwartung.
Es gibt keine GNU C-Bibliotheksfunktion zum Ändern des Speichers, der diese Zeichenfolgen enthält. Dafür haben verschiedene Programme ihre eigenen Funktionen.
Betrachten Sie als Beispiel OpenSSH. Der OpenSSH-Server ändert, was psfür seinen Argumentvektor angezeigt wird, um Dinge wie zu lesen sshd: JdeBP [priv].
Der OpenSSH-Server enthält Code, der versucht, unter Linux nachzuahmen, was er mit der BSD C-Bibliothek unter OpenBSD tun kann. Unter OpenBSD gibt es eine BSD C-Bibliotheksfunktion mit dem Namen setproctitle(), die den vom psBefehl angegebenen Prozessargumentvektor neu schreibt . Es wird aufgerufen sysctl(), einen neuen Argumentvektor an den Kernel zu übergeben, der psmit auslesen kann sysctl(). FreeBSD hat eine ähnliche Funktion.
Unter Linux erinnert sich der Kernel, wie erläutert, nicht an tatsächliche Argumente und Umgebungen, sondern lediglich an die Start- und Endadressen der Speicherbereiche, in denen er sie beim Starten des Prozesses ursprünglich platziert hat. Der Linux-Port von OpenSSH verfügt also über eine Kompatibilitätsfunktion setproctitle(), die stattdessen den oben genannten Speicherbereich überschreibt.
Diese Kompatibilitätsfunktion berechnet die Gesamtgröße des Umgebungsbereichs und des Argumentbereichs und überschreibt alles mit der neuen Argumentzeichenfolge. Dies geschieht, weil Programme, die aufrufen setproctitle(), im Normalfall einen längeren Satz von Argumentdaten schreiben möchten als ursprünglich. sshdoft tut. Auf diese Weise können die neuen Argumente den Umgebungsbereich überschreiben, der dem Argumentbereich folgt, und den Programmen mehr Platz für längere Sätze von Argumentzeichenfolgen geben.
Wichtig ist auch , dass der nicht verwendete Teil des Bereichs , den es nicht zum Überschreiben benötigt hat, auf die ursprüngliche Länge der gesamten Argument- und Umgebungsdaten mit ␀s aufgefüllt wird.
Und was Sie sehen, ist das genaue Ergebnis davon. Wenn Sie einen OpenSSH-Serverprozess auf Ihrem System finden, werden Sie feststellen, dass auch dieser viele ␀s enthält /proc/${PID}/environ.
Weiterführende Literatur