Browse Source

Merge branch 'bug24733_squashed_2'

Nick Mathewson 6 years ago
parent
commit
c8c258a433
3 changed files with 24 additions and 1 deletions
  1. 6 0
      changes/bug24733
  2. 13 1
      src/common/address.c
  3. 5 0
      src/common/util.h

+ 6 - 0
changes/bug24733

@@ -0,0 +1,6 @@
+  o Minor bugfixes (code correctness):
+    - Stop invoking undefined behaviour by using tor_free() on an unaligned
+      pointer in get_interface_addresses_ioctl(). This pointer alignment issue
+      exists on x86_64 macOS, but is unlikely to exist elsewhere.
+      Fixes bug 24733; bugfix on 0.3.0.0-alpha-dev;
+      not in any released version of tor.

+ 13 - 1
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) */

+ 5 - 0
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                                 \