]> git.ipfire.org Git - ipfire-2.x.git/blob - src/patches/glibc/glibc-rh1027101.patch
dhcpcd: fix delay after dhcp down.
[ipfire-2.x.git] / src / patches / glibc / glibc-rh1027101.patch
1 commit 362b47fe09ca9a928d444c7e2f7992f7f61bfc3e
2 Author: Maxim Kuvyrkov <maxim@kugelworks.com>
3 Date: Tue Dec 24 09:44:50 2013 +1300
4
5 Fix race in free() of fastbin chunk: BZ #15073
6
7 Perform sanity check only if we have_lock. Due to lockless nature of fastbins
8 we need to be careful derefencing pointers to fastbin entries (chunksize(old)
9 in this case) in multithreaded environments.
10
11 The fix is to add have_lock to the if-condition checks. The rest of the patch
12 only makes code more readable.
13
14 * malloc/malloc.c (_int_free): Perform sanity check only if we
15 have_lock.
16
17 diff --git a/malloc/malloc.c b/malloc/malloc.c
18 index b1668b5..5e419ad 100644
19 --- a/malloc/malloc.c
20 +++ b/malloc/malloc.c
21 @@ -3783,25 +3783,29 @@ _int_free(mstate av, mchunkptr p, int have_lock)
22 fb = &fastbin (av, idx);
23
24 #ifdef ATOMIC_FASTBINS
25 - mchunkptr fd;
26 - mchunkptr old = *fb;
27 + /* Atomically link P to its fastbin: P->FD = *FB; *FB = P; */
28 + mchunkptr old = *fb, old2;
29 unsigned int old_idx = ~0u;
30 do
31 {
32 - /* Another simple check: make sure the top of the bin is not the
33 - record we are going to add (i.e., double free). */
34 + /* Check that the top of the bin is not the record we are going to add
35 + (i.e., double free). */
36 if (__builtin_expect (old == p, 0))
37 {
38 errstr = "double free or corruption (fasttop)";
39 goto errout;
40 }
41 - if (old != NULL)
42 + /* Check that size of fastbin chunk at the top is the same as
43 + size of the chunk that we are adding. We can dereference OLD
44 + only if we have the lock, otherwise it might have already been
45 + deallocated. See use of OLD_IDX below for the actual check. */
46 + if (have_lock && old != NULL)
47 old_idx = fastbin_index(chunksize(old));
48 - p->fd = fd = old;
49 + p->fd = old2 = old;
50 }
51 - while ((old = catomic_compare_and_exchange_val_rel (fb, p, fd)) != fd);
52 + while ((old = catomic_compare_and_exchange_val_rel (fb, p, old2)) != old2);
53
54 - if (fd != NULL && __builtin_expect (old_idx != idx, 0))
55 + if (have_lock && old != NULL && __builtin_expect (old_idx != idx, 0))
56 {
57 errstr = "invalid fastbin entry (free)";
58 goto errout;