Hacker News new | past | comments | ask | show | jobs | submit login

This refers to the fact that systemd was planning to drop the dependency on liblzma (the conpression library installed by xz), and instead dlopen it at runtime when needed. Not for security reasons, but to avoid pulling the libs into initramfs images.

The backdoor relies on sshd being patched to depend on libsystemd to call sd_notify(), which several distros had done.

OpenSSH has since merged a new patch upstream that implements similar logic to sd_notify() in sshd itself to allow distros to drop that patch.

So the attack surface of both sshd and libsystemd has since shrunk a bit.




> The backdoor relies on sshd being patched to depend on libsystemd to call sd_notify

I remember when we added sd_notify support to our services at work, I was wondering why one would pull in libsystemd as a dependency for this. I mean, there's a pure-Python library [1] that basically boils down to:

  import os, socket
  
  def notify(state=b"READY=1"):
    sock = socket.socket(socket.AF_UNIX, socket.SOCK_DGRAM)
    addr = os.getenv('NOTIFY_SOCKET')
    if addr[0] == '@':
     addr = '\0' + addr[1:]
    sock.connect(addr)
    sock.sendall(state)
With proper error handling, that's about 50 lines of C code. I would vendor that into my application in a heartbeat.

[1]: https://raw.githubusercontent.com/bb4242/sdnotify/master/sdn...


> With proper error handling, that's about 50 lines of C code.

Writing proper error handling in C is a very tedious and error prone task. So it doesn't surprise me that people would rather call another library instead.


> So it doesn't surprise me that people would rather call another library instead.

Which shall be harder to justify now: "You're calling a gigantic library full of potential security holes just to call one function, to save writing a few lines of code, are you trying to JIA TAN the project?".


> Writing proper error handling in C is a very tedious and error prone task.

Managing C dependencies is even more tedious and error prone. And even in C, opening a UNIX ___domain socket to write a single packet is not that hard.


You think error handling for a socket connection + send is outside the capabilities of those developing sshd?


You think every time people call an external library to save their effort is a proof of their lack of capabilities?


> I was wondering why one would pull in libsystemd as a dependency for this. I mean, there's a pure-Python library [...] With proper error handling, that's about 50 lines of C code.

There's also a pure C library (libsystemd itself) which already does all that, and you don't need to test all the error handling cases in your 50 lines of C code. It makes sense to use the battle-tested code, instead of writing your own.


The problem is people keep focusing on the libsystemd element because systemd has it's big hate-on crew and the vector was for what's deemed "simple".

The better question though is...okay, what if the code involved was not simple? xz is a full compression algorithm, compressors have been exploit vectors for a while, so rolling your own is a terrifically bad idea in almost all cases. There's plenty of other more sophisticated libraries as well where you could've tried to pull the exact same trick - there's nothing about it being a "simple" inclusion in this case which implies vendoring or rolling your own is a good mitigation.

The saying goes that everyone is always preparing to fight the last war, not the next (particularly relevant because adversaries are likely scouring OSS looking for other projects that might be amenable to this sort of attack - how many applications have network access these days? An RCE doesn't need to be in sshd).


Frankly, I think it is idiotic to require each program to parse an environment variable, open that named file, write a magic string, and all the error handling that that requires -- all for the purpose of having a backchannel between the daemon and its supervisor?

Compare with how s6 does the same thing: instead of passing a random path via an environment variable, it opens the file descriptor itself before exec()ing the binary. All the binary has to do is write a newline to that fd and close it.

No 50 lines of C code needed.




Consider applying for YC's Summer 2025 batch! Applications are open till May 13

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: