[systemd-devel] Anonymous SYSTEMD_NOTIFY socket
Lennart Poettering
lennart at poettering.net
Wed Jun 28 13:28:09 UTC 2023
On Di, 27.06.23 13:36, Adrian Vovk (adrianvovk at gmail.com) wrote:
> Hello!
>
> I'm working on passing sd_notify events from systemd-{pull,import} through
> sysupdate.
>
> All services that consume sd_notify events (systemd itself, importd,
> machined, homed, etc) act as daemons and own a directory in /run. Thus,
> they can open a notification socket at, say, /run/SERVICENAME/notify and
> set NOTIFY_SOCKET to that. Also, there's no cleanup involved: if the
> service goes away the file sticks around until the service is restarted.
>
> sysupdate, however, is the first instance of a worker process forking off
> another worker process. Thus, we cannot bind the notify socket to some
> stable name. Here are potential approaches I've explored to solve this:
>
> - Simply pass through the NOTIFY_SOCKET environment variable. That's not
> suitable because we want to export an overall progress value (smoothly from
> 0 to 100), but systemd-import is forked off multiple times so we'd instead
> export a progress value that bounces around from 0 to 100 and back to 0.
> Also progress messages would come from different PIDs for a single
> invocation of sysupdate
>
> - Create a temporary file and use that as the socket. Problem: What happens
> if systemd-sysupdate crashes and we don't get to clean up that file? Over
> time that potentially clutters up /tmp! Is this a concern?
>
> - Use socketpair to open an anonymous socket and pass it into the child.
> This one seems ideal on paper but it doesn't actually work. I can modify
> sd_notify to just use an open file descriptor instead of tying to open its
> own, and that does work except for some reason process credentials aren't
> sent over. Also using the socket pair method doesn't work all that well
> with CLOEXEC, though maybe we don't want to CLOEXEC (We'd only close the
> socket when sd_notify is called with unset_env=true)
>
> - Create an abstract socket, named after the PID of the parent sysupdate.
> i.e. @/run/sysupdate/PID/notify. I'm not super familiar with abstract
> sockets so I'm not sure of the downsides
>
> Which approach would you suggest?
Use an abstract socket for this, with a randomized name, to avoid DoS
scenarios (i.e. include a formatted value of random_u64() in the
socket address).
abstract namespace sockets are nice for things like this, but they are
inherently vulnerable to DoS attacks if you use a fixed name since the
namespace knows not access controls: everyone can grab any socket they
like.
Make sure to look at the source PID (i..e SCM_CREDENTIALS) before
using incoming data.
Lennart
--
Lennart Poettering, Berlin
More information about the systemd-devel
mailing list