323 karma · joined June 20, 2017
I really don't know what the problem is suppoaed to be.
Lennart
First of all, in systemd, which is a heavy D-Bus user, we effectively IRL only send integers > 2^53 when we use UINT64_MAX as a special "niche" marker meaning "unlimited"/"unset"/"undefined". But the thing is that JSON has a proper concept for this: the "null" value (or simply not specifying a specific JSON field). Hence, in reasonably clean APIs this is mostly a non-issue.
That said, sd-varlink/sd-json (i.e. systemd's implementation of it), of course is 64bit signed and unsigned integer clean when it processes JSON. More-over it automatically handles if you do what the various specs on the internet suggest you do if you have an integer > 2^53: you encode it as decimal value as a string.
Would it be better if JSON would have been more precise on this, yes. Is it a big issue? No, not at all.
A 100 digit number cannot be encoded losslessly in D-Bus btw, nor in the far majority of IPC marshallings on this word.
Having done systems-level OS development since 25y or so I never felt the burning urge to send a 100 digit number over local IPC.
Not that 100 digit numbers aren't useful, even in IPC, but typically, that's a cryptography thing, and they generally use their own serializations anyway.
(Yes, we then store the structure log data on disk in a binary format. Lookup indexes are just nasty in text based formats).
Hence, not sure what the Journal has to do with Varlink, but any IPC that the journal does is text-based, and very nicely strace'able in fact, I do that all the time.
[Maybe, when trying to be a smartass, try to be "smart", and not just an "ass"?]
What does matter though are roundtrips. In Varlink there are much fewer required for typical ops than there are in D-Bus. That's because D-Bus implies a broker (which doubles the number of roundtrips), but also because D-Bus forces you into a model of sending smaller "summary" messages when enumerating plus querying "details" for each listed objects, because it enforces transfer rate limits on everything (if you hit them, you are kicked off the bus), which means you have to refrain from streaming too large data.
Or in other words: marshalling is quite an irrelevant minor detail when it comes to performance, you must look at roundtrips instead and the context switches it effects, instead.
Using JSON for this has two major benefits: the whole world speaks JSON, and modern programming languages typically pretty natively. And it's directly readable in tools such as strace. With a simple "strace" I can now reasonably trace my programs, which a binary serialization will never allow you. And if you tell me that that doesn't matter, then you apparently live in an entirely different world than I do, because in mine debuggability does matter. A lot. Probably more than most other things.
Lennart
Dlopen has drawbacks but also major benefits. We decided the benefits relatively clearly outweigh the drawbacks, but of course people may disagree.
I have proposed a mechanism before, that would expose the list of libs we potentially load via dlopen into an ELF section or ELF note. This could be consumed by things such as packagae managers (for auto-dep generation) and ldd. However there was no interest in getting this landed from anyone else, so I dropped it.
Note that there are various cases where people use dlopen not on hardcoded lib names, but dynamically configured ones, where this would not help. I.e. things like glibc nss or pam or anything else plugin based. But in particular pam kinda matters since that tends to be loaded into almost any kind of security relavant software, including sshd.
But let me stress two other things:
Libselinux pulls in liblzma too and gets linked into tons more programs than libsystemd. And will end up in sshd too (at the very least via libpam/pam_selinux). And most of the really big distros tend do support selinux at least to some level. Hence systemd or not, sshd remains vulnerable by this specific attack.
With that in mind libsystemd git dropped the dep on liblzma actually, all compressors are now dlopen deps and thus only pulled in when needed.
(To make this happen the user record is embedded into the LUKS2 header metadata so that we can use it before mounting the fs)
It's entirely OK if the admin then opts out specific users or even all users from this behaviour, i.e. if a privileged players decides to liberalize unbounded, unlifecycled resource consumption for unprivileged players. But a default where unprivileged code can just stick around uncontrolled and consume as much as it wants forever is just a strange choice security wise.
i.e. I think the fact that SIGHUP masking is unrestricted, i.e. is not subject to privilege checks is the problem really. Something is unpriv by default that should be priv by default. And that's pretty much what this option in systemd provides you with.
That said the question is not so much about who sends what, but more about whether a secure system should allow user code to escape lifecycle management or whether logging out means logging out and giving up all resources.
I am not trying to get you to use our APIs. You talking about the cgroups APIs again, if I am not mistaken? As I tried to explain again and again: if you want container runtimes to manage their own cgroups then just set Delegate=yes in the unit file of your manager, get your own cgroup subtree, and you can do below it whatever you want, you do not have to call into systemd ever. Not a single API call, no C call, no D-Bus call, nothing. You get your own kingdom if you set Delegate=yes, and systemd won't interfere with that. This is extensively documented.
I wished you'd actually listen to what I keep repeating to you. We tried to be really nice to container managers, knowing that they disklike systemd APIs, so we put a lot of work in making the delegation boundary clean, so that they can be entirely systemd agnostic beyond setting the Delegate=yes boolean in their unit file, but alas, we just keep hearing the same nonsense.
The LXC/LXD people btw did get this right: they manage their own cgroup subtree now, and systemd doesn't interfere, and they don't link to or do dbus calls into systemd either.
Lennart
Moreover, this doesn't affect cron at all. Cron creates its own PAM session for each job it runs which means those jobs are independent from any real login session (i.e. ssh, graphical, tty login), and thus also don't get cleaned up by them.
This affected stuff that is forked off a login session and then stays around as "orphan" if you so will, i.e. with all session resources released, except for these processes that try hard to avoid clean-up (usually by double forking + detaching explicitly from any TTY/ignoring SIGHUP).
Now I am used to taking blame for apparently everything that every went wrong on Linux, but you might as well blame your downstream distros for this as much you want to blame us upstream about this, as it's up to them to pick the right compile-time options matching their userbase and requirements in compatibility, and if they didn't do that to your liking, then maybe you should complain to them first.
(And yes, I still consider it a weakness of UNIX that "logout" doesn't really mean "logout", but just "maybe, please, if you'd be so kind, i'd like to exit, but not quite". I mean, that's not how you build a secure system. We fixed that really, fully knowing it would depart from UNIX tradition, but that's why we made it both compile-time and runtime configurable)
(Also, nobody has to "incorporate" systemd's library to avoid the automatic clean-up. In fact, there's no library we provide that could do that. What was requested though is to either run things as child of systemd --user or just register a separate PAM session, neither of which requires any systemd-specific library.)
Lennart
It doesn't. All this stuff is opt-in. If you don't want to use it, don't.
What's a bit unfair though is that you imply that the various technologies where equivalent in behaviour and would be different only in performance. That's really not the case. The eBPF stuff allows configuration of per-cgroup, i.e. per-service or per-container access control. And that's a massive advantage. Classic Netfilter doesn't allow that: you can't tell it to permit all traffic to bittorrentd.service, because service/container/cgroup information is not available to it. Yes, people have tried to make that work, and there was some support for it in the kernel, but only for egress, and that made it pretty useless ultimately.
You know, if iptables would allow us to configure tables per-service, we'd happily hook that up. Such a design is in fact where we started from originally. But the fact is that such a scheme isn't really compatible with Netfilter's design and thus didn't happen. And that that's the case is really not systemd's fault, but a technical decision of the kernel community.
I know it is fashionable to blame systemd for everything, but seriously, eBPF+cgroups and all that kind of stuff is the result of the kernel's development scheme, and systemd only follows that and exposes what they came up with. If you don't like where kernel development goes, please complain about and to the kernel community, but systemd is just a consumer of what they do, and I couldn't care less if per-service firewalling is ultimately implemented based on netfilter, on nftables or on ebpf/cgroup. As it turns out only the latter ended up being capable enough to make this possible. And I accept that, and then made use of this.
Do note that the port forward hookups in nspawn (i.e. --port=) are actually implemented using netfilter, not cgroups/ebpf. I hope that illustrates a bit that we use what works and is provided by the kernel community, and don't really follow an evil scheme here.
Lennart
I am not sure why you imply that there was some evil scheme behind all this. In reality, things are a bit different: one group at Red Hat decided to put an end to TCP wrappers (which btw is something other distros already did a while back, we are late at the party), and another group then offered to make a more modern replacement available, that could cover some of the uses, in order not leave users in the cold. I am not sure why you think that's an evil thing to do? Isn't it nicer to drop something with a suggestion how to replace it then to drop it without replacement?
Also, let's not forget: this functionality is implemented in the kernel, systemd merely adds knobs to expose this kernel functionality to the user. Hence, no, this functionality didn't really "show up in systemd". It showed up in the kernel, and systemd just wraps it to make it usable.
I mean, this is a dilemma, isn't it? Whatever we do you are unhappy, right? ;-)
Lennart