]> granicus.if.org Git - gc/commit
Avoid potential race in hb_sz access between realloc and reclaim_block
authorIvan Maidanski <ivmai@mail.ru>
Tue, 26 Feb 2019 22:32:53 +0000 (01:32 +0300)
committerIvan Maidanski <ivmai@mail.ru>
Wed, 27 Feb 2019 08:44:25 +0000 (11:44 +0300)
commitd4968840692ba710e7fb74068b2453d54facd6cf
tree490bd249ea6e15cda00e4172965a20a513e62381
parent7c5992de50ffb1f805b9b62c2176a9e9d8c8286d
Avoid potential race in hb_sz access between realloc and reclaim_block

Issue #240 (bdwgc).

GC_realloc might be changing the block size while GC_reclaim_block
is examining it.  The change to the size field is benign, i.e.
GC_reclaim would work correctly with either value, since we are not
changing the number of objects in the block.  But seeing a half-updated
value (though unlikely to occur in practice) could be probably bad.
Using unordered atomic fetch of hb_sz field should solve the issue.

* reclaim.c (GC_block_nearly_full, GC_reclaim_small_nonempty_block):
Add sz argument; use sz instead of hhdr->hb_sz.
* reclaim.c (GC_reclaim_clear, GC_reclaim_uninit, GC_reclaim_check):
Skip the assertion about hhdr->hb_sz if THREADS.
* reclaim.c [ENABLE_DISCLAIM] (GC_disclaim_and_reclaim): Likewise.
* reclaim.c [AO_HAVE_load] (GC_reclaim_block): Use AO_load to access
hhdr->hb_sz; add comments.
* reclaim.c (GC_reclaim_block): Pass sz to
GC_reclaim_small_nonempty_block() and GC_block_nearly_full().
* reclaim.c (GC_continue_reclaim, GC_reclaim_all): Pass hhdr->hb_sz to
GC_reclaim_small_nonempty_block().
* reclaim.c [!EAGER_SWEEP && ENABLE_DISCLAIM]
(GC_reclaim_unconditionally_marked): Likewise.
reclaim.c