getifaddrs can return a struct ifaddrs entry with a NULL ifa_addr.
I think an unnumbered point-to-point interface can trigger this.
So better check for it before accessing anything in ifa_addr.

-- 
:wq Claudio

Index: config.c
===================================================================
RCS file: /cvs/src/usr.sbin/bgpd/config.c,v
retrieving revision 1.95
diff -u -p -r1.95 config.c
--- config.c    14 Feb 2020 13:54:31 -0000      1.95
+++ config.c    4 Dec 2020 11:46:33 -0000
@@ -339,7 +339,8 @@ get_bgpid(void)
                fatal("getifaddrs");
 
        for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
-               if (ifa->ifa_addr->sa_family != AF_INET)
+               if (ifa->ifa_addr == NULL ||
+                   ifa->ifa_addr->sa_family != AF_INET)
                        continue;
                cur = ((struct sockaddr_in *)ifa->ifa_addr)->sin_addr.s_addr;
                if ((cur & localnet) == localnet)       /* skip 127/8 */
Index: session.c
===================================================================
RCS file: /cvs/src/usr.sbin/bgpd/session.c,v
retrieving revision 1.406
diff -u -p -r1.406 session.c
--- session.c   11 Dec 2020 12:00:01 -0000      1.406
+++ session.c   17 Dec 2020 12:18:54 -0000
@@ -1223,7 +1223,8 @@ get_alternate_addr(struct sockaddr *sa, 
                fatal("getifaddrs");
 
        for (match = ifap; match != NULL; match = match->ifa_next)
-               if (sa_cmp(sa, match->ifa_addr) == 0)
+               if (match->ifa_addr != NULL &&
+                   sa_cmp(sa, match->ifa_addr) == 0)
                        break;
 
        if (match == NULL) {
@@ -1234,7 +1235,8 @@ get_alternate_addr(struct sockaddr *sa, 
        switch (sa->sa_family) {
        case AF_INET6:
                for (ifa = ifap; ifa != NULL; ifa = ifa->ifa_next) {
-                       if (ifa->ifa_addr->sa_family == AF_INET &&
+                       if (ifa->ifa_addr != NULL &&
+                           ifa->ifa_addr->sa_family == AF_INET &&
                            strcmp(ifa->ifa_name, match->ifa_name) == 0) {
                                sa2addr(ifa->ifa_addr, alt, NULL);
                                break;
@@ -1243,10 +1245,12 @@ get_alternate_addr(struct sockaddr *sa, 
                break;
        case AF_INET:
                for (ifa = ifap; ifa != NULL; ifa = ifa->ifa_next) {
-                       struct sockaddr_in6 *s =
-                           (struct sockaddr_in6 *)ifa->ifa_addr;
-                       if (ifa->ifa_addr->sa_family == AF_INET6 &&
+                       if (ifa->ifa_addr != NULL &&
+                           ifa->ifa_addr->sa_family == AF_INET6 &&
                            strcmp(ifa->ifa_name, match->ifa_name) == 0) {
+                               struct sockaddr_in6 *s =
+                                   (struct sockaddr_in6 *)ifa->ifa_addr;
+
                                /* only accept global scope addresses */
                                if (IN6_IS_ADDR_LINKLOCAL(&s->sin6_addr) ||
                                    IN6_IS_ADDR_SITELOCAL(&s->sin6_addr))

Reply via email to