From: Roy Marples Date: Wed, 30 Sep 2020 16:25:32 +0000 (+0100) Subject: privsep: We now need to carry ifa_data for BSD X-Git-Tag: v9.3.0~5 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c4c15d9a6423827ea80cc537e6f7fcf7d6fc172d;p=thirdparty%2Fdhcpcd.git privsep: We now need to carry ifa_data for BSD --- diff --git a/src/privsep-root.c b/src/privsep-root.c index 92faec4c..770dd953 100644 --- a/src/privsep-root.c +++ b/src/privsep-root.c @@ -346,15 +346,14 @@ ps_root_monordm(uint64_t *rdm, size_t len) #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 @@ ps_root_dogetifaddrs(void **rdata, size_t *rlen) 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 @@ ps_root_dogetifaddrs(void **rdata, size_t *rlen) *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 @@ ps_root_dogetifaddrs(void **rdata, size_t *rlen) #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 @@ ps_root_dogetifaddrs(void **rdata, size_t *rlen) 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 @@ ps_root_getifaddrs(struct dhcpcd_ctx *ctx, struct ifaddrs **ifahead) 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