echo 'main(){}' | gcc -xc - -o /dev/stdout | ???
Gibt es eine Möglichkeit, die Ausgabebinärdatei auf einem Unix-ähnlichen System auszuführen?
BEARBEITEN: Ich brauchte es, um die Ausgabe von g ++ in einer Sandbox-Umgebung auszuführen, in der ich keine Datei schreiben kann (nichts Bösartiges, wie ich verspreche).
shell
executable
stdout
Alex B
quelle
quelle
csh
.Antworten:
Ich glaube nicht, dass das möglich ist. Der Systemaufruf exec (2) erfordert immer einen Dateinamen oder einen absoluten Pfad (der Dateiname ist immer a
char*
).posix_spawn
hat auch ähnliche Anforderungen für einen Dateinamen.Das Nächste, was Sie tun können, ist, die Ausgabe in eine Named Pipe umzuleiten und die Ausführung über die Pipe zu versuchen. Das kann funktionieren, obwohl die Shell möglicherweise die Ausführung von Dateien ablehnt, für die die
--x--x--x
Bits nicht gesetzt sind. Erstellen Sie die Pipe mitmkfifo(1)
und versuchen Sie, sie zum Laufen zu bringen.Ein anderer Ansatz wäre, etwas zu schreiben, das die Standardeingabe liest, eine Datei in einen temporären Bereich ausschreibt, die --x-Bits darauf setzt, die Datei gabelt und ausführt und dann löscht. Der Inode und der Inhalt bleiben so lange erhalten, bis die Ausführung des Programms abgeschlossen ist. Über das Dateisystem kann jedoch nicht darauf zugegriffen werden. Wenn der Prozess beendet ist, wird der Inode freigegeben und der Speicher auf die freie Liste zurückgesetzt.
BEARBEITEN: Wie Mat betont, funktioniert der erste Ansatz nicht, da der Loader versucht, eine Seite in der ausführbaren Datei anzufordern, wodurch zufälliger Suchverkehr für die Datei generiert wird. Dies ist in einer Pipe nicht möglich. Dies lässt eine Art Ansatz wie der zweite.
quelle
Eine Lösung mit memfd syscall: https://github.com/abbat/elfexec
Es wird ein benannter Dateideskriptor im Speicher erstellt, der verwendet werden kann
exec
. Ein Pseudocode:quelle
memfd.h
Header nicht, es sei denn, Sie möchten ihn verwendenMFD_CLOEXEC
(wodurch#! /bin/sh
Skripte aufgrund von Fehlern in Linux beschädigt werdenfexecve()
). Das ist nicht allzu kompliziert. Sie können ein 20- zeiliges Arbeitsprobe in Ihre Antwort aufnehmen (z. B. dieses Git-Gist - obwohl dies kein Ersatz für Ihr istelfexec
, da Sie damit auchargv[0]
eine Binärdatei angeben und ausführen können nur von einer Pipe (UUoC mandated ;-)).o
Dateien nach / tmp und stirbt, wenn dies nicht möglich ist.Sie können tcc ausprobieren , das ein Programm in einem Schritt kompiliert und ausführt, ohne Zwischendateien zu schreiben. Es ist nicht gcc, was für Sie ein Problem sein kann, aber es ist spektakulär schnell, so dass es für Ihre Zwecke sogar besser als gcc sein kann.
quelle
Dadurch wird die Kompilierung Ihres Codes automatisch ausgeführt, es wird jedoch (vorübergehend) eine Datei auf dem Dateisystem erstellt, um dies zu tun.
(Ich teste dies gerade, aber ich bin mir ziemlich sicher, dass dies oder etwas in der Nähe für Sie funktionieren wird.)
BEARBEITEN: Wenn das Ziel Ihrer Rohrleitungen darin besteht, physische Datenträger aus Gründen der Geschwindigkeit aus der Gleichung herauszuschneiden, sollten Sie eine RAM-Platte für die Zwischendatei erstellen.
quelle
csh
.Genau wie @TheQUUX vorgeschlagen hat, habe ich es nicht selbst getestet, aber Sie möchten es vielleicht ausprobieren
cling
- "den interaktiven C ++ - Interpreter, der auf LLVM- und Clang-Bibliotheken aufbaut".Weitere Informationen finden Sie hier: https://cdn.rawgit.com/root-project/cling/master/www/index.html
quelle