diff options
| author | Roy Marples <roy@marples.name> | 2020-09-30 17:25:32 +0100 |
|---|---|---|
| committer | Roy Marples <roy@marples.name> | 2020-09-30 17:25:32 +0100 |
| commit | c4c15d9a6423827ea80cc537e6f7fcf7d6fc172d (patch) | |
| tree | 5dbd87c6936b170bb34a7c372f3299ad4f316978 /src/privsep-root.c | |
| parent | 3ef993986b2ac5aca49ecf10f04fe5fc067473cd (diff) | |
| download | dhcpcd-c4c15d9a6423827ea80cc537e6f7fcf7d6fc172d.tar.xz | |
privsep: We now need to carry ifa_data for BSD
Diffstat (limited to 'src/privsep-root.c')
| -rw-r--r-- | src/privsep-root.c | 58 |
1 files changed, 41 insertions, 17 deletions
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 |
