From 426f322c58be3a89cd617c9ec57ec2cfbae34814 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Marczykowski-G=C3=B3recki?= Date: Sat, 8 Dec 2018 12:32:56 +0100 Subject: [PATCH] qrexec: add startup notification Avoid race conditions with services ordered shortly after qrexec start. Make systemd know when qrexec-agent is really ready to serve. Fixes QubesOS/qubes-issues#3985 --- qrexec/qrexec-agent.c | 40 +++++++++++++++++++++++++++ vm-systemd/qubes-qrexec-agent.service | 1 + 2 files changed, 41 insertions(+) diff --git a/qrexec/qrexec-agent.c b/qrexec/qrexec-agent.c index f9b4ff7..e368eb2 100644 --- a/qrexec/qrexec-agent.c +++ b/qrexec/qrexec-agent.c @@ -309,6 +309,42 @@ void handle_vchan_error(const char *op) exit(1); } +int my_sd_notify(int unset_environment, const char *state) { + struct sockaddr_un addr; + int fd; + int ret = -1; + + addr.sun_family = AF_UNIX; + strncpy(addr.sun_path, getenv("NOTIFY_SOCKET"), sizeof(addr.sun_path)-1); + addr.sun_path[sizeof(addr.sun_path)-1] = '\0'; + if (addr.sun_path[0] == '@') + addr.sun_path[0] = '\0'; + + if (unset_environment) + unsetenv("NOTIFY_SOCKET"); + + fd = socket(AF_UNIX, SOCK_DGRAM, 0); + if (fd == -1) { + perror("sd_notify socket"); + return -1; + } + + if (connect(fd, &addr, sizeof(addr)) == -1) { + perror("sd_notify connect"); + goto out; + } + + if (send(fd, state, strlen(state), 0) == -1) { + perror("sd_notify send"); + goto out; + } + + ret = 0; +out: + close(fd); + return ret; +} + void init() { mode_t old_umask; @@ -326,6 +362,10 @@ void init() /* wait for qrexec daemon */ while (!libvchan_is_open(ctrl_vchan)) libvchan_wait(ctrl_vchan); + + if (getenv("NOTIFY_SOCKET")) { + my_sd_notify(1, "READY=1"); + } } void wake_meminfo_writer() diff --git a/vm-systemd/qubes-qrexec-agent.service b/vm-systemd/qubes-qrexec-agent.service index 3c49b86..b09480a 100644 --- a/vm-systemd/qubes-qrexec-agent.service +++ b/vm-systemd/qubes-qrexec-agent.service @@ -3,6 +3,7 @@ Description=Qubes remote exec agent After=xendriverdomain.service [Service] +Type=notify ExecStartPre=/bin/sh -c '[ -e /dev/xen/evtchn ] || modprobe xen_evtchn' ExecStart=/usr/lib/qubes/qrexec-agent