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))