mirror of
https://github.com/yrutschle/sslh.git
synced 2026-10-22 18:12:10 +03:00
move unix path length checks to config_sanity_check()
cfg->host is static configuration, so an over-long path is a config error: validate it once at startup in config_sanity_check() for both is_unix listen endpoints and is_unix protocol targets, instead of at bind()/connect() time. This also fails fast for protocol targets, where the previous runtime check only dropped each connection instead of reporting the bad config. The memset()/bounded strncpy() calls stay in place: they are what make sun_path termination structurally safe regardless of the input length.
This commit is contained in:
1 parent
7afa284efc
commit
e20f2381c3
2 files changed
+21
-14
No files matched your search
@@ -205,13 +205,6 @@ static int start_listen_unix(struct listen_endpoint *sockfd[], int num_addr, str
|
||||
{
|
||||
struct sockaddr_un sun;
|
||||
|
||||
/* Fail before unlink()ing an existing file we could not bind anyway */
|
||||
if (strlen(cfg->host) >= sizeof(sun.sun_path)) {
|
||||
print_message(msg_config_error, "unix socket path too long (%zd, max %zd): %s\n",
|
||||
strlen(cfg->host), sizeof(sun.sun_path) - 1, cfg->host);
|
||||
exit(4);
|
||||
}
|
||||
|
||||
int fd = socket(AF_UNIX, cfg->is_udp ? SOCK_DGRAM : SOCK_STREAM, 0);
|
||||
CHECK_RES_DIE(fd, "socket(AF_UNIX)");
|
||||
|
||||
@@ -484,13 +477,6 @@ static int connect_unix(struct connection *cnx, int fd_from, connect_blocking bl
|
||||
struct sockaddr_storage ss;
|
||||
struct sockaddr_un* sun = (struct sockaddr_un*)&ss;
|
||||
|
||||
if (strlen(cnx->proto->host) >= sizeof(sun->sun_path)) {
|
||||
print_message(msg_system_error, "unix socket path too long (%zd, max %zd): %s\n",
|
||||
strlen(cnx->proto->host), sizeof(sun->sun_path) - 1,
|
||||
cnx->proto->host);
|
||||
return -1;
|
||||
}
|
||||
|
||||
memset(&ss, 0, sizeof(ss));
|
||||
sun->sun_family = AF_UNIX;
|
||||
strncpy(sun->sun_path, cnx->proto->host, sizeof(sun->sun_path)-1);
|
||||
|
||||
+21
@@ -30,6 +30,8 @@
|
||||
#include <pcre2.h>
|
||||
#endif
|
||||
|
||||
#include <sys/un.h>
|
||||
|
||||
#include "common.h"
|
||||
#include "probe.h"
|
||||
#include "log.h"
|
||||
@@ -277,6 +279,21 @@ static void config_sanity_libwrap(const struct sslhcfg_protocols_item* prot)
|
||||
#endif
|
||||
}
|
||||
|
||||
/* sun_path has a fixed, compile-time size (typically 108 chars): a configured
|
||||
* unix socket path that does not fit can never work, so reject it once at
|
||||
* startup rather than at bind()/connect() time */
|
||||
static void config_sanity_unix_path(const char* host)
|
||||
{
|
||||
size_t path_max = sizeof(((struct sockaddr_un*)0)->sun_path);
|
||||
|
||||
if (host && strlen(host) >= path_max) {
|
||||
print_message(msg_config_error,
|
||||
"unix socket path too long (%zd, max %zd): %s\n",
|
||||
strlen(host), path_max - 1, host);
|
||||
exit(4);
|
||||
}
|
||||
}
|
||||
|
||||
void config_sanity_check(struct sslhcfg_item* cfg)
|
||||
{
|
||||
size_t i;
|
||||
@@ -291,6 +308,8 @@ void config_sanity_check(struct sslhcfg_item* cfg)
|
||||
|
||||
for (i = 0; i < cfg->listen_len; i++) {
|
||||
config_sanity_listen_proxyprotocol(&cfg->listen[i]);
|
||||
if (cfg->listen[i].is_unix)
|
||||
config_sanity_unix_path(cfg->listen[i].host);
|
||||
}
|
||||
|
||||
for (i = 0; i < cfg->protocols_len; ++i) {
|
||||
@@ -312,6 +331,8 @@ void config_sanity_check(struct sslhcfg_item* cfg)
|
||||
config_sanity_regex(&cfg->protocols[i]);
|
||||
config_sanity_proxyprotocol(&cfg->protocols[i]);
|
||||
config_sanity_libwrap(&cfg->protocols[i]);
|
||||
if (cfg->protocols[i].is_unix)
|
||||
config_sanity_unix_path(cfg->protocols[i].host);
|
||||
|
||||
if (cfg->protocols[i].is_udp) {
|
||||
if (cfg->protocols[i].tfo_ok) {
|
||||
|
||||
Reference in new issue
Block a user