Initiative to reduce dependencies in libsystemd

Among developers of the system manager systemd, there is a discussion about reducing dependencies in the libsystemd library, which is linked not only to systemd components but also to many external applications. For example, in Fedora, over 150 packages use libsystemd as dependencies. The initiator of the discussion believes that pulling in additional third-party libraries into libsystemd, which are not controlled by systemd developers, significantly increases the attack surface in the event of a compromise of these third-party libraries, as happened with the liblzma library.

In addition to liblzma and glibc, libsystemd also loads libraries libzstd, liblz4, and libgcrypt, where maintaining security becomes a critically important task. libsystemd provides access to 12 basic APIs (sd-bus, sd-daemon, sd-device, sd-event, sd-hwdb, sd-id128, sd-journal, sd-login, sd-netlink, sd-network, sd-path, and sd-resolve), leading to a situation where an application, for example, using libsystemd solely for the sd_notify function to inform systemd of state changes or sd_journal for logging data, is linked to all other libraries and API handlers. As a solution, it is proposed to split libsystemd into several separate libraries, responsible for individual APIs, which would allow third-party dependencies to be loaded only where necessary.

The developers of systemd consider the separation impractical, as the handlers present in libsystemd are interconnected. Splitting would require a massive amount of work and would either lead to a loss of efficiency or require code duplication. To reduce memory usage in libsystemd, a change was recently adopted to implement dynamic loading of the libraries liblzma, libzstd, and liblz4 using the dlopen() call when their functions are genuinely needed. A similar change will also be implemented for libgcrypt starting from the next release.

This solution has faced criticism, as instead of explicit and noticeable linking, the loading of third-party libraries will now be done implicitly, complicating diagnostics, since the connection between libsystemd API calls and function calls from external libraries will not be obvious. The transition to loading via dlopen() does not change the architecture itself; it merely hides external components from maintainers and users.

Lenart Pottering expressed strong disagreement with the idea of splitting libsystemd into several libraries, as this step would significantly complicate code sharing within systemd and require all internal handlers to be either made public or statically compiled into each library. In the first case, there would be issues maintaining API stability and namespaces, and in the second, an increase in size due to code duplication.

The implementation for the next release, loading external libraries only on demand, is perceived by Lenart as the optimal strategy. The issue of complicating the retrieval of data about dynamically loaded libraries is proposed to be resolved by adding additional fields with information about such dynamic dependencies to ELF files, which can be handled by debuggers and displayed in the output of the readelf utility.

Regarding the binding of a large number of applications to libsystemd, Lenart recommended that application developers not attempt to load libsystemd for a single function but instead implement the protocol handler at the application level. For example, implementing the sd_notify() functionality is quite trivial and can fit into just a few lines of code when using UNIX sockets (AF_UNIX). A similar standalone implementation of sd_notify has been available for OpenSSH since 2017 and was recently accepted into the portable branch of OpenSSH 9.8, with a release scheduled for mid-summer.

Source: opennet.ru

Buy reliable website hosting with DDoS protection, VPS VDS servers 🔥 Buy reliable website hosting with DDoS protection, VPS VDS servers | ProHoster