From bbc4f91f682e5f6a99da51ca2e290164e8bd8946 Mon Sep 17 00:00:00 2001 From: Stefan Meinecke Date: Sun, 18 Oct 2026 02:37:22 +0200 Subject: [PATCH] systemd: give socket-activated endpoints a default endpoint_cfg Sockets passed by systemd socket activation never get endpoint_cfg set, but inc_listen_connections() dereferences it unconditionally at accept() time. The first connection to a socket-activated unit therefore crashed the daemon with a NULL pointer dereference, and probe_client_protocol() dereferences it as well for the proxyprotocol check. Verified with a stub sd_listen_fds(): sslh-select segfaults (SIGSEGV) on the first connection to an activated socket before the fix, and forwards the connection normally after it. Assign a static zeroed sslhcfg_listen_item so these sockets behave as if configured with no max_connections limit and no proxyprotocol. --- common.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/common.c b/common.c index 1301813..9e98cb9 100644 --- a/common.c +++ b/common.c @@ -74,6 +74,13 @@ int get_fd_sockets(struct listen_endpoint *sockfd[]) int sd = 0; #ifdef SYSTEMD + /* Sockets passed by systemd socket activation do not correspond to a + * `listen` entry in the configuration, but code dereferences + * endpoint->endpoint_cfg unconditionally (e.g. inc_listen_connections() + * and probe_client_protocol()), so give them a default, empty + * configuration: no max_connections, no proxyprotocol. */ + static struct sslhcfg_listen_item default_endpoint_cfg; + sd = sd_listen_fds(0); if (sd < 0) { print_message(msg_system_error, "sd_listen_fds(): %s\n", strerror(-sd)); @@ -86,6 +93,7 @@ int get_fd_sockets(struct listen_endpoint *sockfd[]) for (i = 0; i < sd; i++) { (*sockfd)[i].socketfd = SD_LISTEN_FDS_START + i; (*sockfd)[i].type = SOCK_STREAM; + (*sockfd)[i].endpoint_cfg = &default_endpoint_cfg; } } #endif