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.)
libsystemd is linked to compression libraries primarly because those compressorsare 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