summaryrefslogtreecommitdiff
path: root/finalize.c
diff options
context:
space:
mode:
authorIvan Maidanski <ivmai@mail.ru>2016-12-17 01:01:06 +0300
committerIvan Maidanski <ivmai@mail.ru>2016-12-17 01:01:06 +0300
commiteeb118d8438919e7f1eb8f80851e6dadaaaab14f (patch)
tree69a8c701a34cd0f4a2aa45f0a1848b537cd07fbd /finalize.c
parent0363e03857f2697fa2cfa26f1899f81ddaf47e2a (diff)
downloadbdwgc-eeb118d8438919e7f1eb8f80851e6dadaaaab14f.tar.gz
Eliminate 'integer shift by a negative amount' code defect in finalize
* finalize.c (GC_register_disappearing_link_inner): Add assertion that dl_hashtbl->log_size is non-negative after GC_grow_table() call. * finalize.c (GC_unregister_disappearing_link_inner): If dl_hashtbl->log_size is negative then return immediately (to avoid an integer value shift by log_size==-1 in HASH2). * finalize.c [!GC_MOVE_DISAPPEARING_LINK_NOT_NEEDED] (GC_move_disappearing_link_inner): Likewise. * finalize.c (GC_register_finalizer_inner): Add assertion that log_fo_table_size is non-negative after GC_grow_table() call. * finalize.c (GC_finalize): Add assertion that log_fo_table_size is non-negative unless GC_fnlz_roots.finalize_now is null.
Diffstat (limited to 'finalize.c')
-rw-r--r--finalize.c12
1 files changed, 11 insertions, 1 deletions
diff --git a/finalize.c b/finalize.c
index c765d628..50caaa55 100644
--- a/finalize.c
+++ b/finalize.c
@@ -158,6 +158,7 @@ STATIC int GC_register_disappearing_link_inner(
|| dl_hashtbl -> entries > ((word)1 << dl_hashtbl -> log_size)) {
GC_grow_table((struct hash_chain_entry ***)&dl_hashtbl -> head,
&dl_hashtbl -> log_size);
+ GC_ASSERT(dl_hashtbl->log_size >= 0);
GC_COND_LOG_PRINTF("Grew %s table to %u entries\n", tbl_log_name,
1 << (unsigned)dl_hashtbl -> log_size);
}
@@ -229,8 +230,12 @@ GC_INLINE struct disappearing_link *GC_unregister_disappearing_link_inner(
{
struct disappearing_link *curr_dl;
struct disappearing_link *prev_dl = NULL;
- size_t index = HASH2(link, dl_hashtbl->log_size);
+ size_t index;
+
+ if (dl_hashtbl->log_size == -1)
+ return NULL; /* prevent integer shift by a negative amount */
+ index = HASH2(link, dl_hashtbl->log_size);
for (curr_dl = dl_hashtbl -> head[index]; curr_dl;
curr_dl = dl_next(curr_dl)) {
if (curr_dl -> dl_hidden_link == GC_HIDE_POINTER(link)) {
@@ -492,6 +497,9 @@ GC_API GC_await_finalize_proc GC_CALL GC_get_await_finalize_proc(void)
word curr_hidden_link;
word new_hidden_link;
+ if (dl_hashtbl->log_size == -1)
+ return GC_NOT_FOUND; /* prevent integer shift by a negative amount */
+
/* Find current link. */
curr_index = HASH2(link, dl_hashtbl -> log_size);
curr_hidden_link = GC_HIDE_POINTER(link);
@@ -642,6 +650,7 @@ STATIC void GC_register_finalizer_inner(void * obj,
|| GC_fo_entries > ((word)1 << log_fo_table_size)) {
GC_grow_table((struct hash_chain_entry ***)&GC_fnlz_roots.fo_head,
&log_fo_table_size);
+ GC_ASSERT(log_fo_table_size >= 0);
GC_COND_LOG_PRINTF("Grew fo table to %u entries\n",
1 << (unsigned)log_fo_table_size);
}
@@ -1036,6 +1045,7 @@ GC_INNER void GC_finalize(void)
other finalizable objects */
if (need_unreachable_finalization) {
curr_fo = GC_fnlz_roots.finalize_now;
+ GC_ASSERT(NULL == curr_fo || log_fo_table_size >= 0);
prev_fo = NULL;
while (curr_fo != NULL) {
next_fo = fo_next(curr_fo);