Fix deadlock in _int_free consistency check

This patch fixes a deadlock in the fastbin consistency check.
If we fail the fast check due to concurrent modifications to
the next chunk or system_mem, we should not lock if we already
have the arena lock.  Simplify the check to make it obviously
correct.

	* malloc/malloc.c (_int_free): Fix deadlock bug in consistency check.
This commit is contained in:
Wilco Dijkstra 2017-10-19 18:19:55 +01:00
parent 4d916f0f12
commit d74e6f6c0d
2 changed files with 16 additions and 9 deletions

View File

@ -1,3 +1,7 @@
2017-10-19 Wilco Dijkstra <wdijkstr@arm.com>
* malloc/malloc.c (_int_free): Fix deadlock bug in consistency check.
2017-10-19 Valery Reznic <valery_reznic@yahoo.com>
H.J. Lu <hongjiu.lu@intel.com>

View File

@ -4135,17 +4135,20 @@ _int_free (mstate av, mchunkptr p, int have_lock)
|| __builtin_expect (chunksize (chunk_at_offset (p, size))
>= av->system_mem, 0))
{
bool fail = true;
/* 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
|| ({ __libc_lock_lock (av->mutex);
chunksize_nomask (chunk_at_offset (p, size)) <= 2 * SIZE_SZ
|| chunksize (chunk_at_offset (p, size)) >= av->system_mem;
}))
of system_mem might result in a false positive. Redo the test after
getting the lock. */
if (!have_lock)
{
__libc_lock_lock (av->mutex);
fail = (chunksize_nomask (chunk_at_offset (p, size)) <= 2 * SIZE_SZ
|| chunksize (chunk_at_offset (p, size)) >= av->system_mem);
__libc_lock_unlock (av->mutex);
}
if (fail)
malloc_printerr ("free(): invalid next size (fast)");
if (! have_lock)
__libc_lock_unlock (av->mutex);
}
free_perturb (chunk2mem(p), size - 2 * SIZE_SZ);