Extract the raw_free() of ifc_buf into a new function.

Explain the problem more correctly.
This commit is contained in:
Nick Mathewson 2018-01-10 09:51:45 -05:00
parent 54899b404c
commit f71bbd20a4

View File

@ -1515,6 +1515,18 @@ get_interface_addresses_win32(int severity, sa_family_t family)
#define _SIZEOF_ADDR_IFREQ sizeof #define _SIZEOF_ADDR_IFREQ sizeof
#endif #endif
/* Free ifc->ifc_buf safely. */
static void
ifconf_free_ifc_buf(struct ifconf *ifc)
{
/* On macOS, tor_free() takes the address of ifc.ifc_buf, which leads to
* undefined behaviour, because pointer-to-pointers are expected to be
* aligned at 8-bytes, but the ifconf structure is packed. So we use
* raw_free() instead. */
raw_free(ifc->ifc_buf);
ifc->ifc_buf = NULL;
}
/** Convert <b>*buf</b>, an ifreq structure array of size <b>buflen</b>, /** Convert <b>*buf</b>, an ifreq structure array of size <b>buflen</b>,
* into smartlist of <b>tor_addr_t</b> structures. * into smartlist of <b>tor_addr_t</b> structures.
*/ */
@ -1601,11 +1613,7 @@ get_interface_addresses_ioctl(int severity, sa_family_t family)
done: done:
if (fd >= 0) if (fd >= 0)
close(fd); close(fd);
/* On macOS, tor_free() loads ifc.ifc_buf, which leads to undefined ifconf_free_ifc_buf(&ifc);
* behaviour, because it is always aligned at 8-bytes (ifc) plus 4 bytes
* (ifc_len and pragma pack(4)). So we use raw_free() instead. */
raw_free(ifc.ifc_buf);
ifc.ifc_buf = NULL;
return result; return result;
} }
#endif /* defined(HAVE_IFCONF_TO_SMARTLIST) */ #endif /* defined(HAVE_IFCONF_TO_SMARTLIST) */