mirror of git://git.musl-libc.org/musl
reintroduce hardening against partially-replaced allocator
commit618b18c78e
removed the previous detection and hardening since it was incorrect. commit72141795d4
already handled all that remained for hardening the static-linked case. in the dynamic-linked case, have the dynamic linker check whether malloc was replaced and make that information available. with these changes, the properties documented in commitc9f415d7ea
are restored: if calloc is not provided, it will behave as malloc+memset, and any of the memalign-family functions not provided will fail with ENOMEM.
This commit is contained in:
parent
72141795d4
commit
b4b1e10364
|
@ -133,6 +133,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;
|
||||
|
||||
|
@ -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. */
|
||||
|
|
|
@ -39,4 +39,7 @@ struct bin {
|
|||
__attribute__((__visibility__("hidden")))
|
||||
void __bin_chunk(struct chunk *);
|
||||
|
||||
__attribute__((__visibility__("hidden")))
|
||||
extern int __malloc_replaced;
|
||||
|
||||
#endif
|
||||
|
|
|
@ -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)))
|
||||
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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue