ELF Shared Libraries - Motivation für das PLT

11

Könnte selbstmodifizierender Code verwendet werden, um den Funktionsaufruf in dynamisch verknüpften Bibliotheken zu beschleunigen?

Soweit ich weiß, verwenden gemeinsam genutzte ELF-Bibliotheken eine Art indirekte Sprungtabelle (die Prozedurverknüpfungstabelle oder PLT), um eine verzögerte Bindung von Bibliotheksfunktionen zu ermöglichen. Der Zweck scheint darin zu bestehen, zu vermeiden, dass die Tabelle im Codesegment geändert werden muss, während die verzögerte Auflösung von Funktionspositionen beim ersten Aufruf weiterhin ermöglicht wird.

Wäre es nicht schneller, den Code für diese Tabelle beim Laden oder möglicherweise sogar beim ersten Funktionsaufruf dynamisch zu erstellen?

Ist es möglich, die gemeinsame Nutzung des Codesegments zwischen Prozessen so weit wie möglich zu ermöglichen (eine dynamische Tabelle wäre für einen Prozess privat)? Ist dies aus Sicherheitsgründen der Fall (beschreibbarer Code sollte nicht ausführbar sein - JITs tun dies jedoch ständig, und die Schreibberechtigung kann vom Loader hinzugefügt und entfernt werden, bevor das Programm tatsächlich gestartet wird)?

Oder ist es eine Kombination davon, und der geringe Leistungsgewinn pro Funktionsaufruf wäre die Mühe einfach nicht wert?

lxgr
quelle

Antworten:

8

Ich nehme an, wir sprechen über x86-Architektur.

Sie können keinen sich selbst ändernden Code im geschützten Modus haben , der von den meisten mir bekannten UNIX-basierten Betriebssystemen (und nicht nur) verwendet wird, da die Codesegmente immer schreibgeschützt sind. Ein Loader steuert nicht, dass -es vom Speicherverwaltungssubsystem des Kernels verwaltet wird.

Aber selbst wenn Sie "den Code für diese Tabelle beim Laden erstellen" könnten, wie Sie sagen, würde dies dem gesamten Zweck von gemeinsam genutzten Bibliotheken widersprechen. Auf diese Weise würde jeder Prozess eine "private" Kopie der Funktionen der Bibliothek in seinem Adressraum haben, wodurch der Speicherbedarf effektiv erhöht würde. Einer der Gründe, warum gemeinsam genutzte Bibliotheken erstellt wurden, bestand darin, dieses Problem zu beheben.

Der gesamte von Ihnen beschriebene Prozess ist recht komplex und würde mehr Verarbeitungszyklen kosten als die heutzutage verwendete PLT-Methode und wahrscheinlich mehr neue und interessante Sicherheitsprobleme mit sich bringen.

dkaragasidis
quelle
2
Mit dem Systemaufruf mprotect (2) können Sie Textsegmentseiten beschreibbar und ausführbar machen.
Bruce Ediger
1
Das ist richtig, Sir. Wahrscheinlich würde es auf einem durchschnittlichen UNIX-basierten System anständig funktionieren, aber der gesamte Verknüpfungsprozess würde unterbrochen, sobald jemand versuchte, das System mit z. B. PaX zu härten, wodurch Einschränkungen für mprotect erzwungen werden (2).
Dkaragasidis
(Es scheint, dass ich @BruceEdiger in meinem vorherigen Kommentar nicht erwähnt habe)
dkaragasidis
1

ELF-DSOs können ein Flag (DF_TEXREL) verwenden, um anzukündigen, dass sie durch Ändern ihres Textabschnitts (der normalerweise schreibgeschützt ist) eine Neuzuweisung benötigen. Der Sprungtabellenansatz zusammen mit dem positionsunabhängigen PIE-Code sollte jedoch optimaler sein.

(Gefunden, dass in http://www.akkadia.org/drepper/dsohowto.pdf , aber andere Ressourcen erwähnen dies auch).

PSkocik
quelle