diff options
| -rw-r--r-- | ldso/dynlink.c | 9 | ||||
| -rw-r--r-- | src/internal/malloc_impl.h | 3 | ||||
| -rw-r--r-- | src/malloc/malloc.c | 13 | ||||
| -rw-r--r-- | src/malloc/memalign.c | 2 | 
4 files changed, 22 insertions, 5 deletions
diff --git a/ldso/dynlink.c b/ldso/dynlink.c index 63e7b81f..cea5f452 100644 --- a/ldso/dynlink.c +++ b/ldso/dynlink.c @@ -134,6 +134,9 @@ static struct dso *const nodeps_dummy;  struct debug *_dl_debug_addr = &debug;  __attribute__((__visibility__("hidden"))) +extern int __malloc_replaced; + +__attribute__((__visibility__("hidden")))  void (*const __init_array_start)(void)=0, (*const __fini_array_start)(void)=0;  __attribute__((__visibility__("hidden"))) @@ -1691,6 +1694,12 @@ _Noreturn void __dls3(size_t *sp)  	if (ldso_fail) _exit(127);  	if (ldd_mode) _exit(0); +	/* Determine if malloc was interposed by a replacement implementation +	 * so that calloc and the memalign family can harden against the +	 * possibility of incomplete replacement. */ +	if (find_sym(head, "malloc", 1).dso != &ldso) +		__malloc_replaced = 1; +  	/* Switch to runtime mode: any further failures in the dynamic  	 * linker are a reportable failure rather than a fatal startup  	 * error. */ diff --git a/src/internal/malloc_impl.h b/src/internal/malloc_impl.h index 4c4a4b46..5d025b06 100644 --- a/src/internal/malloc_impl.h +++ b/src/internal/malloc_impl.h @@ -39,4 +39,7 @@ struct bin {  __attribute__((__visibility__("hidden")))  void __bin_chunk(struct chunk *); +__attribute__((__visibility__("hidden"))) +extern int __malloc_replaced; +  #endif diff --git a/src/malloc/malloc.c b/src/malloc/malloc.c index 239ab9c6..d72883e1 100644 --- a/src/malloc/malloc.c +++ b/src/malloc/malloc.c @@ -20,6 +20,8 @@ static struct {  	volatile int free_lock[2];  } mal; +int __malloc_replaced; +  /* Synchronization tools */  static inline void lock(volatile int *lk) @@ -356,10 +358,13 @@ void *calloc(size_t m, size_t n)  	}  	n *= m;  	void *p = malloc(n); -	if (!p || IS_MMAPPED(MEM_TO_CHUNK(p))) -		return p; -	if (n >= PAGE_SIZE) -		n = mal0_clear(p, PAGE_SIZE, n); +	if (!p) return p; +	if (!__malloc_replaced) { +		if (IS_MMAPPED(MEM_TO_CHUNK(p))) +			return p; +		if (n >= PAGE_SIZE) +			n = mal0_clear(p, PAGE_SIZE, n); +	}  	return memset(p, 0, n);  } diff --git a/src/malloc/memalign.c b/src/malloc/memalign.c index 7246a99b..8a6152f4 100644 --- a/src/malloc/memalign.c +++ b/src/malloc/memalign.c @@ -13,7 +13,7 @@ void *__memalign(size_t align, size_t len)  		return 0;  	} -	if (len > SIZE_MAX - align) { +	if (len > SIZE_MAX - align || __malloc_replaced) {  		errno = ENOMEM;  		return 0;  	}  | 
