microsoft / microsoft/mimalloc
ASAN crash in `mi_checked_ptr_segment` when freeing memory from `abi::__cxa_demangle`
Nobody has claimed this yet.
- Dominant language
- C
- Stars
- 13.4k
- Forks
- 1.2k
- Avg merge
- 4d 45m
- Merged PRs (30d)
- 13
Description
Version: mimalloc v2.1.2
Mode: Static linking, override, ASAN
OS: Linux (RHEL 7.9.2009)
Compiler: GCC 10.3.0
Minimal repro:
mimalloc built with: `cmake3 .. -DCMAKE_BUILD_TYPE=Debug -DMI_TRACK_ASAN=ON`
Source code `testing.cpp`
```
#include
#include
int main() {
int status = 0;
char* const readable_name = abi::__cxa_demangle("FivE", 0, 0, &status);
free(readable_name);
return status;
}
```
Compile with:
```
g++-10.3 -ggdb3 -Wall mimalloc-asan-debug.o testing.cpp -otesting -fsanitize=address -lpthread
```
Execution result:
```
$ ./testing
mimalloc: warning: mi_free: pointer might not point to a valid heap region: 0x602000000010
(this may still be a valid very large allocation (over 64MiB))
=================================================================
==599==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x6020000000d8 at pc 0x000000408002 bp 0x7ffc163fb3c0 sp 0x7ffc163fb3b8
READ of size 8 at 0x6020000000d8 thread T0
#0 0x408001 in mi_checked_ptr_segment [...]/mimalloc/src/alloc.c:543
#1 0x40815d in mi_free [...]/mimalloc/src/alloc.c:564
#2 0x404f7e in free [...]/mimalloc/src/alloc-override.c:135
#3 0x43c0ff in main [...]/mimalloc/build-asan-debug/testing.cpp:7
#4 0x7f8ca61b2554 in __libc_start_main (/lib64/libc.so.6+0x22554)
#5 0x4023a8 (/var[...]/mimalloc/build-asan-debug/testing+0x4023a8)
Address 0x6020000000d8 is a wild pointer.
SUMMARY: AddressSanitizer: heap-buffer-overflow [...]/mimalloc/src/alloc.c:543 in mi_checked_ptr_segment
Shadow bytes around the buggy address:
0x0c047fff7fc0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c047fff7fd0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c047fff7fe0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c047fff7ff0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c047fff8000: fa fa 00 fa fa fa fa fa fa fa fa fa fa fa fa fa
=>0x0c047fff8010: fa fa fa fa fa fa fa fa fa fa fa[fa]fa fa fa fa
0x0c047fff8020: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c047fff8030: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c047fff8040: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c047fff8050: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c047fff8060: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
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
Shadow gap: cc
==599==ABORTING
```
I noticed that when running under `gdb`, it appears that there is a call to `realloc` that does not go through `mi_realloc`.
```
#0 __interceptor_realloc (ptr=0x0, size=8) at ../../../../../src/gcc-10.3.0/libsanitizer/asan/asan_malloc_linux.cpp:38
#1 0x00007ffff7eb4d53 in d_growable_string_resize (need=, dgs=0x7fffffffbb40) at cp-demangle.c:4036
#2 d_growable_string_append_buffer (l=6, s=0x7fffffffb980 "int ()", dgs=0x7fffffffbb40) at cp-demangle.c:4060
#3 d_growable_string_callback_adapter (s=0x7fffffffb980 "int ()", l=6, opaque=0x7fffffffbb40) at cp-demangle.c:4077
#4 0x00007ffff7ebd1f0 in d_print_flush (dpi=0x7fffffffb980) at cp-demangle.c:4282
#5 d_print_callback (options=17, opaque=0x7fffffffbb40, callback=0x7ffff7eb4cd0 , dc=0x7fffffffb860) at cp-demangle.c:4368
#6 d_demangle_callback (mangled=, callback=callback@entry=0x7ffff7eb4cd0 , opaque=opaque@entry=0x7fffffffbb40, options=17) at cp-demangle.c:6358
#7 0x00007ffff7ebd9bd in d_demangle (options=17, palc=, mangled=) at cp-demangle.c:6380
#8 __cxa_demangle (mangled_name=, output_buffer=0x0, length=0x0, status=0x7fffffffbbc0) at cp-demangle.c:6444
#9 0x000000000043c0f0 in main () at testing.cpp:6
```
However:
- If I compile without ASAN, I see this call go through `mi_realloc` as expected.
- If I call `realloc()` manually instead of through `abi::__cxa_demangle`, the call goes through `mi_realloc` as expected.
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Reproduce the ASAN failure using testing.cpp and the stated CMake build, then inspect src/alloc.c:543 and src/alloc-override.c:135 alongside the __cxa_demangle realloc stack. Compare the ASAN and non-ASAN paths to identify why the allocation bypasses mi_realloc. Done means the reproducer no longer crashes under ASAN and the relevant behavior is covered by a regression check.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- c, cmake, linux
- Domain
- operating-systems, testing-qa
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 50/100