Maschinencode-JITs und das Execution Disable-Bit

10

Wie wird zur Laufzeit generierter Maschinencode (z. B. die Ausgabe einer JIT) tatsächlich von der CPU ausgeführt, wenn die CPU / das Betriebssystem über ein Ausführungssperrbit verfügt?

Soweit ich weiß, unterstützen viele moderne Prozessoren und Betriebssysteme ein NX-Bit (einschließlich Intel und ARM), das verhindert, dass Maschinencode ausgeführt wird, der an einer anderen Adresse als dem Codeabschnitt einer kompilierten Binärdatei gespeichert ist. Dies ist eindeutig ein netter Sicherheitsvorteil, da dadurch Shell-Code-Injection-Angriffe verhindert werden.

Aber wie umgehen JIT-Engines wie LLVM, die dynamisch Maschinencode generieren, dies?

Siler
quelle
Schauen Sie sich die Implementierungen von Memory :: allocateMappedMemory an, um zu sehen, wie es in LLVM gemacht wird. - Für * nix - Für Windows
zr01

Antworten:

6

Unter Linux und viele Posix - Systemen kann eine Anwendung den Schutz eines gewissen Bereichs des Prozesses ändern Adressraum in den virtuellen Speicher , die unter Verwendung von mmap (2) und mprotect (2) syscalls.

Die JIT-Engine könnte diese also verwenden (wahrscheinlich vor der Ausgabe des Maschinencodes, aber möglicherweise danach ).

Übrigens müssen Sie bei einigen Architekturen möglicherweise den CPU-Cache über neu verfügbare Maschinencodesegmente informieren, z __builtin_clear_cache. B. über GCC.

Basile Starynkevitch
quelle