unix: fix uv_interface_addresses()

The memset() in the inner loop clears previously copied phys_addrs. As a
result, every interface is reported to have a phys_addr of
00:00:00:00:00:00, except the last one. This bug only manifests on
systems with multiple interfaces.

PR-URL: https://github.com/libuv/libuv/pull/2153
Reviewed-By: Jameson Nash <vtjnash@gmail.com>
Reviewed-By: Santiago Gimeno <santiago.gimeno@gmail.com>
This commit is contained in:
Andreas Rohner 2019-01-13 23:09:22 +01:00 committed by Santiago Gimeno
parent 99440bb673
commit d0fb86cdf3
No known key found for this signature in database
GPG Key ID: F28C3C8DA33C03BE
2 changed files with 6 additions and 10 deletions

View File

@ -84,7 +84,8 @@ int uv_interface_addresses(uv_interface_address_t** addresses, int* count) {
return 0; return 0;
} }
*addresses = uv__malloc(*count * sizeof(**addresses)); /* Make sure the memory is initiallized to zero using calloc() */
*addresses = uv__calloc(*count, sizeof(**addresses));
if (*addresses == NULL) { if (*addresses == NULL) {
freeifaddrs(addrs); freeifaddrs(addrs);
@ -116,6 +117,7 @@ int uv_interface_addresses(uv_interface_address_t** addresses, int* count) {
address++; address++;
} }
#if !(defined(__CYGWIN__) || defined(__MSYS__))
/* Fill in physical addresses for each interface */ /* Fill in physical addresses for each interface */
for (ent = addrs; ent != NULL; ent = ent->ifa_next) { for (ent = addrs; ent != NULL; ent = ent->ifa_next) {
if (uv__ifaddr_exclude(ent, UV__EXCLUDE_IFPHYS)) if (uv__ifaddr_exclude(ent, UV__EXCLUDE_IFPHYS))
@ -124,20 +126,15 @@ int uv_interface_addresses(uv_interface_address_t** addresses, int* count) {
address = *addresses; address = *addresses;
for (i = 0; i < *count; i++) { for (i = 0; i < *count; i++) {
#if defined(__CYGWIN__) || defined(__MSYS__)
memset(address->phys_addr, 0, sizeof(address->phys_addr));
#else
if (strcmp(address->name, ent->ifa_name) == 0) { if (strcmp(address->name, ent->ifa_name) == 0) {
struct sockaddr_dl* sa_addr; struct sockaddr_dl* sa_addr;
sa_addr = (struct sockaddr_dl*)(ent->ifa_addr); sa_addr = (struct sockaddr_dl*)(ent->ifa_addr);
memcpy(address->phys_addr, LLADDR(sa_addr), sizeof(address->phys_addr)); memcpy(address->phys_addr, LLADDR(sa_addr), sizeof(address->phys_addr));
} else {
memset(address->phys_addr, 0, sizeof(address->phys_addr));
} }
#endif
address++; address++;
} }
} }
#endif
freeifaddrs(addrs); freeifaddrs(addrs);

View File

@ -860,7 +860,8 @@ int uv_interface_addresses(uv_interface_address_t** addresses, int* count) {
return 0; return 0;
} }
*addresses = uv__malloc(*count * sizeof(**addresses)); /* Make sure the memory is initiallized to zero using calloc() */
*addresses = uv__calloc(*count, sizeof(**addresses));
if (!(*addresses)) { if (!(*addresses)) {
freeifaddrs(addrs); freeifaddrs(addrs);
return UV_ENOMEM; return UV_ENOMEM;
@ -902,8 +903,6 @@ int uv_interface_addresses(uv_interface_address_t** addresses, int* count) {
if (strcmp(address->name, ent->ifa_name) == 0) { if (strcmp(address->name, ent->ifa_name) == 0) {
sll = (struct sockaddr_ll*)ent->ifa_addr; sll = (struct sockaddr_ll*)ent->ifa_addr;
memcpy(address->phys_addr, sll->sll_addr, sizeof(address->phys_addr)); memcpy(address->phys_addr, sll->sll_addr, sizeof(address->phys_addr));
} else {
memset(address->phys_addr, 0, sizeof(address->phys_addr));
} }
address++; address++;
} }