Systemd replacing ELF dependencies with dlopen
mastodon.social
mastodon.social
Deleted comment
Which the recent xz attack used to mess with `sshd`, even if it never actually used functions from the library.
dlopen loading only loads the library *when it's actually used*, and doesn't include everything and the kitchen sink on startup.
If the libraries are used seldomly enough, it might also allow to make more dependencies optional in package management.
What you gain is that the vulnerabilities will be harder to track down?
Debian's sshd only uses libsystemd for the notify api. I.e. it doesn't need any feature that uses libxz. If it's dlopen()ed, it does not need to be loaded into the process context to use an unrelated feature.
FWIW, IMO upstream systemd should split their monolithic library and allow users to pick better that way, but this has other implications on DX.
FWIW, upstream systemd has the opinion that no-one should load the library for startup notification, instead they should use the well documented api and just write a message to a socket.
It calls it a "good choice". Did they say somewhere else that no-one should do it despite it supposedly being a good choice?
They've done the exact opposite afaict. Libsysd used to be split up, now it is monolithic.
They probably couldn't change it anymore if they tried to.
No, they're just as easily tracked.
What you gain is that you can refuse to install optional dependencies because they are now optional when they used to be required.
That's a fairly big deal.
Of course, in practice all those optional dependencies will be installed anyways because of other things in the distro needing them. You can fairly object that not much changed, at least for now.
A better approach would be to eliminate a lot of these dependencies somehow. Another approach would be to sandbox the dependencies that cannot be eliminated.
On my laptop there's 141 binaries in /bin/ that link against lzma; an abbreviated list with similar entries omitted below. And that's a fairly minimal Void Linux system – the list for an average Ubuntu system is probably a lot longer. Sneaking in via kmod, grub-install, udevd, or xbps-install seems just as viable as sneaking in via libsystemd. Perhaps a little bit harder, but not much.
It will remain problem as long as you have a single command that runs your malicious code as root. Being directly linked against sshd was convenient, but there's all sorts of devious shit you can pull once you've got root, and it doesn't take that much more effort.
% for f in /bin/*(*); ldd $f 2>&1 | grep -q lzma && print $f
/bin/amdgpu-arch
/bin/bsdcat
/bin/bsdcpio
/bin/bsdtar
/bin/bsdunzip
/bin/c-index-test
/bin/clang-*
/bin/clangd
/bin/diagtool
/bin/ffmpeg
/bin/ffplay
/bin/ffprobe
/bin/find-all-symbols
/bin/grub-editenv
/bin/grub-install
/bin/grub-mkimage
/bin/grub-mknetdir
/bin/grub-mkrescue
/bin/grub-mkstandalone
/bin/kmod
/bin/lspci
/bin/modularize
/bin/mpv
/bin/nvptx-arch
/bin/pp-trace
/bin/pskctool
/bin/qemu-*
/bin/rtorrent
/bin/tiffcp
/bin/tiffdump
/bin/tiffinfo
/bin/tiffset
/bin/tiffsplit
/bin/udevadm
/bin/udevd
/bin/update-mime-database
/bin/xbps-alternatives
/bin/xbps-checkvers
/bin/xbps-create
/bin/xbps-dgraph
/bin/xbps-digest
/bin/xbps-fbulk
/bin/xbps-fetch
/bin/xbps-install
/bin/xbps-pkgdb
/bin/xbps-query
/bin/xbps-reconfigure
/bin/xbps-remove
/bin/xbps-rindex
/bin/xbps-uchroot
/bin/xbps-uhelper
/bin/xbps-uunshare
/bin/xmlcatalog
/bin/xmllint
/bin/xsltproc
/bin/zstdSo upgrading XZ could even attack already running sshd too?
I would be more inclined to have static linked libraries instead of having lazy loading of them for preventing this kind of attacks..
With the specifics of how the xz injection attack worked, actually it wouldn't. libsystemd would have been loaded to implement the service-started notification, and then there is no reason to use anything further and therefore nothing to trigger the loading of the xz library.
Which is kind of the point of this change: the goal is to load libraries on-demand instead of eagerly, so if there is nothing demanding the library load, the library is never loaded.
There's also "filters" and "auxiliary filters", which can be used to make dependencies optional without having to go to `dlopen()`. However, IIRC filter functionality is very bare-bones or non-workin in the Linux link-editors and ld.so.
Doesn't that work both ways, without dlopen updating to the patched version would still leave your sshd running with the old backdoored one.
Instead of dlopen()ing libfoo.so.7, you should build a private wrapper library, normally linked with -lfoo, and then dlopen() that private wrapper. Then you get dependency tracking for free.
This seems a lot like a workaround for our tools not supporting optional dependencies. Let's fix that instead.
On the one hand, this seems like a slight improvement.
On the other hand, while it’s a bit of a slog, it’s possible to actually sandbox dependencies. libxz, for example, has well defined inputs and outputs. It’s possible to load it in such a way that all it can do is consume inputs and produce outputs that depend on those inputs. (And allocate memory and waste CPU, but that’s DoS at worst.)
I agree that a simple self-contained .h header file would solve it in a better way.
But I stopped trying to push for minimalism. Sadly.
It isn't systemd's decision what version of xz-utils to use, it's the distro's decision. And Jia Tan did push the distro maintainers to update xz-utils, but the systemd developers have absolutely nothing to do with that, so your statement is incorrect.
2024-02-29: On GitHub, @teknoraver sends pull request to stop linking liblzma into libsystemd. It appears that this would have defeated the attack. Kevin Beaumont speculates that knowing this was on the way may have accelerated the attacker’s schedule. @teknoraver commented on HN that the liblzma PR was one in a series of dependency slimming changes for libsystemd; there were two mentions of it in late January. https://research.swtch.com/xz-timeline
See also previously on HN: https://news.ycombinator.com/item?id=39916125
The podcast is interesting either way.
> "Jia Tan" was pushing hard to get systemd updated to use the new xz
Which is different from your claim "changes in upstream systemd would limit the timeline for them"
Apologies for any misunderstanding.