On Di, 27.06.23 13:36, Adrian Vovk (adrianvovk@xxxxxxxxx) 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