Skip to content

Commit 21425bc

Browse files
committed
check all os_commit calls and return NULL on failure
1 parent 30a17bf commit 21425bc

File tree

4 files changed

+27
-14
lines changed

4 files changed

+27
-14
lines changed

include/mimalloc/internal.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -163,13 +163,13 @@ bool _mi_os_has_overcommit(void);
163163
bool _mi_os_has_virtual_reserve(void);
164164

165165
bool _mi_os_reset(void* addr, size_t size);
166-
bool _mi_os_commit(void* p, size_t size, bool* is_zero);
167-
bool _mi_os_commit_ex(void* addr, size_t size, bool* is_zero, size_t stat_size);
168166
bool _mi_os_decommit(void* addr, size_t size);
169-
bool _mi_os_protect(void* addr, size_t size);
170167
bool _mi_os_unprotect(void* addr, size_t size);
171168
bool _mi_os_purge(void* p, size_t size);
172169
bool _mi_os_purge_ex(void* p, size_t size, bool allow_reset, size_t stat_size);
170+
mi_decl_nodiscard bool _mi_os_commit(void* p, size_t size, bool* is_zero);
171+
mi_decl_nodiscard bool _mi_os_commit_ex(void* addr, size_t size, bool* is_zero, size_t stat_size);
172+
mi_decl_nodiscard bool _mi_os_protect(void* addr, size_t size);
173173

174174
void* _mi_os_alloc_aligned(size_t size, size_t alignment, bool commit, bool allow_large, mi_memid_t* memid);
175175
void* _mi_os_alloc_aligned_at_offset(size_t size, size_t alignment, size_t align_offset, bool commit, bool allow_large, mi_memid_t* memid);

src/os.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -300,7 +300,10 @@ static void* mi_os_prim_alloc_aligned(size_t size, size_t alignment, bool commit
300300

301301
// explicitly commit only the aligned part
302302
if (commit) {
303-
_mi_os_commit(p, size, NULL);
303+
if (!_mi_os_commit(p, size, NULL)) {
304+
mi_os_prim_free(p, over_size, 0);
305+
return NULL;
306+
}
304307
}
305308
}
306309
else { // mmap can free inside an allocation

src/page.c

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ static inline mi_block_t* mi_page_block_at(const mi_page_t* page, void* page_sta
3737
}
3838

3939
static void mi_page_init(mi_heap_t* heap, mi_page_t* page, size_t size, mi_tld_t* tld);
40-
static void mi_page_extend_free(mi_heap_t* heap, mi_page_t* page, mi_tld_t* tld);
40+
static bool mi_page_extend_free(mi_heap_t* heap, mi_page_t* page, mi_tld_t* tld);
4141

4242
#if (MI_DEBUG>=3)
4343
static size_t mi_page_list_count(mi_page_t* page, mi_block_t* head) {
@@ -630,14 +630,14 @@ static mi_decl_noinline void mi_page_free_list_extend( mi_page_t* const page, co
630630
// Note: we also experimented with "bump" allocation on the first
631631
// allocations but this did not speed up any benchmark (due to an
632632
// extra test in malloc? or cache effects?)
633-
static void mi_page_extend_free(mi_heap_t* heap, mi_page_t* page, mi_tld_t* tld) {
633+
static bool mi_page_extend_free(mi_heap_t* heap, mi_page_t* page, mi_tld_t* tld) {
634634
mi_assert_expensive(mi_page_is_valid_init(page));
635635
#if (MI_SECURE<=2)
636636
mi_assert(page->free == NULL);
637637
mi_assert(page->local_free == NULL);
638-
if (page->free != NULL) return;
638+
if (page->free != NULL) return true;
639639
#endif
640-
if (page->capacity >= page->reserved) return;
640+
if (page->capacity >= page->reserved) return true;
641641

642642
size_t page_size;
643643
//uint8_t* page_start =
@@ -673,6 +673,7 @@ static void mi_page_extend_free(mi_heap_t* heap, mi_page_t* page, mi_tld_t* tld)
673673
page->capacity += (uint16_t)extend;
674674
mi_stat_increase(tld->stats.page_committed, extend * bsize);
675675
mi_assert_expensive(mi_page_is_valid_init(page));
676+
return true;
676677
}
677678

678679
// Initialize a fresh page
@@ -724,8 +725,10 @@ static void mi_page_init(mi_heap_t* heap, mi_page_t* page, size_t block_size, mi
724725
mi_assert_expensive(mi_page_is_valid_init(page));
725726

726727
// initialize an initial free list
727-
mi_page_extend_free(heap,page,tld);
728-
mi_assert(mi_page_immediate_available(page));
728+
if (mi_page_extend_free(heap,page,tld)) {
729+
mi_assert(mi_page_immediate_available(page));
730+
}
731+
return;
729732
}
730733

731734

@@ -817,9 +820,14 @@ static mi_page_t* mi_page_queue_find_free_ex(mi_heap_t* heap, mi_page_queue_t* p
817820
if (page_candidate != NULL) {
818821
page = page_candidate;
819822
}
820-
if (page != NULL && !mi_page_immediate_available(page)) {
821-
mi_assert_internal(mi_page_is_expandable(page));
822-
mi_page_extend_free(heap, page, heap->tld);
823+
if (page != NULL) {
824+
if (!mi_page_immediate_available(page)) {
825+
mi_assert_internal(mi_page_is_expandable(page));
826+
if (!mi_page_extend_free(heap, page, heap->tld)) {
827+
page = NULL; // failed to extend
828+
}
829+
}
830+
mi_assert_internal(page == NULL || mi_page_immediate_available(page));
823831
}
824832

825833
if (page == NULL) {

src/segment.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,9 @@ static bool mi_page_not_in_queue(const mi_page_t* page, mi_segments_tld_t* tld)
182182

183183
static void mi_segment_protect_range(void* p, size_t size, bool protect) {
184184
if (protect) {
185-
_mi_os_protect(p, size);
185+
if (!_mi_os_protect(p, size)) {
186+
_mi_error_message(EFAULT,"unable to protect segment memory at %p\n", p);
187+
}
186188
}
187189
else {
188190
_mi_os_unprotect(p, size);

0 commit comments

Comments
 (0)