diff options
-rw-r--r-- | ChangeLog | 26 | ||||
-rw-r--r-- | elf/rtld.c | 21 | ||||
-rw-r--r-- | malloc/malloc.c | 63 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/i386/dl-librecon.h | 3 |
4 files changed, 86 insertions, 27 deletions
diff --git a/ChangeLog b/ChangeLog index 01737dfeec..5dd30e6129 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,6 +1,30 @@ +1999-02-23 Andreas Schwab <schwab@issan.cs.uni-dortmund.de> + + * malloc/malloc.c (mALLOC_SET_STATe): Handle the case where a + non-checked heap is restored when malloc checking was requested by + the user. + (struct malloc_state): Add using_malloc_checking. + (MALLOC_STATE_VERSION): Increment minor. + (using_malloc_checking, disallow_malloc_check): New variables. + (__malloc_check_init): Use them. + (mALLOC_GET_STATe): Use mALLOc to allocate the malloc_state, so + that it can the chunk is properly instrumented when malloc + checking is enabled. Set the new using_malloc_checking field. + (malloc_hook_ini): Correct signature when _LIBC is not defined. + +1999-02-23 Andreas Schwab <schwab@issan.cs.uni-dortmund.de> + + * sysdeps/unix/sysv/linux/i386/dl-librecon.h + (DISTINGUISH_LIB_VERSIONS): Don't relocate DT_STRTAB a second + time. + + * elf/rtld.c (dl_main): Rename paths_initialized to rtld_is_main. + Don't call elf_get_dynamic_info and _dl_setup_hash a second time + if ld.so is the main program. + 1999-02-23 Ulrich Drepper <drepper@cygnus.com> - * stdio-common/vfprintf.c (vfprintf): If precision or width if too + * stdio-common/vfprintf.c (vfprintf): If precision or width is too large for work_buffer, allocate new buffer. (printf_unknown): Likewise. [PR libc/988] diff --git a/elf/rtld.c b/elf/rtld.c index 762cdc5ff2..40405d15af 100644 --- a/elf/rtld.c +++ b/elf/rtld.c @@ -340,7 +340,7 @@ dl_main (const ElfW(Phdr) *phdr, char *file; int has_interp = 0; unsigned int i; - int paths_initialized = 0; + int rtld_is_main = 0; hp_timing_t start; hp_timing_t stop; hp_timing_t diff; @@ -368,6 +368,7 @@ dl_main (const ElfW(Phdr) *phdr, pay attention to its PT_INTERP command (we are the interpreter ourselves). This is an easy way to test a new ld.so before installing it. */ + rtld_is_main = 1; /* Note the place where the dynamic linker actually came from. */ _dl_rtld_map.l_name = _dl_argv[0]; @@ -441,7 +442,6 @@ of this helper program; chances are you did not intend to run this program.\n\ /* Initialize the data structures for the search paths for shared objects. */ _dl_init_paths (library_path); - paths_initialized = 1; if (__builtin_expect (mode, normal) == verify) { @@ -574,12 +574,15 @@ of this helper program; chances are you did not intend to run this program.\n\ else assert (_dl_rtld_map.l_libname); /* How else did we get here? */ - /* Extract the contents of the dynamic section for easy access. */ - elf_get_dynamic_info (_dl_loaded->l_ld, _dl_loaded->l_addr, - _dl_loaded->l_info); - if (_dl_loaded->l_info[DT_HASH]) - /* Set up our cache of pointers into the hash table. */ - _dl_setup_hash (_dl_loaded); + if (! rtld_is_main) + { + /* Extract the contents of the dynamic section for easy access. */ + elf_get_dynamic_info (_dl_loaded->l_ld, _dl_loaded->l_addr, + _dl_loaded->l_info); + if (_dl_loaded->l_info[DT_HASH]) + /* Set up our cache of pointers into the hash table. */ + _dl_setup_hash (_dl_loaded); + } if (__builtin_expect (mode, normal) == verify) { @@ -597,7 +600,7 @@ of this helper program; chances are you did not intend to run this program.\n\ _exit (has_interp ? 0 : 2); } - if (! paths_initialized) + if (! rtld_is_main) /* Initialize the data structures for the search paths for shared objects. */ _dl_init_paths (library_path); diff --git a/malloc/malloc.c b/malloc/malloc.c index 2cf2025237..03d68b75e7 100644 --- a/malloc/malloc.c +++ b/malloc/malloc.c @@ -1691,14 +1691,11 @@ thread_atfork_static(ptmalloc_lock_all, ptmalloc_unlock_all, \ initialization routine, then do the normal work. */ static Void_t* -#ifdef _LIBC -malloc_hook_ini(size_t sz, const __malloc_ptr_t caller) -#else #if __STD_C -malloc_hook_ini(size_t sz) +malloc_hook_ini(size_t sz, const __malloc_ptr_t caller) #else -malloc_hook_ini(sz) size_t sz; -#endif +malloc_hook_ini(sz, caller) + size_t sz; const __malloc_ptr_t caller; #endif { __malloc_hook = NULL; @@ -1746,10 +1743,33 @@ __malloc_ptr_t weak_variable (*__memalign_hook) = memalign_hook_ini; void weak_variable (*__after_morecore_hook) __MALLOC_P ((void)) = NULL; +/* Whether we are using malloc checking. */ +static int using_malloc_checking; + +/* A flag that is set by malloc_set_state, to signal that malloc checking + must not be enabled on the request from the user (via the MALLOC_CHECK_ + environment variable). It is reset by __malloc_check_init to tell + malloc_set_state that the user has requested malloc checking. + + The purpose of this flag is to make sure that malloc checking is not + enabled when the heap to be restored was constructed without malloc + checking, and thus does not contain the required magic bytes. + Otherwise the heap would be corrupted by calls to free and realloc. If + it turns out that the heap was created with malloc checking and the + user has requested it malloc_set_state just calls __malloc_check_init + again to enable it. On the other hand, reusing such a heap without + further malloc checking is safe. */ +static int disallow_malloc_check; + /* Activate a standard set of debugging hooks. */ void __malloc_check_init() { + if (disallow_malloc_check) { + disallow_malloc_check = 0; + return; + } + using_malloc_checking = 1; __malloc_hook = malloc_check; __free_hook = free_check; __realloc_hook = realloc_check; @@ -4041,7 +4061,7 @@ int mALLOPt(param_number, value) int param_number; int value; functions. */ #define MALLOC_STATE_MAGIC 0x444c4541l -#define MALLOC_STATE_VERSION (0*0x100l + 0l) /* major*0x100 + minor */ +#define MALLOC_STATE_VERSION (0*0x100l + 1l) /* major*0x100 + minor */ struct malloc_state { long magic; @@ -4060,24 +4080,20 @@ struct malloc_state { unsigned int max_n_mmaps; unsigned long mmapped_mem; unsigned long max_mmapped_mem; + int using_malloc_checking; }; Void_t* mALLOC_GET_STATe() { - mchunkptr victim; struct malloc_state* ms; int i; mbinptr b; - ptmalloc_init(); - (void)mutex_lock(&main_arena.mutex); - victim = chunk_alloc(&main_arena, request2size(sizeof(*ms))); - if(!victim) { - (void)mutex_unlock(&main_arena.mutex); + ms = (struct malloc_state*)mALLOc(sizeof(*ms)); + if (!ms) return 0; - } - ms = (struct malloc_state*)chunk2mem(victim); + (void)mutex_lock(&main_arena.mutex); ms->magic = MALLOC_STATE_MAGIC; ms->version = MALLOC_STATE_VERSION; ms->av[0] = main_arena.av[0]; @@ -4108,6 +4124,11 @@ mALLOC_GET_STATe() ms->max_n_mmaps = max_n_mmaps; ms->mmapped_mem = mmapped_mem; ms->max_mmapped_mem = max_mmapped_mem; +#if defined _LIBC || defined MALLOC_HOOKS + ms->using_malloc_checking = using_malloc_checking; +#else + ms->using_malloc_checking = 0; +#endif (void)mutex_unlock(&main_arena.mutex); return (Void_t*)ms; } @@ -4123,6 +4144,9 @@ mALLOC_SET_STATe(msptr) Void_t* msptr; int i; mbinptr b; +#if defined _LIBC || defined MALLOC_HOOKS + disallow_malloc_check = 1; +#endif ptmalloc_init(); if(ms->magic != MALLOC_STATE_MAGIC) return -1; /* Must fail if the major version is too high. */ @@ -4160,6 +4184,15 @@ mALLOC_SET_STATe(msptr) Void_t* msptr; mmapped_mem = ms->mmapped_mem; max_mmapped_mem = ms->max_mmapped_mem; /* add version-dependent code here */ + if (ms->version >= 1) { +#if defined _LIBC || defined MALLOC_HOOKS + /* Check whether it is safe to enable malloc checking. */ + if (ms->using_malloc_checking && !using_malloc_checking && + !disallow_malloc_check) + __malloc_check_init (); +#endif + } + (void)mutex_unlock(&main_arena.mutex); return 0; } diff --git a/sysdeps/unix/sysv/linux/i386/dl-librecon.h b/sysdeps/unix/sysv/linux/i386/dl-librecon.h index 4ae2e87a7b..84b4396285 100644 --- a/sysdeps/unix/sysv/linux/i386/dl-librecon.h +++ b/sysdeps/unix/sysv/linux/i386/dl-librecon.h @@ -33,8 +33,7 @@ const ElfW(Dyn) *d; \ const char *strtab; \ \ - strtab = ((void *) _dl_loaded->l_addr \ - + _dl_loaded->l_info[DT_STRTAB]->d_un.d_ptr); \ + strtab = (const char *) _dl_loaded->l_info[DT_STRTAB]->d_un.d_ptr; \ \ for (d = _dl_loaded->l_ld; d->d_tag != DT_NULL; ++d) \ if (d->d_tag == DT_NEEDED \ |