diff options
author | Ivan Maidanski <ivmai@mail.ru> | 2021-07-29 09:13:05 +0300 |
---|---|---|
committer | Ivan Maidanski <ivmai@mail.ru> | 2021-07-29 13:20:04 +0300 |
commit | dcaad02116999a1ebb28707d301dd220f7e96005 (patch) | |
tree | c7744a40f80ea7c55a0bd5a257f91fe822c5192b /mallocx.c | |
parent | d0ba209660ea8c663e06d9a68332ba5f42da54ba (diff) | |
download | bdwgc-dcaad02116999a1ebb28707d301dd220f7e96005.tar.gz |
Fix data race regarding *rlh value in generic_malloc_many
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); change for statement to while; reload rlh value after
acquiring the GC lock (at the end of the loop).
Diffstat (limited to 'mallocx.c')
-rw-r--r-- | mallocx.c | 7 |
1 files changed, 5 insertions, 2 deletions
@@ -343,9 +343,9 @@ GC_API void GC_CALL GC_generic_malloc_many(size_t lb, int k, void **result) struct hblk * hbp; hdr * hhdr; - for (rlh += lg; (hbp = *rlh) != NULL; ) { + 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 @@ -409,6 +409,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 } |