I am not convinced dlopen will it make secure in the end. I am not sure this is a good solution. dlopen makes those dependencies non-obvious from packaging side and non-visible from ldd or similar checking programs.

I think it should be considered to offer more than one dynamic library. For example most services I maintain links to libsystemd just because it wants sd_notify calls in their services. Without any proof I would expect quite many services would have similar problem. Could be perhaps libsystemd broken into few more dynamic linked libraries? I somehow doubt any kind of compression is needed for sd_notify calls.

Could be even smaller library libsystemd-notify linked from libsystemd, which would allow end applications to explicitly declare they need more limited set of functions?

Is there now relatively simple way to analyze packages depending on libsystemd, how rich functionality they need to use? I somehow doubt many packages need explicit work with journal. If they do, okay, use more heavy-weight library. But quite alot of programs needs just sd_notify* and sd_listen* calls, maybe with addition to sd_booted.

The best example is sshd itself, which plays important role in this story. For a very good reason.

$ objdump -T /usr/sbin/sshd | grep sd_
0000000000000000      DF *UND*    0000000000000000 (LIBSYSTEMD_209) sd_notify

Less code linked into libraries means less code needs to be analysed for malware or security scans. It also allows an user to explicitly declare just limited functions should be available.

I have made crude script getting calls used on my own system. While there is larger group with also journal involved, I think number of packages using just sd_notify, sd_listen or similar is not unimportant.

$ dnf repoquery --whatdepends systemd-libs --alldeps | sort -u | while read PKG; do rpm -q "$PKG" >/dev/null && echo "$PKG"; done | tee installed
$ cat installed | while read PKG; do rpm -ql "$PKG" | grep -E '^(/usr/s?bin/|/usr/lib64/|/usr/libexec)' | while read BIN; do objdump -T "$BIN" 2>/dev/null | grep -E ' (sd|udev)_' | sed -e 's/[0-9a-f]\+\s*DF\s*\(\*UND\*\|.text\)\s*[0-9a-f]\+\s*//' -e "s|^|$PKG ${BIN}: |" ; done; done | tee libsystemd-calls.txt

Attached the results in libsystemd-calls.txt attachment.

I would prefer ability to explicitly declare I want just limited functionality for cooperating with systemd, without any obscure dlopen calls. They are even more suspicious in low-level library and I don't think they should be used to solve resource limitations. They make it more difficult to discover actually used dependencies by static analysis tools. udev has already own library, perhaps notify and bus should be able to use with a more lightweight library too?

Regards,
Petr 

(edit: attached compressed list.)

On 30. 03. 24 19:43, Zbigniew Jędrzejewski-Szmek wrote:
libsystemd is linked to compression libraries primarly because those compressors
are options for journald files, and we generally want to mainain the property
that all journal files from the past, as well as journal files from other
systems, can be read by later journal code.

(bzip2 is an exception here. It is only used by systemd-importd and related
tools, so libsystemd was never linked to it, IIRC.)

In recent systemd versions, dlopen is used for various compression libraries and
other libraries, so they'll be opportunistically loaded if needed, effectively
making those dependencies optional at runtime.

Conversions to use dlopen require a bit of boilerplate code and make the code
less readable, so we only would to them if there was a reason. Usually, this
reason was size and/or the dependency tree. Compression libraries are very small
and have no dependencies, so it wasn't considered important to use dlopen for
them. But now that there's a new motivation, as mentioned elsewhere in the
thread, we'll load pretty much all dependencies of libsystemd via dlopen.

Zbyszek

Petr Menšík
Software Engineer, RHEL
Red Hat, http://www.redhat.com/
PGP: DFCF908DB7C87E8E529925BC4931CA5B6C9FC5CB