SelfLinux » Überblick über Linux » Bibliotheken » Teil 3 SelfLinux-0.8.0
« zurück weiter »
SelfLinux logo
OrdnerBibliotheken Revision: 1.1.2.6
Autor: Steffen Dettmer
Layout: Torsten Hemm
Lizenz: GFDL

5 Gemeinsam genutzte, dynamisch gelinkte Bibliotheken


5.1 Verwenden von Bibliotheken

Hat man eine Linux-Distribution (SuSE Linux, RedHat Linux oder andere) installiert, so hat man sehr viele Komponenten installiert. Neben dem Kernel (also Linux selbst) sind unzählige Programme und natürlich Bibliotheken installiert worden. Die Bibliotheksdateien befinden sich in den Verzeichnisse /lib und /usr/lib. Etliche der installierten Programme verwenden auch statisch gebundene Bibliotheken, aber da man davon im Betrieb nichts merkt, wird das hier nicht näher betrachtet.

Die dynamischen, gemeinsam benutzbaren Bibliotheken sind für alle Programme des Linuxsystems verwendbar. Neben der einfachen Benutzung bietet ein Linuxsystem jedoch weitere Vorteile, die anspruchsvolleren Anforderungen genügen.

Es ist möglich, zu einem Zeitpunkt verschiedene Versionen einer Bibliothek installiert zu haben. Man kann in diesem Fall beeinflussen, welche Bibliotheken ein Programm verwendet. So kann man auch ältere Programme weiterverwenden, die eine alte, inkompatible Version einer Bibliothek benötigen.

Man kann auch veranlassen, dass bestimmte Bibliotheken, die ein Programm verwendet, gegen andere ersetzt werden, um damit beispielsweise gezielt einzelne Funktionen zu ersetzen.



5.2 Der Linux Programm Lader

Soll ein Programm, welches Bibliotheken verwendet, gestartet werden, so müssen natürlich diese mitgeladen werden. Dazu wird zunächst gar nicht das eigentliche Programm gestartet, sondern der sogenannte Programm Lader (eng: program loader). Dieser wird auch dynamic linker genannt, da er die Bibliotheken zum Programm bindet (engl: link). Auf Linuxsystemen heißt dieser /lib/ld-linux.so.2 (die .2 ist wieder eine Versionsnummer; das "-linux" zeigt, dass er Linuxspezifisch ist. Oft wird er jedoch insbesondere in technischer Dokumentation ld.so genannt). Der Programmlader lädt nun auch die benötigten Bibliotheken automatisch. Im Kopf der Programmdateien steht eine Liste mit diesen. Nach dem Laden bereitet er das Programm zum Start vor, und startet es letztendlich.

Dieser Vorgang findet bei fast allen Linux-Programmen statt. Nur sehr wenige Programme verwenden keine dynamischen Bibliotheken. Beispiele dafür sind login (hier aus Sicherheitsgründen) und rpm (damit man es auch starten kann, wenn die Systembibliotheken beschädigt oder defekt sind).

Um eine Bibliothek zu laden, bestimmt der Programm Lader den Namen der Bibliotheksdatei.



5.3 Namen von Bibliotheken

Jede Bibliothek hat natürlich einen Namen. So heißt die Lib-C beispielsweise c und Mathematikfunktionen findet man als m und die für das dynamische Laden heißt dl (C-Programmierer scheinen sehr kurze Namen zu lieben).

Vor diese Namen wird lib vorangestellt, um kenntlich zu machen, dass es sich um eine Bibliothek handelt. Dahinter schreibt man bei gemeinsam benutzbaren Bibliotheken .so (für engl: shared object) und bei statisch linkbaren .a (für engl. archive).

Hinter das .so hängt man noch eine Versionsnummer an. Diese Versionsnummer wird durch einen Punkt abgetrennt und kann mehrwertig sein, so kann man beispielsweise eine /lib/libdl.so.1.9.9 haben. Hierbei handelt es sich um die dl in der Version 1.9.9.

Da die Bibliotheken die Versionsnummer im Dateinamen haben, aber ein Programm in der Regel nicht an einer bestimmten Version interessiert ist, werden symbolische Links angelegt (wie diese Links entstehen, wird später noch beschrieben). So wird beispielsweise die Datei libcrack.so.2.7 auch als libcrack.so.2 und als libcrack.so bekannt gemacht. Ein Programm kann nun gegen libcrack gelinkt werden, und es wird auch noch funktionieren, wenn eine libcrack.so.2.8 installiert wird, oder ein System nur eine libcrack.so.2.6 anbietet. Linkt ein Programm direkt gegen eine Version, so muss natürlich die genau passende vorhanden sein. Dies wird auch manchmal gemacht, was bei Updates zu Problemen führen kann, weil die Programme plötzlich nicht mehr gestartet werden können. Oft funktionieren die Programme jedoch auch mit neueren Versionen. Nun kann man natürlich einfach einen Link per Hand erzeugen, der von Programm verwendet wird, und auf eine vorhandene, neuere Version zeigt, doch kann es auch hier zu Problemen kommen. Diese Vorgehen sollte daher in Produktion vermieden werden.



5.4 Platzierung im Dateisystem

Werden diese bereits für das Starten eines Linuxsystems benötigt, so werden diese Bibliotheken in /lib installiert. Andere, die zum Starten selbst noch nicht benötigt werden (zum Beispiel Grafikbibliotheken) finden sich dagegen in /usr/lib. Zusätzliche Bibliotheken, die nicht zu einer Distribution gehören, sondern selbst installiert wurden, finden sich meistens in /usr/local/lib.



5.5 Funktion des Dynamischen Linkers (Programm Laders)

Der Programmlader versucht zunächst, sämtliche Bibliotheken zu laden. Er sucht dazu in den Pfaden, die in der Umgebungsvariablen LD_LIBRARY_PATH hinterlegt sind. Anschließend wird in einem Cachefile gesucht (/etc/ld.so.cache), welches aus Effizienzgründen verwendet wird, und letztlich in /usr/lib und /lib. Da die Verwendung von LD_LIBRARY_PATH im Normalbetrieb umständlich ist, wird diese normalerweise nicht gesetzt, vielmehr stehen alle Bibliotheken im Cachefile. Dieses wird über ein spezielles Werkzeug erstellt. Fast alle Bibliotheken werden über diesen Weg geladen.

Findet der Dynamische Linker nicht alle benötigen Bibliotheken (oder fehlt eine Funktion oder ein anderes Symbol in einer gefundenen Bibliothek), so wird der Start mit einer Fehlermeldung abgebrochen.



5.6 Umgebungsvariablen

Der Dynamische Linker wird über Umgebungsvariablen gesteuert. Neben der bereits erwähnten Variable LD_LIBRARY_PATH erkennt der Programm Lader die Variable LD_PRELOAD. Die durch Leerzeichen getrennten Einträge dieser Variable ist eine Liste von Bibliotheken, die auf jeden Fall zuerst geladen werden sollen. Dies ermöglicht es, Bibliotheken zu laden, die Funktionen von anderen Bibliotheken "überschreiben". Der Linker verbindet die Programmfunktionen in diesem Fall nämlich mit denen aus dieser Bibliothek, selbst wenn später eine andere Bibliothek diese Funktion auch definiert. Dies ist jedoch auch für Angriffe ausnutzbar, so könnte man beispielsweise Bibliotheken "unterschieben", die über Seiteneffekte von "normalen" Funktionen bestimmte ungewollte Aktionen ausführen. Aus diesem Grund ignoriert der Programmlader (beide) Variablen bei "setuid" Programmen (also Programme, die unter anderen Benutzerrechten laufen, als der Aufrufer besitzt). Dadurch kann ein Aufrufer sich keine zusätzlichen Rechte verschaffen.

Eine Liste aller Umgebungsvariablen findet man in der Manpage ld.so.



5.7 Cachefile erzeugen

Das bereits erwähnte Cachefile wird vom Werkzeug ldconfig erzeugt. Dieses verwendet eine Konfigurationsdatei /etc/ld.so.conf. Erkennt man, dass ldconfig und ld-linux.so sehr stark zusammenarbeiten, wird auch der Name der Datei erkenntlich. Indirekt konfiguriert man ja den dynamischen Linker (der ja manchmal ld.so genannt wird).

ldconfig sucht in den Verzeichnissen, die in /etc/ld.so.conf stehen, nach Bibliotheken. Bei diesem Vorgang werden auch die symbolischen Links angelegt, die im Abschnitt "Namen von Bibliotheken" beschrieben wurden. Die gefundenen Bibliotheken aus allen angegebenen Verzeichnissen werden mit Versions- und weiteren Informationen im Cachefile /etc/ld.so.cache abgespeichert (welches dann vom Programmlader verwendet wird).

Das Programm ldconfig lässt sich über Kommandozeilenparameter steuern, die in der Manpage gelistet sind. Ein Beispiel ist der Schalter -v, der etliche Informationen anzeigt; ein Aufruf von ldconfig -v ist vielleicht an dieser Stelle interessant.

Aus naheliegenden Gründen verwendet ldconfig selbst keine dynamischen Bibliotheken, sondern ist statisch gebunden.



« zurück weiter »
Inhalt