Skip to content

Commit

Permalink
openssh: systemd notification was implemented upstream
Browse files Browse the repository at this point in the history
Still side effects of the XZ backdoor. The systemd sd-notify patch
was rejected [1] upstream and was chosen a standalone implementation
that does not depend on libsystemd [2].

Racional [1]:

License incompatibility and library bloatedness were the reasons.
Given recent events we're never going to take a dependency on libsystemd,
though we might implement the notification protocol ourselves if it isn't too much work.

[1] openssh/openssh-portable#375 (comment)
[2] openssh/openssh-portable@08f5792

(From OE-Core rev: 79a68cbb7a5401d035d0cf837024ac1c78f475a1)

Signed-off-by: Jose Quaresma <[email protected]>
Signed-off-by: Richard Purdie <[email protected]>
  • Loading branch information
quaresmajose authored and rpurdie committed Jul 16, 2024
1 parent 8516537 commit 25ebb20
Show file tree
Hide file tree
Showing 5 changed files with 228 additions and 100 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,225 @@
From fc73e2405a8ca928465580b74a4d76112919367b Mon Sep 17 00:00:00 2001
From: Damien Miller <[email protected]>
Date: Wed, 3 Apr 2024 14:40:32 +1100
Subject: [PATCH] notify systemd on listen and reload

Standalone implementation that does not depend on libsystemd.
With assistance from Luca Boccassi, and feedback/testing from Colin
Watson. bz2641

Upstream-Status: Backport [https://github.com/openssh/openssh-portable/commit/08f579231cd38a1c657aaa6ddeb8ab57a1fd4f5c]

Signed-off-by: Jose Quaresma <[email protected]>
---
configure.ac | 1 +
openbsd-compat/port-linux.c | 97 ++++++++++++++++++++++++++++++++++++-
openbsd-compat/port-linux.h | 5 ++
platform.c | 11 +++++
platform.h | 1 +
sshd.c | 2 +
6 files changed, 115 insertions(+), 2 deletions(-)

diff --git a/configure.ac b/configure.ac
index 82e8bb7c1..854f92b5b 100644
--- a/configure.ac
+++ b/configure.ac
@@ -915,6 +915,7 @@ int main(void) { if (NSVersionOfRunTimeLibrary("System") >= (60 << 16))
AC_DEFINE([_PATH_BTMP], ["/var/log/btmp"], [log for bad login attempts])
AC_DEFINE([USE_BTMP])
AC_DEFINE([LINUX_OOM_ADJUST], [1], [Adjust Linux out-of-memory killer])
+ AC_DEFINE([SYSTEMD_NOTIFY], [1], [Have sshd notify systemd on start/reload])
inet6_default_4in6=yes
case `uname -r` in
1.*|2.0.*)
diff --git a/openbsd-compat/port-linux.c b/openbsd-compat/port-linux.c
index 0457e28d0..df7290246 100644
--- a/openbsd-compat/port-linux.c
+++ b/openbsd-compat/port-linux.c
@@ -21,16 +21,23 @@

#include "includes.h"

-#if defined(WITH_SELINUX) || defined(LINUX_OOM_ADJUST)
+#if defined(WITH_SELINUX) || defined(LINUX_OOM_ADJUST) || \
+ defined(SYSTEMD_NOTIFY)
+#include <sys/socket.h>
+#include <sys/un.h>
+
#include <errno.h>
+#include <inttypes.h>
#include <stdarg.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
+#include <time.h>

#include "log.h"
#include "xmalloc.h"
#include "port-linux.h"
+#include "misc.h"

#ifdef WITH_SELINUX
#include <selinux/selinux.h>
@@ -310,4 +317,90 @@ oom_adjust_restore(void)
return;
}
#endif /* LINUX_OOM_ADJUST */
-#endif /* WITH_SELINUX || LINUX_OOM_ADJUST */
+
+#ifdef SYSTEMD_NOTIFY
+
+static void ssh_systemd_notify(const char *, ...)
+ __attribute__((__format__ (printf, 1, 2))) __attribute__((__nonnull__ (1)));
+
+static void
+ssh_systemd_notify(const char *fmt, ...)
+{
+ char *s = NULL;
+ const char *path;
+ struct stat sb;
+ struct sockaddr_un addr;
+ int fd = -1;
+ va_list ap;
+
+ if ((path = getenv("NOTIFY_SOCKET")) == NULL || strlen(path) == 0)
+ return;
+
+ va_start(ap, fmt);
+ xvasprintf(&s, fmt, ap);
+ va_end(ap);
+
+ /* Only AF_UNIX is supported, with path or abstract sockets */
+ if (path[0] != '/' && path[0] != '@') {
+ error_f("socket \"%s\" is not compatible with AF_UNIX", path);
+ goto out;
+ }
+
+ if (path[0] == '/' && stat(path, &sb) != 0) {
+ error_f("socket \"%s\" stat: %s", path, strerror(errno));
+ goto out;
+ }
+
+ memset(&addr, 0, sizeof(addr));
+ addr.sun_family = AF_UNIX;
+ if (strlcpy(addr.sun_path, path,
+ sizeof(addr.sun_path)) >= sizeof(addr.sun_path)) {
+ error_f("socket path \"%s\" too long", path);
+ goto out;
+ }
+ /* Support for abstract socket */
+ if (addr.sun_path[0] == '@')
+ addr.sun_path[0] = 0;
+ if ((fd = socket(PF_UNIX, SOCK_DGRAM, 0)) == -1) {
+ error_f("socket \"%s\": %s", path, strerror(errno));
+ goto out;
+ }
+ if (connect(fd, &addr, sizeof(addr)) != 0) {
+ error_f("socket \"%s\" connect: %s", path, strerror(errno));
+ goto out;
+ }
+ if (write(fd, s, strlen(s)) != (ssize_t)strlen(s)) {
+ error_f("socket \"%s\" write: %s", path, strerror(errno));
+ goto out;
+ }
+ debug_f("socket \"%s\" notified %s", path, s);
+ out:
+ if (fd != -1)
+ close(fd);
+ free(s);
+}
+
+void
+ssh_systemd_notify_ready(void)
+{
+ ssh_systemd_notify("READY=1");
+}
+
+void
+ssh_systemd_notify_reload(void)
+{
+ struct timespec now;
+
+ monotime_ts(&now);
+ if (now.tv_sec < 0 || now.tv_nsec < 0) {
+ error_f("monotime returned negative value");
+ ssh_systemd_notify("RELOADING=1");
+ } else {
+ ssh_systemd_notify("RELOADING=1\nMONOTONIC_USEC=%llu",
+ ((uint64_t)now.tv_sec * 1000000ULL) +
+ ((uint64_t)now.tv_nsec / 1000ULL));
+ }
+}
+#endif /* SYSTEMD_NOTIFY */
+
+#endif /* WITH_SELINUX || LINUX_OOM_ADJUST || SYSTEMD_NOTIFY */
diff --git a/openbsd-compat/port-linux.h b/openbsd-compat/port-linux.h
index 3c22a854d..14064f87d 100644
--- a/openbsd-compat/port-linux.h
+++ b/openbsd-compat/port-linux.h
@@ -30,4 +30,9 @@ void oom_adjust_restore(void);
void oom_adjust_setup(void);
#endif

+#ifdef SYSTEMD_NOTIFY
+void ssh_systemd_notify_ready(void);
+void ssh_systemd_notify_reload(void);
+#endif
+
#endif /* ! _PORT_LINUX_H */
diff --git a/platform.c b/platform.c
index 4fe8744ee..9cf818153 100644
--- a/platform.c
+++ b/platform.c
@@ -44,6 +44,14 @@ platform_pre_listen(void)
#endif
}

+void
+platform_post_listen(void)
+{
+#ifdef SYSTEMD_NOTIFY
+ ssh_systemd_notify_ready();
+#endif
+}
+
void
platform_pre_fork(void)
{
@@ -55,6 +63,9 @@ platform_pre_fork(void)
void
platform_pre_restart(void)
{
+#ifdef SYSTEMD_NOTIFY
+ ssh_systemd_notify_reload();
+#endif
#ifdef LINUX_OOM_ADJUST
oom_adjust_restore();
#endif
diff --git a/platform.h b/platform.h
index 7fef8c983..5dec23276 100644
--- a/platform.h
+++ b/platform.h
@@ -21,6 +21,7 @@
void platform_pre_listen(void);
void platform_pre_fork(void);
void platform_pre_restart(void);
+void platform_post_listen(void);
void platform_post_fork_parent(pid_t child_pid);
void platform_post_fork_child(void);
int platform_privileged_uidswap(void);
diff --git a/sshd.c b/sshd.c
index b4f2b9742..865331b46 100644
--- a/sshd.c
+++ b/sshd.c
@@ -2077,6 +2077,8 @@ main(int ac, char **av)
ssh_signal(SIGTERM, sigterm_handler);
ssh_signal(SIGQUIT, sigterm_handler);

+ platform_post_listen();
+
/*
* Write out the pid file after the sigterm handler
* is setup and the listen sockets are bound
--
2.45.2

This file was deleted.

2 changes: 1 addition & 1 deletion meta/recipes-connectivity/openssh/openssh/sshd.service
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@ After=sshdgenkeys.service
After=nss-user-lookup.target

[Service]
Type=notify-reload
Environment="SSHD_OPTS="
EnvironmentFile=-/etc/default/ssh
ExecStartPre=@BASE_BINDIR@/mkdir -p /var/run/sshd
ExecStart=-@SBINDIR@/sshd -D $SSHD_OPTS
ExecReload=@BASE_BINDIR@/kill -HUP $MAINPID
KillMode=process
Restart=on-failure
RestartSec=42s
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ Description=OpenSSH Per-Connection Daemon
After=sshdgenkeys.service

[Service]
Type=notify-reload
Environment="SSHD_OPTS="
EnvironmentFile=-/etc/default/ssh
ExecStart=-@SBINDIR@/sshd -i $SSHD_OPTS
Expand Down
4 changes: 1 addition & 3 deletions meta/recipes-connectivity/openssh/openssh_9.7p1.bb
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ SRC_URI = "http://ftp.openbsd.org/pub/OpenBSD/OpenSSH/portable/openssh-${PV}.tar
file://run-ptest \
file://sshd_check_keys \
file://0001-regress-banner.sh-log-input-and-output-files-on-erro.patch \
file://0001-systemd-Add-optional-support-for-systemd-sd_notify.patch \
file://0001-notify-systemd-on-listen-and-reload.patch \
file://CVE-2024-6387.patch \
"
SRC_URI[sha256sum] = "490426f766d82a2763fcacd8d83ea3d70798750c7bd2aff2e57dc5660f773ffd"
Expand Down Expand Up @@ -52,7 +52,6 @@ SYSTEMD_PACKAGES = "${PN}-sshd"
SYSTEMD_SERVICE:${PN}-sshd = "${@bb.utils.contains('PACKAGECONFIG','systemd-sshd-socket-mode','sshd.socket', '', d)} ${@bb.utils.contains('PACKAGECONFIG','systemd-sshd-service-mode','sshd.service', '', d)}"

inherit autotools-brokensep ptest pkgconfig
DEPENDS += "${@bb.utils.contains('DISTRO_FEATURES', 'systemd', 'systemd', '', d)}"

# systemd-sshd-socket-mode means installing sshd.socket
# and systemd-sshd-service-mode corresponding to sshd.service
Expand All @@ -78,7 +77,6 @@ EXTRA_OECONF = "'LOGIN_PROGRAM=${base_bindir}/login' \
--sysconfdir=${sysconfdir}/ssh \
--with-xauth=${bindir}/xauth \
--disable-strip \
${@bb.utils.contains('DISTRO_FEATURES', 'systemd', '--with-systemd', '--without-systemd', d)} \
"

# musl doesn't implement wtmp/utmp and logwtmp
Expand Down

0 comments on commit 25ebb20

Please sign in to comment.