# HG changeset patch # User Roy Marples # Date 1601483132 -3600 # Node ID 6cd47402148f95e56c84c351b180e43aa93b8024 # Parent df4ea0197ce89bc914cb8a8d94bd25e93793b9ce privsep: We now need to carry ifa_data for BSD diff -r df4ea0197ce8 -r 6cd47402148f src/privsep-root.c --- a/src/privsep-root.c Wed Sep 30 16:14:39 2020 +0100 +++ b/src/privsep-root.c Wed Sep 30 17:25:32 2020 +0100 @@ -346,15 +346,14 @@ #endif #ifdef PRIVSEP_GETIFADDRS -#define IFA_NADDRS 3 +#define IFA_NADDRS 4 static ssize_t ps_root_dogetifaddrs(void **rdata, size_t *rlen) { - struct ifaddrs *ifaddrs, *ifa, *ifa_next; + struct ifaddrs *ifaddrs, *ifa; size_t len; uint8_t *buf, *sap; socklen_t salen; - void *ifa_data; if (getifaddrs(&ifaddrs) == -1) return -1; @@ -380,6 +379,15 @@ len += ALIGN(sa_len(ifa->ifa_netmask)); if (ifa->ifa_broadaddr != NULL) len += ALIGN(sa_len(ifa->ifa_broadaddr)); +#ifdef BSD + /* + * On BSD we need to carry ifa_data so we can access + * if_data->ifi_link_state + */ + if (ifa->ifa_addr != NULL && + ifa->ifa_addr->sa_family == AF_LINK) + len += ALIGN(sizeof(struct if_data)); +#endif } /* Use calloc to set everything to zero. @@ -394,15 +402,8 @@ *rlen = len; for (ifa = ifaddrs; ifa != NULL; ifa = ifa->ifa_next) { - /* Don't carry ifa_data or ifa_next. */ - ifa_data = ifa->ifa_data; - ifa_next = ifa->ifa_next; - ifa->ifa_data = NULL; - ifa->ifa_next = NULL; memcpy(buf, ifa, sizeof(*ifa)); buf += ALIGN(sizeof(*ifa)); - ifa->ifa_data = ifa_data; - ifa->ifa_next = ifa_next; strlcpy((char *)buf, ifa->ifa_name, IFNAMSIZ); buf += ALIGN(IFNAMSIZ); @@ -411,7 +412,10 @@ #define COPYINSA(addr) \ do { \ - salen = sa_len((addr)); \ + if ((addr) != NULL) \ + salen = sa_len((addr)); \ + else \ + salen = 0; \ if (salen != 0) { \ memcpy(sap, &salen, sizeof(salen)); \ memcpy(buf, (addr), salen); \ @@ -420,12 +424,21 @@ sap += sizeof(salen); \ } while (0 /*CONSTCOND */) - if (ifa->ifa_addr != NULL) - COPYINSA(ifa->ifa_addr); - if (ifa->ifa_netmask != NULL) - COPYINSA(ifa->ifa_netmask); - if (ifa->ifa_broadaddr != NULL) - COPYINSA(ifa->ifa_broadaddr); + COPYINSA(ifa->ifa_addr); + COPYINSA(ifa->ifa_netmask); + COPYINSA(ifa->ifa_broadaddr); + +#ifdef BSD + if (ifa->ifa_addr != NULL && + ifa->ifa_addr->sa_family == AF_LINK) + { + salen = (socklen_t)sizeof(struct if_data); + memcpy(buf, ifa->ifa_data, salen); + buf += ALIGN(salen); + } else +#endif + salen = 0; + memcpy(sap, &salen, sizeof(salen)); } freeifaddrs(ifaddrs); @@ -948,6 +961,17 @@ COPYOUTSA(ifa->ifa_addr); COPYOUTSA(ifa->ifa_netmask); COPYOUTSA(ifa->ifa_broadaddr); + + memcpy(&salen, sap, sizeof(salen)); + if (len < salen) + goto err; + if (salen != 0) { + ifa->ifa_data = bp; + bp += ALIGN(salen); + len -= ALIGN(salen); + } else + ifa->ifa_data = NULL; + if (len != 0) ifa->ifa_next = (struct ifaddrs *)(void *)bp; else