merge from dev

This commit is contained in:
Daan Leijen 2021-02-24 15:17:35 -08:00
commit ad96d220f4
2 changed files with 26 additions and 9 deletions

View file

@ -469,10 +469,17 @@ static void* mi_unix_mmap(void* addr, size_t size, size_t try_alignment, int pro
#if (MI_INTPTR_SIZE >= 8) && (defined(_WIN32) || (defined(MI_OS_USE_MMAP) && !defined(MAP_ALIGNED))) #if (MI_INTPTR_SIZE >= 8) && (defined(_WIN32) || (defined(MI_OS_USE_MMAP) && !defined(MAP_ALIGNED)))
static mi_decl_cache_align _Atomic(uintptr_t) aligned_base; static mi_decl_cache_align _Atomic(uintptr_t) aligned_base;
// Return a 4MiB aligned address that is probably available // Return a 4MiB aligned address that is probably available.
static void* mi_os_get_aligned_hint(size_t try_alignment, size_t size) { // If this returns NULL, the OS will determine the address but on some OS's that may not be
// properly aligned which can be more costly as it needs to be adjusted afterwards.
// For a size > 4GiB this always returns NULL in order to guarantee good ASLR randomization;
// otherwise an initial large allocation of say 2TiB has a 50% chance to include (known) addresses
// in the middle of the 4TiB - 8TiB address range (see issue #372).
static void* mi_os_get_aligned_hint(size_t try_alignment, size_t size)
{
if (try_alignment == 0 || try_alignment > MI_SEGMENT_SIZE) return NULL; if (try_alignment == 0 || try_alignment > MI_SEGMENT_SIZE) return NULL;
if ((size%MI_SEGMENT_SIZE) != 0) return NULL; if ((size%MI_SEGMENT_SIZE) != 0) return NULL;
if (size > 1*GiB) return NULL; // guarantee the chance of fixed valid address is at most 1/(4<<40 / 1<<30) = 1/4096.
uintptr_t hint = mi_atomic_add_acq_rel(&aligned_base, size); uintptr_t hint = mi_atomic_add_acq_rel(&aligned_base, size);
if (hint == 0 || hint > ((intptr_t)30<<40)) { // try to wrap around after 30TiB (area after 32TiB is used for huge OS pages) if (hint == 0 || hint > ((intptr_t)30<<40)) { // try to wrap around after 30TiB (area after 32TiB is used for huge OS pages)
uintptr_t init = ((uintptr_t)4 << 40); // start at 4TiB area uintptr_t init = ((uintptr_t)4 << 40); // start at 4TiB area

View file

@ -33,17 +33,19 @@ void padding_shrink(); // issue #209
void various_tests(); void various_tests();
void test_mt_shutdown(); void test_mt_shutdown();
void large_alloc(void); // issue #363 void large_alloc(void); // issue #363
void fail_aslr(); // issue #372
int main() { int main() {
mi_stats_reset(); // ignore earlier allocations mi_stats_reset(); // ignore earlier allocations
large_alloc();
//heap_thread_free_large(); heap_thread_free_large();
//heap_no_delete(); heap_no_delete();
//heap_late_free(); heap_late_free();
//padding_shrink(); padding_shrink();
//various_tests(); various_tests();
//test_mt_shutdown(); large_alloc();
test_mt_shutdown();
//fail_aslr();
mi_stats_print(NULL); mi_stats_print(NULL);
return 0; return 0;
} }
@ -222,3 +224,11 @@ void large_alloc(void)
}); });
th.join(); th.join();
} }
// issue #372
void fail_aslr() {
size_t sz = (4ULL << 40); // 4TiB
void* p = malloc(sz);
printf("pointer p: %p: area up to %p\n", p, (uint8_t*)p + sz);
*(int*)0x7FFFFFFF000 = 0; // should segfault
}