mirror of
git://git.musl-libc.org/musl
synced 2025-01-31 02:51:32 +00:00
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;
|
struct debug *_dl_debug_addr = &debug;
|
||||||
|
|
||||||
|
__attribute__((__visibility__("hidden")))
|
||||||
|
extern int __malloc_replaced;
|
||||||
|
|
||||||
__attribute__((__visibility__("hidden")))
|
__attribute__((__visibility__("hidden")))
|
||||||
void (*const __init_array_start)(void)=0, (*const __fini_array_start)(void)=0;
|
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 (ldso_fail) _exit(127);
|
||||||
if (ldd_mode) _exit(0);
|
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
|
/* Switch to runtime mode: any further failures in the dynamic
|
||||||
* linker are a reportable failure rather than a fatal startup
|
* linker are a reportable failure rather than a fatal startup
|
||||||
* error. */
|
* error. */
|
||||||
|
@ -39,4 +39,7 @@ struct bin {
|
|||||||
__attribute__((__visibility__("hidden")))
|
__attribute__((__visibility__("hidden")))
|
||||||
void __bin_chunk(struct chunk *);
|
void __bin_chunk(struct chunk *);
|
||||||
|
|
||||||
|
__attribute__((__visibility__("hidden")))
|
||||||
|
extern int __malloc_replaced;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -20,6 +20,8 @@ static struct {
|
|||||||
volatile int free_lock[2];
|
volatile int free_lock[2];
|
||||||
} mal;
|
} mal;
|
||||||
|
|
||||||
|
int __malloc_replaced;
|
||||||
|
|
||||||
/* Synchronization tools */
|
/* Synchronization tools */
|
||||||
|
|
||||||
static inline void lock(volatile int *lk)
|
static inline void lock(volatile int *lk)
|
||||||
@ -356,10 +358,13 @@ void *calloc(size_t m, size_t n)
|
|||||||
}
|
}
|
||||||
n *= m;
|
n *= m;
|
||||||
void *p = malloc(n);
|
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;
|
return p;
|
||||||
if (n >= PAGE_SIZE)
|
if (n >= PAGE_SIZE)
|
||||||
n = mal0_clear(p, PAGE_SIZE, n);
|
n = mal0_clear(p, PAGE_SIZE, n);
|
||||||
|
}
|
||||||
return memset(p, 0, n);
|
return memset(p, 0, n);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -13,7 +13,7 @@ void *__memalign(size_t align, size_t len)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (len > SIZE_MAX - align) {
|
if (len > SIZE_MAX - align || __malloc_replaced) {
|
||||||
errno = ENOMEM;
|
errno = ENOMEM;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user