From e231ac1f45b556fb1b106d70e29e07b0589c5d2e Mon Sep 17 00:00:00 2001
From: Reiner Hauser <Reiner.Hauser@cern.ch>
Date: Fri, 15 Dec 2023 10:32:13 +0100
Subject: [PATCH] Fix crash when wireguard is enabled

The special wireguard interface has its ifa_addr pointer set to
null, leading to a crash in NameService::publish() which iterates
over all interfaces, checking ifa_addr->family.

Protection against ifa_addr == nullptr were added in various places.
---
 src/Interface.cxx | 18 ++++++++++--------
 1 file changed, 10 insertions(+), 8 deletions(-)

diff --git a/src/Interface.cxx b/src/Interface.cxx
index edc64b1..644b32a 100644
--- a/src/Interface.cxx
+++ b/src/Interface.cxx
@@ -47,7 +47,7 @@ namespace daq {
         // Return the address family.
         int Interface::family() const
         {
-            return m_addr->ifa_addr->sa_family;
+            return (m_addr->ifa_addr ? m_addr->ifa_addr->sa_family : AF_UNSPEC);
         }
 
         /** The internal interface index (usually starting at 1) */
@@ -71,7 +71,7 @@ namespace daq {
         /** The IP address of this interface or 0 */
         in_addr_t Interface::address() const
         {
-            if(m_addr->ifa_addr->sa_family == AF_INET) {
+            if(m_addr->ifa_addr && (m_addr->ifa_addr->sa_family == AF_INET)) {
                 return ((sockaddr_in *)m_addr->ifa_addr)->sin_addr.s_addr;
             } else {
                 return 0;
@@ -81,7 +81,7 @@ namespace daq {
         /** The IP address of this interface or 0 */
         in6_addr Interface::address_v6() const
         {
-            if(m_addr->ifa_addr->sa_family == AF_INET6 ) {
+            if(m_addr->ifa_addr && (m_addr->ifa_addr->sa_family == AF_INET6)) {
                 return ((sockaddr_in6 *)m_addr->ifa_addr)->sin6_addr;
             } else {
                 return in6addr_any;
@@ -92,14 +92,16 @@ namespace daq {
         std::string Interface::address_string() const
         {
             char buf[INET6_ADDRSTRLEN+1]= { 0 };
-            getnameinfo(m_addr->ifa_addr, sizeof(sockaddr_storage), buf, sizeof(buf), 0, 0, NI_NUMERICHOST);
+            if(m_addr->ifa_addr) {
+                getnameinfo(m_addr->ifa_addr, sizeof(sockaddr_storage), buf, sizeof(buf), 0, 0, NI_NUMERICHOST);
+            }
             return buf;
         }
 
         /** The broadcast IP address of this interface or 0 */
         in_addr_t Interface::broadcast() const
         {
-            if(m_addr->ifa_addr->sa_family == AF_INET) {
+            if(m_addr->ifa_addr && (m_addr->ifa_addr->sa_family == AF_INET)) {
                 return ((sockaddr_in *)m_addr->ifa_broadaddr)->sin_addr.s_addr;
             } else {
                 return 0;
@@ -110,7 +112,7 @@ namespace daq {
         std::string Interface::broadcast_string() const
         {
             char buf[INET_ADDRSTRLEN] = { 0 };
-            if(m_addr->ifa_addr->sa_family == AF_INET && m_addr->ifa_broadaddr) {
+            if(m_addr->ifa_addr && (m_addr->ifa_addr->sa_family == AF_INET && m_addr->ifa_broadaddr)) {
                 getnameinfo(m_addr->ifa_broadaddr, sizeof(sockaddr_in), buf, sizeof(buf), 0, 0, NI_NUMERICHOST);
             }
             return buf;
@@ -198,12 +200,12 @@ namespace daq {
         const Interface::InterfaceList& Interface::interfaces()
         {
             if(s_interfaces.size() == 0) {
-                
+
                 getifaddrs(&s_addresses);
                 struct ifaddrs *ptr = s_addresses;
 
                 while(ptr) {
-                    if(ptr->ifa_addr->sa_family == AF_INET || ptr->ifa_addr->sa_family == AF_INET6) {
+                    if(ptr->ifa_addr && (ptr->ifa_addr->sa_family == AF_INET || ptr->ifa_addr->sa_family == AF_INET6)) {
                         s_interfaces.push_back(new Interface(ptr));
                     }
                     ptr = ptr->ifa_next;
-- 
GitLab