diff options
author | Ivan Maidanski <ivmai@mail.ru> | 2021-07-29 09:13:05 +0300 |
---|---|---|
committer | Ivan Maidanski <ivmai@mail.ru> | 2021-08-21 01:04:31 +0300 |
commit | 94a502e6d3adabe865c568110a97058b967228c6 (patch) | |
tree | 62677ee35456ab7a858a15cf35341da21064013f | |
parent | a9b071a1a12f1c3fc2a8f77855d5b1a9c55e5814 (diff) | |
download | bdwgc-94a502e6d3adabe865c568110a97058b967228c6.tar.gz |
Fix data race regarding *rlh value in generic_malloc_many
(a cherry-pick of commit dcaad0211 from 'master')
The issue was highlighted in GC_generic_malloc_many() by a static code
analysis tool as "using an unreliable value of *rlh inside the second
locked section; if the data that *rlh depends on was changed by
another thread, this use might be incorrect".
* mallocx.c (GC_generic_malloc_many): Do not increment rlh by lg (use
rlh[lg] instead); reload rlh value after
acquiring the GC lock (at the end of the loop).
-rw-r--r-- | mallocx.c | 8 |
1 files changed, 5 insertions, 3 deletions
@@ -349,10 +349,9 @@ GC_API void GC_CALL GC_generic_malloc_many(size_t lb, int k, void **result) struct hblk * hbp; hdr * hhdr; - rlh += lg; - while ((hbp = *rlh) != 0) { + while ((hbp = rlh[lg]) != NULL) { hhdr = HDR(hbp); - *rlh = hhdr -> hb_next; + rlh[lg] = hhdr -> hb_next; GC_ASSERT(hhdr -> hb_sz == lb); hhdr -> hb_last_reclaimed = (unsigned short) GC_gc_no; # ifdef PARALLEL_MARK @@ -416,6 +415,9 @@ GC_API void GC_CALL GC_generic_malloc_many(size_t lb, int k, void **result) /* GC lock is needed for reclaim list access. We */ /* must decrement fl_builder_count before reacquiring */ /* the lock. Hopefully this path is rare. */ + + rlh = ok -> ok_reclaim_list; /* reload rlh after locking */ + if (NULL == rlh) break; } # endif } |