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