summaryrefslogtreecommitdiff
path: root/src/common/address.c
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2018-01-10 09:51:45 -0500
committerNick Mathewson <nickm@torproject.org>2018-01-10 12:57:13 -0500
commitf71bbd20a40de78fc1e7d722ba591578f137abec (patch)
tree1d0a33fcdd9b3d36ea71e306c85fa76499f531ce /src/common/address.c
parent54899b404cbde5a24984e4865eed112f303398f6 (diff)
downloadtor-f71bbd20a40de78fc1e7d722ba591578f137abec.tar.gz
tor-f71bbd20a40de78fc1e7d722ba591578f137abec.zip
Extract the raw_free() of ifc_buf into a new function.
Explain the problem more correctly.
Diffstat (limited to 'src/common/address.c')
-rw-r--r--src/common/address.c18
1 files changed, 13 insertions, 5 deletions
diff --git a/src/common/address.c b/src/common/address.c
index ea14e63926..d96ec514b1 100644
--- a/src/common/address.c
+++ b/src/common/address.c
@@ -1515,6 +1515,18 @@ get_interface_addresses_win32(int severity, sa_family_t family)
#define _SIZEOF_ADDR_IFREQ sizeof
#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>,
* into smartlist of <b>tor_addr_t</b> structures.
*/
@@ -1601,11 +1613,7 @@ get_interface_addresses_ioctl(int severity, sa_family_t family)
done:
if (fd >= 0)
close(fd);
- /* On macOS, tor_free() loads ifc.ifc_buf, which leads to undefined
- * 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;
+ ifconf_free_ifc_buf(&ifc);
return result;
}
#endif /* defined(HAVE_IFCONF_TO_SMARTLIST) */