summaryrefslogtreecommitdiff
path: root/src/common
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2018-01-10 12:57:23 -0500
committerNick Mathewson <nickm@torproject.org>2018-01-10 12:57:23 -0500
commitc8c258a4333815e195097a59801397dd7a169828 (patch)
tree075c8dc0d9ae025611a559e9133e99a4c250ab8a /src/common
parentca1d1c382ceb0201bf8761f2b45a0e6f8e83b9be (diff)
parent519fa1a3e6943f858b5dc1dee461053af1c187cd (diff)
downloadtor-c8c258a4333815e195097a59801397dd7a169828.tar.gz
tor-c8c258a4333815e195097a59801397dd7a169828.zip
Merge branch 'bug24733_squashed_2'
Diffstat (limited to 'src/common')
-rw-r--r--src/common/address.c14
-rw-r--r--src/common/util.h5
2 files changed, 18 insertions, 1 deletions
diff --git a/src/common/address.c b/src/common/address.c
index 0c0ba782ae..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,7 +1613,7 @@ get_interface_addresses_ioctl(int severity, sa_family_t family)
done:
if (fd >= 0)
close(fd);
- tor_free(ifc.ifc_buf);
+ ifconf_free_ifc_buf(&ifc);
return result;
}
#endif /* defined(HAVE_IFCONF_TO_SMARTLIST) */
diff --git a/src/common/util.h b/src/common/util.h
index 8dc64ce9fa..2ee0ea28cd 100644
--- a/src/common/util.h
+++ b/src/common/util.h
@@ -79,6 +79,11 @@ extern int dmalloc_free(const char *file, const int line, void *pnt,
*
* This is a macro. If you need a function pointer to release memory from
* tor_malloc(), use tor_free_().
+ *
+ * Note that this macro takes the address of the pointer it is going to
+ * free and clear. If that pointer is stored with a nonstandard
+ * alignment (eg because of a "packed" pragma) it is not correct to use
+ * tor_free().
*/
#ifdef __GNUC__
#define tor_free(p) STMT_BEGIN \