it-swarm.com.de

Warum benötigt Bashs Quelle das Ausführungsbit nicht?

Mit Bashs source ist es möglich, ein Skript ohne gesetztes Ausführungsbit auszuführen. Dies ist dokumentiertes und erwartetes Verhalten, aber ist dies nicht gegen die Verwendung eines Ausführungsbits?

Ich weiß, dass source keine Unterschale erstellt.

60
Motte001

Bash ist Dolmetscher; es akzeptiert Eingaben und macht, was es will. Das ausführbare Bit muss nicht beachtet werden. Tatsächlich ist Bash portabel und kann auf Betriebssystemen und Dateisystemen ausgeführt werden, die kein Konzept für ein ausführbares Bit haben.

Was sich um das ausführbare Bit kümmert, ist der Betriebssystemkern. Wenn der Linux-Kernel beispielsweise ein exec ausführt, prüft er, ob das Dateisystem nicht mit einer noexec -Option gemountet ist, prüft das ausführbare Bit der Programmdatei und erzwingt alle von auferlegten Anforderungen Sicherheitsmodule (wie SELinux oder AppArmor).

Beachten Sie, dass das ausführbare Bit eine eher diskretionäre Art der Steuerung ist. Auf einem Linux x86-64-System können Sie beispielsweise die Überprüfung des ausführbaren Bits durch den Kernel umgehen, indem Sie explizit /lib/x86_64-linux-gnu/ld-linux-x86-64.so.2 Als Interpreter aufrufen :

cp /bin/ls /tmp/
chmod -x /tmp/ls
/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2 /tmp/ls

Dies ist etwas analog zur Beschaffung von Bash-Quellcode in Bash, außer dass ld.so Der Interpreter ist und der Code, den er ausführt, Maschinencode im ELF-Format ist.

38
200_success

source oder das Äquivalent aber Standard Punkt . Führen Sie das Skript nicht aus, sondern lesen Sie die Befehle aus der Skriptdatei und führen Sie sie dann Zeile für Zeile in der aktuellen Shell-Umgebung aus.

Es gibt nichts gegen die Verwendung des Ausführungsbits, da die Shell nur die Leseberechtigung benötigt, um den Inhalt der Datei zu lesen.

Das Ausführungsbit wird nur benötigt, wenn Sie das Skript ausführen . Hier wird die Shell fork() einen neuen Prozess ausführen und dann die Funktion execve() verwenden, um ein neues Prozessabbild aus dem Skript zu erstellen, das eine reguläre, ausführbare Datei sein muss.

57
cuonglm

Das ausführbare Bit (im Gegensatz zu den anderen) in Nonsetuid- und Nonsetguid-Dateien ist kein großer Sicherheitsmechanismus. Alles, was Sie lesen können, können Sie indirekt ausführen, und Linux lässt Sie indirekt alles lesen, was Sie ausführen können, aber nicht direkt lesen (dies sollte ausreichen, um eine Lücke im Konzept von nicht gesetztem (g) uid x-bit als a zu schlagen Sicherheitsmaßnahme).

Es ist eher eine bequeme Sache: Lassen Sie das System es direkt für mich ausführen, wenn das Bit gesetzt ist, andernfalls muss ich es indirekt tun (bash the_script; oder einige Hacken, um das Speicherabbild einer ausführbaren Datei ohne Leseberechtigung zu erhalten ).

Sie können es bequem einstellen, wenn Sie beabsichtigen, Ihr Insourcable sowohl in der Quelle als auch auszuführen.

Anscheinend teilen jedoch viele Implementierer von gemeinsam genutzten Bibliotheken Ihr Denken, und folglich erfordern viele Systeme, dass gemeinsam genutzte Bibliotheken, die im Wesentlichen das native Äquivalent von Shell-Insourcables sind, als ausführbar markiert werden, um verwendbar zu sein. Siehe Warum sind gemeinsam genutzte Bibliotheken ausführbar? .

20
PSkocik

Das ist eine gute Frage! Unix verwendet das ausführbare Bit, um zwischen Programmen und Daten zu unterscheiden. Das Betriebssystem benötigt das Ausführungsbit nicht, da ein Sourcing-Skript nicht zur Ausführung als neuer Prozess an das Betriebssystem übergeben wird. Die Shell behandelt ein Sourcing-Skript jedoch als Programm und sieht in $PATH für die Datei, die Sie beschaffen möchten. Die Shell selbst hätte möglicherweise eine Ausführungsberechtigung für Quelldateien benötigen können. aber das tat es nicht.

Die Frage muss längst aufgetaucht sein. Das Design der Bourne Shell war das Ergebnis von "eine lange Abfolge von Modifikationen, Dialogen, Diskussionen" unter den Bewohnern von Bell Labs, und viele Designentscheidungen wurden von S.R. Bourne und andere im Laufe der Jahre. Leider fand mein kurzer Blick keine Diskussion über die Quellfunktion (zu meiner Verteidigung ist es schwierig, danach zu googeln). Was ich gefunden habe ist, dass das "." Befehl erscheint nicht in diese frühe Einführung in der Shell von Bourne selbst, aber er ist in der reiferen Version 7 Version vorhanden.

Fehlende Autorität, hier ist meine eigene Interpretation:

  1. Das . Befehl, auch bekannt als source, enthält tatsächlich Text (wie #include im C-Präprozessor) in den Quellcode des ausführenden Skripts oder der interaktiven Sitzung. Daher wird die enthaltene Datei wohl nicht "ausgeführt".

  2. Die Unix-Philosophie war es immer, den Programmierern genug Seil zu geben, um sich aufzuhängen. Zu viel Händchenhalten und willkürliche Einschränkungen stören nur. Es ist erst vor relativ kurzer Zeit, dass einige Distributionen rm -r / weigere dich zu tun was du fragst. (Dieser Befehl weist rm an, alles auf Ihrem Computer zu löschen. Versuchen Sie es nicht als root! Or. En besser noch gar nicht.) Also vielleicht Bourne überhaupt. Ich habe gerade entschieden, dass Sie beim Versuch, eine Datei zu erstellen, davon ausgehen müssen, dass Sie wissen, was Sie tun. Das vermeidet auch unnötige Arbeit und Zyklen waren damals sehr wichtig.

9
alexis

Für das Betriebssystem besteht eine Datei mit Shell-Skript nur aus Daten. Wenn Sie den Namen einer solchen Datendatei an den Befehl source übergeben oder ihn in der Befehlszeile an einen Aufruf der Bash-Shell übergeben, sieht das Betriebssystem nur eine Zeichenfolge, die zufällig mit dem Namen von a übereinstimmt Datei mit Daten.

Wie wäre das Ausführungsbit in diesem Fall überhaupt relevant?

4
Stephen M. Webb

Die Unterscheidung ist wichtig, da Sie möglicherweise eine Datei mit Shell-Befehlen haben, die als ausführbare Datei nicht nützlich ist, aber nur dann nützlich ist, wenn sie bezogen wird. Für diese Datei können Sie das Ausführungsbit deaktivieren, und es wird nur dann explizit darauf zugegriffen, wenn dies explizit in einem Quellbefehl angegeben ist. Der Grund für so etwas ist, dass es Nebenwirkungen auf die Shell hat, von der aus es ausgeführt wird. Für ein bestimmtes Beispiel habe ich ein Skript namens fix_path, das den Pfad betrachtet und ändert.

3
MAP

Nur für den Fall, dass jemand an weiteren Studien und/oder Erläuterungen interessiert ist: In einer vor einiger Zeit implementierten nahezu POSIX-kompatiblen Shell sind die internen Funktionen der Funktionen 'exec_program ()' und 'builtin_source ()' sehr beispielhaft. In diesen Funktionen sehen Sie genau, was der Unterschied zwischen ihnen ist:

https://github.com/rsenn/shish/blob/master/src/builtin/builtin_source.c

https://github.com/rsenn/shish/blob/master/src/exec/exec_program.c

grundsätzlich kann Sourcing als die Shell angesehen werden, die ihren internen Dateideskriptor vorübergehend umleitet, von wo aus sie das Shell-Skript analysiert (das Terminal im interaktiven Modus). Daher ist es anderen Umleitungen wie <input_file.txt und >>append_to_something.list sehr ähnlich, und diese müssen nur Dateien öffnen und schließen.

die Ausführung wird also vom Systemaufruf execve() behandelt, für den das Ausführungsbit obligatorisch ist.

Ich erinnere mich, dass ich einige Systeme gesehen habe, die die Ausführung von ELF/a.out-Binärdateien ermöglichen, jedoch über die Ausführung von "/lib/ld-dynamic-linker.so" und mit dem Binärprogramm (ohne Exec-Bit) als erstes Argument. Ich glaube, das war auf einigen DEC Alpha- oder VAX-Maschinen (Könnte es SCO Unix?) Gewesen sein.

1
rsenn