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.
This commit is contained in:
Stefan Meinecke authored and Yves Rutschle committed 2026-10-18 22:23:01 +02:00
1 parent e20f2381c3
commit bbc4f91f68
1 file changed
+8
+8
View File
@@ -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