]> git.ipfire.org Git - thirdparty/glibc.git/commitdiff
Fix race in corruption check.
authorUlrich Drepper <drepper@redhat.com>
Thu, 16 Jul 2009 16:54:34 +0000 (09:54 -0700)
committerUlrich Drepper <drepper@redhat.com>
Thu, 16 Jul 2009 16:54:34 +0000 (09:54 -0700)
With atomic fastbins the checks performed can race with concurrent
modifications of the arena.  If we detect a problem re-do the test
after getting the lock.

ChangeLog
malloc/malloc.c

index 1e9df428c70372b5c404636b1dcb0ae86556fe79..6ddf9a19084945218e01a5d1c352d301dc95fd8b 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2009-07-16  Ulrich Drepper  <drepper@redhat.com>
+           Jakub Jelinek  <jakub@redhat.com>
+
+       * malloc/malloc.c [ATOMIC_FASTBINS] (_int_free): Make check for
+       corruption thread-safe.
+
 2009-07-13  Jakub Jelinek  <jakub@redhat.com>
 
        * include/atomic.h (catomic_compare_and_exchange_val_rel): If arch
index 0c0182ec0b8c32f107caffd981630be9edfe4667..a459a2b89de3b82b4680935d1bb1eba388062156 100644 (file)
@@ -4799,8 +4799,29 @@ _int_free(mstate av, mchunkptr p)
        || __builtin_expect (chunksize (chunk_at_offset (p, size))
                             >= av->system_mem, 0))
       {
-       errstr = "free(): invalid next size (fast)";
-       goto errout;
+#ifdef ATOMIC_FASTBINS
+       /* We might not have a lock at this point and concurrent modifications
+          of system_mem might have let to a false positive.  Redo the test
+          after getting the lock.  */
+       if (have_lock
+           || ({ assert (locked == 0);
+                 mutex_lock(&av->mutex);
+                 locked = 1;
+                 chunk_at_offset (p, size)->size <= 2 * SIZE_SZ
+                   || chunksize (chunk_at_offset (p, size)) >= av->system_mem;
+             }))
+#endif
+         {
+           errstr = "free(): invalid next size (fast)";
+           goto errout;
+         }
+#ifdef ATOMIC_FASTBINS
+       if (! have_lock)
+         {
+           (void)mutex_unlock(&av->mutex);
+           locked = 0;
+         }
+#endif
       }
 
     if (__builtin_expect (perturb_byte, 0))