From: Kjetil Matheussen Date: Sat, 16 Jul 2016 12:43:32 +0000 (+0200) Subject: Handle load_segs overflow in register_dynlib_callback gracefully X-Git-Tag: v7.4.6~260 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=4225468e2e7f5c10c0badec2e8281a423fa7fa1d;p=gc Handle load_segs overflow in register_dynlib_callback gracefully * dyn_load.c [HAVE_DL_ITERATE_PHDR and PT_GNU_RELRO] (GC_register_dynlib_callback): If n_load_segs reaches MAX_LOAD_SEGS then call WARN (with the appropriate message) and call GC_add_roots_inner to register the segment directly instead of ABORT. --- diff --git a/dyn_load.c b/dyn_load.c index cc4a1c4e..b5b7e817 100644 --- a/dyn_load.c +++ b/dyn_load.c @@ -527,7 +527,6 @@ STATIC int GC_register_dynlib_callback(struct dl_phdr_info * info, if (callback != 0 && !callback(info->dlpi_name, start, p->p_memsz)) break; # ifdef PT_GNU_RELRO - if (n_load_segs >= MAX_LOAD_SEGS) ABORT("Too many PT_LOAD segs"); # if CPP_WORDSZ == 64 /* FIXME: GC_push_all eventually does the correct */ /* rounding to the next multiple of ALIGNMENT, so, most */ @@ -536,11 +535,17 @@ STATIC int GC_register_dynlib_callback(struct dl_phdr_info * info, /* start pointer value may require aligning */ start = (ptr_t)((word)start & ~(sizeof(word) - 1)); # endif - load_segs[n_load_segs].start = start; - load_segs[n_load_segs].end = end; - load_segs[n_load_segs].start2 = 0; - load_segs[n_load_segs].end2 = 0; - ++n_load_segs; + if (n_load_segs >= MAX_LOAD_SEGS) { + WARN("Too many PT_LOAD segments;" + " registering as roots directly...\n", 0); + GC_add_roots_inner(start, end, TRUE); + } else { + load_segs[n_load_segs].start = start; + load_segs[n_load_segs].end = end; + load_segs[n_load_segs].start2 = 0; + load_segs[n_load_segs].end2 = 0; + ++n_load_segs; + } # else GC_add_roots_inner(start, end, TRUE); # endif /* PT_GNU_RELRO */