From 764aa4e8dc55f144bdb237566a0dd75ef0c07576 Mon Sep 17 00:00:00 2001 From: Thomas De Backer Date: Mon, 8 Feb 2021 20:48:20 +0100 Subject: [PATCH 1/2] Correct interface binding Signed-off-by: Thomas De Backer --- src/net.c | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/src/net.c b/src/net.c index dcc9db3689..6733287009 100644 --- a/src/net.c +++ b/src/net.c @@ -640,7 +640,8 @@ static int net__bind_interface(struct mosquitto__listener *listener, struct addr } } freeifaddrs(ifaddr); - log__printf(NULL, MOSQ_LOG_ERR, "Error: Interface %s not found.", listener->bind_interface); + log__printf(NULL, MOSQ_LOG_WARNING, "Warning: Interface %s does not support %s.", + listener->bind_interface, rp->ai_addr->sa_family == AF_INET ? "ipv4" : "ipv6"); return MOSQ_ERR_NOT_FOUND; } #endif @@ -654,6 +655,9 @@ static int net__socket_listen_tcp(struct mosquitto__listener *listener) char service[10]; int rc; int ss_opt = 1; +#ifndef WIN32 + bool interface_bound = false; +#endif if(!listener) return MOSQ_ERR_INVAL; @@ -718,12 +722,14 @@ static int net__socket_listen_tcp(struct mosquitto__listener *listener) #ifndef WIN32 if(listener->bind_interface){ + /* It might be possible that an interface does not support all relevant sa_families. + * We should successfully find at least one. */ if(net__bind_interface(listener, rp)){ COMPAT_CLOSE(sock); - freeaddrinfo(ainfo); - mosquitto__free(listener->socks); - return 1; + listener->sock_count--; + continue; } + interface_bound = true; } #endif @@ -745,6 +751,13 @@ static int net__socket_listen_tcp(struct mosquitto__listener *listener) } freeaddrinfo(ainfo); +#ifndef WIN32 + if(listener->bind_interface && !interface_bound){ + mosquitto__free(listener->socks); + return 1; + } +#endif + return 0; } From fd2f764d361e038eae6140a3ee16dbf5c75c299f Mon Sep 17 00:00:00 2001 From: Thomas De Backer Date: Mon, 8 Feb 2021 23:36:21 +0100 Subject: [PATCH 2/2] Check host address binding before overwriting Signed-off-by: Thomas De Backer --- src/net.c | 38 ++++++++++++++++++++++++++------------ 1 file changed, 26 insertions(+), 12 deletions(-) diff --git a/src/net.c b/src/net.c index 6733287009..05b56d69ee 100644 --- a/src/net.c +++ b/src/net.c @@ -624,23 +624,37 @@ static int net__bind_interface(struct mosquitto__listener *listener, struct addr && ifa->ifa_addr->sa_family == rp->ai_addr->sa_family){ if(rp->ai_addr->sa_family == AF_INET){ - memcpy(&((struct sockaddr_in *)rp->ai_addr)->sin_addr, - &((struct sockaddr_in *)ifa->ifa_addr)->sin_addr, - sizeof(struct in_addr)); - - freeifaddrs(ifaddr); - return MOSQ_ERR_SUCCESS; + if(listener->host && + memcmp(&((struct sockaddr_in *)rp->ai_addr)->sin_addr, + &((struct sockaddr_in *)ifa->ifa_addr)->sin_addr, + sizeof(struct in_addr))){ + log__printf(NULL, MOSQ_LOG_WARNING, "Warning: Interface address does not match specified listener host."); + }else{ + memcpy(&((struct sockaddr_in *)rp->ai_addr)->sin_addr, + &((struct sockaddr_in *)ifa->ifa_addr)->sin_addr, + sizeof(struct in_addr)); + + freeifaddrs(ifaddr); + return MOSQ_ERR_SUCCESS; + } }else if(rp->ai_addr->sa_family == AF_INET6){ - memcpy(&((struct sockaddr_in6 *)rp->ai_addr)->sin6_addr, - &((struct sockaddr_in6 *)ifa->ifa_addr)->sin6_addr, - sizeof(struct in6_addr)); - freeifaddrs(ifaddr); - return MOSQ_ERR_SUCCESS; + if(listener->host && + memcmp(&((struct sockaddr_in6 *)rp->ai_addr)->sin6_addr, + &((struct sockaddr_in6 *)ifa->ifa_addr)->sin6_addr, + sizeof(struct in6_addr))){ + log__printf(NULL, MOSQ_LOG_WARNING, "Warning: Interface address does not match specified listener host."); + }else{ + memcpy(&((struct sockaddr_in6 *)rp->ai_addr)->sin6_addr, + &((struct sockaddr_in6 *)ifa->ifa_addr)->sin6_addr, + sizeof(struct in6_addr)); + freeifaddrs(ifaddr); + return MOSQ_ERR_SUCCESS; + } } } } freeifaddrs(ifaddr); - log__printf(NULL, MOSQ_LOG_WARNING, "Warning: Interface %s does not support %s.", + log__printf(NULL, MOSQ_LOG_WARNING, "Warning: Interface %s does not support %s configuration.", listener->bind_interface, rp->ai_addr->sa_family == AF_INET ? "ipv4" : "ipv6"); return MOSQ_ERR_NOT_FOUND; }