]> granicus.if.org Git - gc/commitdiff
Fix potential left shift overflows in finalize.c (64-bit targets)
authorIvan Maidanski <ivmai@mail.ru>
Mon, 15 Feb 2016 21:18:54 +0000 (00:18 +0300)
committerIvan Maidanski <ivmai@mail.ru>
Mon, 15 Feb 2016 21:18:54 +0000 (00:18 +0300)
* 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

index 192de4decc8873c11972c877efe4fadc19f63eee..12fd907ae6c49b2e6f7e3daa088d1b61072ef5ba 100644 (file)
@@ -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 */