How do free&malloc work
How do free&malloc work
0:
This passage is a record while analyzing the source code of glibc-2.29.
free
Complete errs are shown in the next section.
__libc_free
strong_alias (__libc_free, __free) strong_alias (__libc_free, free)
- check __free_hook’s value ( Jmp if NZ)
- check if mmapped (to process if Yes)
- other cases: call _int_free
_int_free
- check
invalid pointer&invalid size - tcach process (
double free detected in tcache 2) - fast bin process (
invalid next size (fast)&double free or corruption (fasttop)&invalid fastbin entry (free)) - unsorted bin process
- checks
double free or corruption (top)double free or corruption (out)double free or corruption (!prev)free(): invalid next size (normal)
- consolidation backward & forward (
corrupted size vs. prev_size while consolidating) - link in unsorted bin (
free(): corrupted unsorted chunks)
- checks
- check after-consolidate-size
- if large enough, do
malloc_consolidate
- if large enough, do
malloc
Complete errs are shown in the next section.
__libc_malloc
- check
__malloc_hook( Jmp if NZ) - tcache process
- other cases: call
_int_malloc
_int_malloc
- fast bin process
- check victim’s size (
memory corruption (fast)) - stash fast bin (
No size check in this process)
- check victim’s size (
- small bin process (if
smallbin[idx] → bk≠ itself)- double link check(
smallbin double linked list corrupted) - unlink victim
- stash small bin(
No unlink check in this process)
- double link check(
- if size > small bin max call
malloc_consolidate - unsorted bin process
- check (
invalid size (unsorted)&invalid next size (unsorted)&mismatching next->prev_size (unsorted)&unsorted double linked list corrupted&invalid next->prev_inuse (unsorted)) - if larger: split the last remainder and return
- double link check
(corrupted unsorted chunks 3) -
if fit: stash unsorted bin and set return_cached=1return the fit one - if smaller: unlink unsorted bin & link into bins(
No unlink check in this process) - if
return_cached=1, return onetcachechunk
- check (
- large bin process
- get a large bin chunk that has the same
idx- if larger: split + link the remainder into unsorted bin(
corrupted unsorted chunks)
- if larger: split + link the remainder into unsorted bin(
- get a large bin chunk that has
idx+1,idx+2,idx+3 …. (corrupted unsorted chunks 2)
- get a large bin chunk that has the same
- use top chunk
- check
corrupted top size - split top chunk
- if can’t fit: use
sysmalloc
- check
Error print list
# 12 for free
malloc_printerr ("free(): invalid pointer");
malloc_printerr ("free(): invalid size");
malloc_printerr ("free(): double free detected in tcache 2");
malloc_printerr ("free(): invalid next size (fast)");
malloc_printerr ("double free or corruption (fasttop)");
malloc_printerr ("invalid fastbin entry (free)");
malloc_printerr ("double free or corruption (top)");
malloc_printerr ("double free or corruption (out)");
malloc_printerr ("double free or corruption (!prev)");
malloc_printerr ("free(): invalid next size (normal)");
malloc_printerr ("corrupted size vs. prev_size while consolidating");
malloc_printerr ("free(): corrupted unsorted chunks");
# 9 for malloc
malloc_printerr ("malloc(): memory corruption (fast)");
malloc_printerr ("malloc(): smallbin double linked list corrupted");
malloc_printerr ("malloc(): invalid size (unsorted)");
malloc_printerr ("malloc(): invalid next size (unsorted)");
malloc_printerr ("malloc(): mismatching next->prev_size (unsorted)");
malloc_printerr ("malloc(): unsorted double linked list corrupted");
malloc_printerr ("malloc(): invalid next->prev_inuse (unsorted)");
malloc_printerr ("malloc(): corrupted unsorted chunks 3");
malloc_printerr ("malloc(): corrupted unsorted chunks");