Unter den Entwicklern des Systemmanagers systemd wird die Frage diskutiert, die Abhängigkeiten der Bibliothek libsystemd zu verringern, die nicht nur mit den Komponenten von systemd, sondern auch mit vielen externen Anwendungen verbunden ist. Zum Beispiel verwenden in Fedora über 150 Pakete libsystemd in ihren Abhängigkeiten. Der Initiator der Diskussion ist der Meinung, dass das Einbinden zusätzlicher externer Bibliotheken in libsystemd, die nicht von den Entwicklern von systemd kontrolliert werden, die Angriffsfläche im Fall einer Kompromittierung dieser externen Bibliotheken erheblich vergrößert, wie es bei der Bibliothek liblzma der Fall war.
Neben liblzma und glibc werden in libsystemd auch die Bibliotheken libzstd, liblz4 und libgcrypt geladen, deren Sicherheit kritisch wichtig wird. In libsystemd gibt es Zugriff auf 12 grundlegende APIs (sd-bus, sd-daemon, sd-device, sd-event, sd-hwdb, sd-id128, sd-journal, sd-login, sd-netlink, sd-network, sd-path und sd-resolve), was zu der Situation führt, dass eine Anwendung, die beispielsweise libsystemd nur für den Aufruf der Funktion sd_notify zur Benachrichtigung von systemd über den Statuswechsel oder sd_journal zur Protokollierung von Daten nutzt, mit all den anderen Bibliotheken und API-Handlern verbunden ist. Als Lösung wird vorgeschlagen, libsystemd in mehrere separate Bibliotheken aufzuteilen, die jeweils für eine bestimmte API zuständig sind, sodass externe Abhängigkeiten nur dort geladen werden, wo sie benötigt werden.
Die Entwickler von systemd halten die Trennung für nicht sinnvoll, da die in libsystemd vorhandenen Handler miteinander verknüpft sind. Eine Trennung würde einen enormen Aufwand erfordern und entweder zu einem Verlust an Effizienz oder zu einer Notwendigkeit der Code-Duplikation führen. Um den Speicherbedarf in libsystemd zu reduzieren, wurde kürzlich eine Änderung beschlossen, die die dynamische Lade der Bibliotheken liblzma, libzstd und liblz4 mittels des Aufrufs dlopen() ermöglicht, wenn deren Funktionen tatsächlich benötigt werden. Eine ähnliche Änderung wird ab der nächsten Version auch für libgcrypt implementiert.
Eine solche Lösung wurde kritisiert, da die Ladezeiten von Drittanbieterbibliotheken nun nicht mehr offensichtlich und sichtbar sind, was die Diagnostik erschwert, da die Verbindung zwischen den API-Aufrufen von libsystemd und den Funktionsaufrufen aus externen Bibliotheken nicht offensichtlich ist. Der Wechsel zum Laden über dlopen() ändert an sich nicht die Architektur, sondern verbirgt lediglich externe Komponenten vor Entwicklern und Benutzern.
Lenart Poettering drückte seine kategorische Ablehnung der Idee aus, libsystemd in mehrere Bibliotheken zu unterteilen, da dieser Schritt die gemeinsame Nutzung von Code in systemd erheblich erschweren würde und es erforderlich machen würde, alle internen Handler entweder öffentlich zu machen oder sie separat statisch in jede Bibliothek zu kompilieren. Im ersten Fall würden Probleme mit der Stabilität der API und den Namensräumen auftreten, im zweiten Fall würde es zu einer Vergrößerung der Größe durch Code-Duplikation kommen.
Die für die nächste Version implementierte bedarfsorientierte Ladeweise externer Bibliotheken wird von Lenart als optimale Strategie betrachtet. Um das Problem zu lösen, dass Informationen über dynamisch geladene Bibliotheken schwer zu beschaffen sind, wird vorgeschlagen, in ELF-Dateien zusätzliche Felder mit Informationen über solche dynamischen Abhängigkeiten hinzuzufügen, die von Debuggern verarbeitet und in der Ausgabe des Tools readelf angezeigt werden können.
Was die Bindung von libsystemd an viele Anwendungen betrifft, so empfahl Lenart den Entwicklern, libsystemd nicht nur für eine Funktion zu laden, sondern einen Protokollhandler auf Anwendungsebene zu implementieren. Zum Beispiel ist die Implementierung der Funktionalität von sd_notify() ziemlich trivial und kann in wenigen Zeilen Code unter Verwendung von UNIX-Sockets (AF_UNIX) erledigt werden. Eine derartige eigenständige Implementierung von sd_notify ist seit 2017 für OpenSSH verfügbar und wurde vor kurzem in die tragbare Version von OpenSSH 9.8 aufgenommen, deren Veröffentlichung für Mitte des Sommers geplant ist.
Quelle: opennet.ru
