mirror of
https://github.com/microsoft/mimalloc.git
synced 2025-07-01 17:24:38 +03:00
always use non-flat map in secure mode and validate pointers passed to free
This commit is contained in:
parent
09c2b7fdcf
commit
8a66ae818a
5 changed files with 13 additions and 3 deletions
|
@ -123,13 +123,17 @@ typedef int32_t mi_ssize_t;
|
||||||
|
|
||||||
// use a flat page-map (or a 2-level one)
|
// use a flat page-map (or a 2-level one)
|
||||||
#ifndef MI_PAGE_MAP_FLAT
|
#ifndef MI_PAGE_MAP_FLAT
|
||||||
#if MI_MAX_VABITS <= 40 && !defined(__APPLE__)
|
#if MI_MAX_VABITS <= 40 && !MI_SECURE && !defined(__APPLE__)
|
||||||
#define MI_PAGE_MAP_FLAT 1
|
#define MI_PAGE_MAP_FLAT 1
|
||||||
#else
|
#else
|
||||||
#define MI_PAGE_MAP_FLAT 0
|
#define MI_PAGE_MAP_FLAT 0
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if MI_PAGE_MAP_FLAT && MI_SECURE
|
||||||
|
#error should not use MI_PAGE_MAP_FLAT with a secure build
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------------
|
/* --------------------------------------------------------------------------------
|
||||||
Builtin's
|
Builtin's
|
||||||
|
|
|
@ -589,7 +589,7 @@ static inline mi_page_t* _mi_checked_ptr_page(const void* p) {
|
||||||
|
|
||||||
static inline mi_page_t* _mi_ptr_page(const void* p) {
|
static inline mi_page_t* _mi_ptr_page(const void* p) {
|
||||||
mi_assert_internal(p==NULL || mi_is_in_heap_region(p));
|
mi_assert_internal(p==NULL || mi_is_in_heap_region(p));
|
||||||
#if MI_DEBUG || defined(__APPLE__)
|
#if MI_DEBUG || MI_SECURE || defined(__APPLE__)
|
||||||
return _mi_checked_ptr_page(p);
|
return _mi_checked_ptr_page(p);
|
||||||
#else
|
#else
|
||||||
return _mi_unchecked_ptr_page(p);
|
return _mi_unchecked_ptr_page(p);
|
||||||
|
|
|
@ -50,7 +50,7 @@ terms of the MIT license. A copy of the license can be found in the file
|
||||||
|
|
||||||
// Define MI_SECURE to enable security mitigations. Level 1 has minimal performance impact,
|
// Define MI_SECURE to enable security mitigations. Level 1 has minimal performance impact,
|
||||||
// but protects most metadata with guard pages:
|
// but protects most metadata with guard pages:
|
||||||
// #define MI_SECURE 1 // guard page around metadata
|
// #define MI_SECURE 1 // guard page around metadata; check pointer validity on free
|
||||||
//
|
//
|
||||||
// Level 2 has more performance impact but protect well against various buffer overflows
|
// Level 2 has more performance impact but protect well against various buffer overflows
|
||||||
// by surrounding all mimalloc pages with guard pages:
|
// by surrounding all mimalloc pages with guard pages:
|
||||||
|
|
|
@ -202,8 +202,12 @@ bool _mi_page_map_init(void) {
|
||||||
const size_t page_map_size = _mi_align_up( mi_page_map_count * sizeof(mi_page_t**), os_page_size);
|
const size_t page_map_size = _mi_align_up( mi_page_map_count * sizeof(mi_page_t**), os_page_size);
|
||||||
const size_t submap_size = MI_PAGE_MAP_SUB_SIZE;
|
const size_t submap_size = MI_PAGE_MAP_SUB_SIZE;
|
||||||
const size_t reserve_size = page_map_size + submap_size;
|
const size_t reserve_size = page_map_size + submap_size;
|
||||||
|
#if MI_SECURE
|
||||||
|
const bool commit = true; // the whole page map is valid and we can reliably check any pointer
|
||||||
|
#else
|
||||||
const bool commit = page_map_size <= 64*MI_KiB ||
|
const bool commit = page_map_size <= 64*MI_KiB ||
|
||||||
mi_option_is_enabled(mi_option_pagemap_commit) || _mi_os_has_overcommit();
|
mi_option_is_enabled(mi_option_pagemap_commit) || _mi_os_has_overcommit();
|
||||||
|
#endif
|
||||||
_mi_page_map = (_Atomic(mi_page_t**)*)_mi_os_alloc_aligned(reserve_size, 1, commit, true /* allow large */, &mi_page_map_memid);
|
_mi_page_map = (_Atomic(mi_page_t**)*)_mi_os_alloc_aligned(reserve_size, 1, commit, true /* allow large */, &mi_page_map_memid);
|
||||||
if (_mi_page_map==NULL) {
|
if (_mi_page_map==NULL) {
|
||||||
_mi_error_message(ENOMEM, "unable to reserve virtual memory for the page map (%zu KiB)\n", page_map_size / MI_KiB);
|
_mi_error_message(ENOMEM, "unable to reserve virtual memory for the page map (%zu KiB)\n", page_map_size / MI_KiB);
|
||||||
|
|
|
@ -89,9 +89,11 @@ int main(void) {
|
||||||
CHECK_BODY("malloc-free-null") {
|
CHECK_BODY("malloc-free-null") {
|
||||||
mi_free(NULL);
|
mi_free(NULL);
|
||||||
};
|
};
|
||||||
|
#if MI_INTPTR_BITS >= 64
|
||||||
CHECK_BODY("malloc-free-invalid-low") {
|
CHECK_BODY("malloc-free-invalid-low") {
|
||||||
mi_free((void*)(MI_ZU(0x0000000003990080))); // issue #1087
|
mi_free((void*)(MI_ZU(0x0000000003990080))); // issue #1087
|
||||||
};
|
};
|
||||||
|
#endif
|
||||||
CHECK_BODY("calloc-overflow") {
|
CHECK_BODY("calloc-overflow") {
|
||||||
// use (size_t)&mi_calloc to get some number without triggering compiler warnings
|
// use (size_t)&mi_calloc to get some number without triggering compiler warnings
|
||||||
result = (mi_calloc((size_t)&mi_calloc,SIZE_MAX/1000) == NULL);
|
result = (mi_calloc((size_t)&mi_calloc,SIZE_MAX/1000) == NULL);
|
||||||
|
|
Loading…
Add table
Reference in a new issue