[BZ 21357] unwind-dw2-fde: Call free() outside of unwind mutex
authorRabin Vincent <rabinv@axis.com>
Mon, 17 Apr 2017 15:03:44 +0000 (12:03 -0300)
committerAdhemerval Zanella <adhemerval.zanella@linaro.org>
Mon, 17 Apr 2017 15:03:44 +0000 (12:03 -0300)
__deregister_frame_info_bases() calls free() while holding a mutex which
is also used from _Unwind_Find_FDE().  This leads to a deadlock if
AddressSanitizer uses _Unwind_Backtrace() from its free()
implementation.

Checked on mips-linux-gnu and x86_64-linux-gnu.

[BZ #21357]
* sysdeps/generic/unwind-dw2-fde.c (__deregister_frame_info_bases):
Call free() outside of mutex.

ChangeLog
sysdeps/generic/unwind-dw2-fde.c

index b209f9c8cc5b44c1abaaade996fb0698a26d55ec..bfda0e13ddd99fd4e084b03e006205deafe8130b 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2017-04-17  Rabin Vincent  <rabinv@axis.com>
+
+       [BZ #21357]
+       * sysdeps/generic/unwind-dw2-fde.c (__deregister_frame_info_bases):
+       Call free() outside of mutex.
+
 2017-04-13  Florian Weimer  <fweimer@redhat.com>
 
        * csu/check_fds.c (__libc_check_standard_fds): Assume O_NOFOLLOW
index 2f0bcd2ee9a34da40846e9484db7c3cade1c8fcf..104a2552b4d357bb845f8031137a8529a0eabb90 100644 (file)
@@ -202,6 +202,7 @@ __deregister_frame_info_bases (void *begin)
 {
   struct object **p;
   struct object *ob = 0;
+  struct fde_vector *tofree = NULL;
 
   /* If .eh_frame is empty, we haven't registered.  */
   if (*(uword *) begin == 0)
@@ -225,7 +226,7 @@ __deregister_frame_info_bases (void *begin)
          {
            ob = *p;
            *p = ob->next;
-           free (ob->u.sort);
+           tofree = ob->u.sort;
            goto out;
          }
       }
@@ -244,6 +245,7 @@ __deregister_frame_info_bases (void *begin)
 
  out:
   __gthread_mutex_unlock (&object_mutex);
+  free (tofree);
   return (void *) ob;
 }
 hidden_def (__deregister_frame_info_bases)