mimalloc
mimalloc copied to clipboard
AddressSanitizer: global buffer overflow in `mi_stat_update`
Running with version 2.2.4 under ASan produces the following error when releasing a heap:
=================================================================
==5940==ERROR: AddressSanitizer: global-buffer-overflow on address 0x7ff6228aa360 at pc 0x7ff6222cf09a bp 0x00e060b4baf0 sp 0x00e060b4baf8
READ of size 8 at 0x7ff6228aa360 thread T0
#0 0x7ff6222cf099 in mi_stat_update D:\projects\solvespace\extlib\mimalloc\src\stats.c:41
#1 0x7ff6222cec12 in _mi_stat_decrease(struct mi_stat_count_s *, unsigned __int64) D:\projects\solvespace\extlib\mimalloc\src\stats.c:61
#2 0x7ff6222c14b9 in mi_segment_page_clear D:\projects\solvespace\extlib\mimalloc\src\segment.c:1027
#3 0x7ff6222b7224 in _mi_segment_page_free(struct mi_page_s *, bool, struct mi_segments_tld_s *) D:\projects\solvespace\extlib\mimalloc\src\segment.c:1059
#4 0x7ff62229e2e1 in _mi_heap_page_destroy D:\projects\solvespace\extlib\mimalloc\src\heap.c:365
#5 0x7ff62229d5c0 in mi_heap_visit_pages D:\projects\solvespace\extlib\mimalloc\src\heap.c:46
#6 0x7ff62229ae9f in _mi_heap_destroy_pages(struct mi_heap_s *) D:\projects\solvespace\extlib\mimalloc\src\heap.c:371
#7 0x7ff622299f85 in mi_heap_destroy D:\projects\solvespace\extlib\mimalloc\src\heap.c:405
#8 0x7ff6216c0162 in SolveSpace::Platform::MimallocHeap::~MimallocHeap(void) D:\projects\solvespace\src\platform\platformbase.cpp:74
#9 0x7ff6216bfc84 in SolveSpace::Platform::FreeAllTemporary(void) D:\projects\solvespace\src\platform\platformbase.cpp:93
#10 0x7ff6216570f0 in SolveSpace::SolveSpaceUI::SolveGroup(class SolveSpace::hGroup, bool) D:\projects\solvespace\src\generate.cpp:567
#11 0x7ff62165713a in SolveSpace::SolveSpaceUI::SolveGroupAndReport(class SolveSpace::hGroup, bool) D:\projects\solvespace\src\generate.cpp:512
#12 0x7ff621656337 in SolveSpace::SolveSpaceUI::GenerateAll(enum SolveSpace::SolveSpaceUI::Generate, bool, bool) D:\projects\solvespace\src\generate.cpp:291
#13 0x7ff621655808 in SolveSpace::SolveSpaceUI::GenerateAll(enum SolveSpace::SolveSpaceUI::Generate, bool, bool) D:\projects\solvespace\src\generate.cpp:215
#14 0x7ff62146b897 in SolveSpace::SolveSpaceUI::AfterNewFile(void) D:\projects\solvespace\src\solvespace.cpp:544
#15 0x7ff6213b93ef in SolveSpace::Test::Helper::CheckLoad(char const *, int, char const *) D:\projects\solvespace\test\harness.cpp:217
#16 0x7ff621448e46 in Test_other_roundtrip D:\projects\solvespace\test\constraint\equal_angle\test.cpp:20
#17 0x7ff62142f9f3 in std::invoke<void (__cdecl *&)(class SolveSpace::Test::Helper *), class SolveSpace::Test::Helper *>(void (__cdecl *&)(class SolveSpace::Test::Helper *), class SolveSpace::Test::Helper *&&) C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.44.35207\include\type_traits:1680
#18 0x7ff62142fab8 in std::_Func_impl_no_alloc<void (__cdecl *)(class SolveSpace::Test::Helper *), void, class SolveSpace::Test::Helper *>::_Do_call(class SolveSpace::Test::Helper *&&) C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.44.35207\include\functional:880
#19 0x7ff6213fa9f1 in std::_Func_class<void, class SolveSpace::Test::Helper *>::operator()(class SolveSpace::Test::Helper *) const C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.44.35207\include\functional:926
#20 0x7ff6213bf24c in main D:\projects\solvespace\test\harness.cpp:381
#21 0x7ff622374c68 in invoke_main D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl:78
#22 0x7ff622374bb1 in __scrt_common_main_seh D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl:288
#23 0x7ff622374a6d in __scrt_common_main D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl:330
#24 0x7ff622374cdd in mainCRTStartup D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_main.cpp:16
#25 0x7ffd0bcb7373 (C:\Windows\System32\KERNEL32.DLL+0x180017373)
#26 0x7ffd0d2dcc90 (C:\Windows\SYSTEM32\ntdll.dll+0x18004cc90)
0x7ff6228aa360 is located 16 bytes after global variable 'tld_main' defined in 'init.c:153:36' (0x7ff6228a8f40) of size 5136
SUMMARY: AddressSanitizer: global-buffer-overflow D:\projects\solvespace\extlib\mimalloc\src\stats.c:41 in mi_stat_update
Shadow bytes around the buggy address:
0x7ff6228aa080: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x7ff6228aa100: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x7ff6228aa180: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x7ff6228aa200: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x7ff6228aa280: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x7ff6228aa300: 00 00 00 00 00 00 00 00 00 00 f9 f9[f9]f9 f9 f9
0x7ff6228aa380: f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9
0x7ff6228aa400: f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9
0x7ff6228aa480: f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9
0x7ff6228aa500: f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9
0x7ff6228aa580: f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9
Shadow byte legend (one shadow byte represents 8 application bytes):
Addressable: 00
Partially addressable: 01 02 03 04 05 06 07
Heap left redzone: fa
Freed heap region: fd
Stack left redzone: f1
Stack mid redzone: f2
Stack right redzone: f3
Stack after return: f5
Stack use after scope: f8
Global redzone: f9
Global init order: f6
Poisoned by user: f7
Container overflow: fc
Array cookie: ac
Intra object redzone: bb
ASan internal: fe
Left alloca redzone: ca
Right alloca redzone: cb
==5940==ABORTING
This is caused by the fact that _mi_page_bin(page) returns MI_BIN_FULL (defined in mimalloc/types.h, and evaluating to 74) in mi_segment_page_clear(), while mi_stats_t::page_bins can only hold MI_BIN_HUGE+1 (73+1) elements, causing an off-by-one overflow. This likely requires page_bins to grow to MI_BIN_FULL+1, but I don't know if this is the right fix or not, and if the malloc_bins member should also grow accordingly.
This doesn't happen with 2.2.3, and is likely caused by 08c33768a5344e43a1ba95b88c3adcbb6a5c3498.
#1118 might be related.