Warum verzweigt sich Sudo vor der Ausführung des Prozesses?

1345
ssice

Diese Frage mag etwas dumm erscheinen, aber da in Unix-basierten Systemen das Abbild einer ausführbaren Datei in einem einzigen Schritt ersetzt wird und der derzeit ausgeführte Prozess im Funktionsaufruf execve(und Ableitungen) ersetzt wird, lautet die Frage:

Warum sudo fork()wird standardmäßig vor execvedem Ersetzungsvorgang vorgegangen?

Durch vorheriges Forking müssen zusätzliche Kernel-Elemente initialisiert werden, und obwohl Fork in einigen Unices ziemlich optimiert ist, gibt es noch einige unvermeidbare Elemente, die initialisiert werden müssen. Wenn fork()dies nicht standardmäßig der Fall ist, wird der PID-Bereich langsamer inkrementiert.

Wenn Sie neugierig sind, können Sie dieses Standardverhalten überprüfen, indem Sie einen Befehl wie z

sudo sleep 30 

Der aktuelle Code [ 1 ] ist etwas komplizierter zu befolgen, da seitdem viele Funktionen hinzugefügt wurden. aber in der Version von Apple gehostet [ 2 ] es ist ganz klar, was es tut.

#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 */ 

Ich arbeite derzeit mit der Sudo-Version 1.8.11p2, und der Schlafmodus wird entweder mit oder ohne -bSchalter erzeugt. Es scheint also, dass der aktuelle Code komplizierter wird.

Ich suche nach einer Antwort, die auch abdeckt, warum dies das Standardverhalten ist und welche Vorteile es uns bringen kann.

3

2 Antworten auf die Frage

2
BillThor

Der Grund für die Gabelung ist im Process modelAbschnitt der Manpage dokumentiert . Der relevante Inhalt ist:

Dieser zusätzliche Vorgang ermöglicht es beispielsweise, den Befehl auszusetzen und wieder aufzunehmen. Ohne dieses Kommando würde der Befehl in gewisser Weise eine "verwaiste Prozessgruppe" von POSIX sein und er würde keine Jobsteuerungssignale empfangen. Wenn das Richtlinien-Plugin keine close-Funktion definiert und kein pty erforderlich ist, führt sudo als Sonderfall den Befehl direkt aus, anstatt zunächst fork (2) aufzurufen. Das Plug-In für Sudoers-Richtlinien definiert nur dann eine close-Funktion, wenn die E / A-Protokollierung aktiviert ist, ein pty erforderlich ist oder die Optionen pam_session oder pam_setcred aktiviert sind. Beachten Sie, dass pam_session und pam_setcred auf Systemen, die PAM verwenden, standardmäßig aktiviert sind.

Warum konnte es keine Jobsteuerungssignale auswählen? Wenn ich 'bash' eingebe und in die gegabelte + execve'd neue Shell ein "exec sleep 10" schreibe, kann ich immer noch Ctrl. + Z von meiner übergeordneten Shell auswählen, da der Prozess ersetzt wurde, aber das übergeordnete Element immer noch vorhanden ist das Gleiche ist es nicht? Würde Waisen nicht passieren, wenn das übergeordnete Element (fork () == 0) beendet wird, bevor es seine untergeordneten Elemente abruft? ssice vor 9 Jahren 0
@ssice Ich denke, es geht weniger um den Umgang mit Signalen als in den anderen Fällen: close function, pty, pam_session und pam_setcred. "sudo" verwaist auf meinem System, und dies kann auf einigen Plattformen zu Problemen beim Weiterleiten von Signalen führen. BillThor vor 9 Jahren 0
2
grawity

Der PID-Speicherplatz unter Linux kann mit einem einfachen sysctl auf 2 22 erhöht werden . das ist wirklich kein problem ...

Die meisten Linux-Distributionen verwenden heutzutage PAM und sudowerden normalerweise auch mit PAM-Unterstützung kompiliert. Es wird unter anderem pam_open_session()aufgerufen, bevor Sie Ihr Programm ausführen, daher muss es auch pam_close_session()innerhalb desselben Prozesses aufgerufen werden, da Ihr Programm nicht weiß, dass es das tun muss (und dies wahrscheinlich nicht erlaubt ist ).