From 69d29e430de4e64240c84fdaf28db3bf3b3af54e Mon Sep 17 00:00:00 2001 From: Ivan Maidanski Date: Tue, 16 Feb 2016 00:18:54 +0300 Subject: [PATCH] Fix potential left shift overflows in finalize.c (64-bit targets) * finalize.c (HASH2, GC_grow_table): Cast 1 to word before shift to avoid overflow. * finalize.c (GC_dump_finalization_links, GC_dump_finalization, ITERATE_DL_HASHTBL_BEGIN, GC_finalize): Cast 1 to size_t before shift to avoid overflow. --- finalize.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/finalize.c b/finalize.c index 192de4de..12fd907a 100644 --- a/finalize.c +++ b/finalize.c @@ -26,7 +26,7 @@ typedef void (* finalization_mark_proc)(ptr_t /* finalizable_obj_ptr */); #define HASH3(addr,size,log_size) \ ((((word)(addr) >> 3) ^ ((word)(addr) >> (3 + (log_size)))) \ & ((size) - 1)) -#define HASH2(addr,log_size) HASH3(addr, 1 << (log_size), log_size) +#define HASH2(addr,log_size) HASH3(addr, (word)1 << (log_size), log_size) struct hash_chain_entry { word hidden_key; @@ -100,7 +100,7 @@ STATIC void GC_grow_table(struct hash_chain_entry ***table, register struct hash_chain_entry *p; signed_word log_old_size = *log_size_ptr; signed_word log_new_size = log_old_size + 1; - word old_size = ((log_old_size == -1)? 0: (1 << log_old_size)); + word old_size = log_old_size == -1 ? 0 : (word)1 << log_old_size; word new_size = (word)1 << log_new_size; /* FIXME: Power of 2 size often gets rounded up to one more page. */ struct hash_chain_entry **new_table; @@ -792,7 +792,7 @@ GC_API void GC_CALL GC_register_finalizer_unreachable(void * obj, struct disappearing_link *curr_dl; ptr_t real_ptr, real_link; size_t dl_size = dl_hashtbl->log_size == -1 ? 0 : - 1 << dl_hashtbl->log_size; + (size_t)1 << dl_hashtbl->log_size; size_t i; for (i = 0; i < dl_size; i++) { @@ -808,7 +808,8 @@ GC_API void GC_CALL GC_register_finalizer_unreachable(void * obj, void GC_dump_finalization(void) { struct finalizable_object * curr_fo; - size_t fo_size = log_fo_table_size == -1 ? 0 : 1 << log_fo_table_size; + size_t fo_size = log_fo_table_size == -1 ? 0 : + (size_t)1 << log_fo_table_size; ptr_t real_ptr; size_t i; @@ -868,7 +869,7 @@ GC_API void GC_CALL GC_register_finalizer_unreachable(void * obj, { \ size_t i; \ size_t dl_size = dl_hashtbl->log_size == -1 ? 0 : \ - 1 << dl_hashtbl->log_size; \ + (size_t)1 << dl_hashtbl->log_size; \ for (i = 0; i < dl_size; i++) { \ curr_dl = dl_hashtbl -> head[i]; \ prev_dl = NULL; \ @@ -935,7 +936,8 @@ GC_INNER void GC_finalize(void) struct finalizable_object * curr_fo, * prev_fo, * next_fo; ptr_t real_ptr; size_t i; - size_t fo_size = log_fo_table_size == -1 ? 0 : 1 << log_fo_table_size; + size_t fo_size = log_fo_table_size == -1 ? 0 : + (size_t)1 << log_fo_table_size; # ifndef SMALL_CONFIG /* Save current GC_[dl/ll]_entries value for stats printing */ -- 2.40.0