(glibc) malloc - 2
circular doubly linked list
fastbin을 제외한 나머지 bins는 circular doubly linked list 구조를 사용한다. fastbin range에 속하지 않는 chunk일 경우, chunk 하나만 free()
해도 <main_arena+88>(unsorted bin-8)
을 가리키는 fd/bk
가 생성된다. * fastbin은 main_arena
를 가리키지 않으며 두 개를 free()
해야 첫 번째 free’d chunk에 fd
가 생성된다.
Note) fd/bk
가 가리키는 곳이 그대로 다음 fd/bk
가 아니라, mchunkptr
이다. 그래서 +8
해주어야 다음 fd/bk
가 나온다. fd/bk
가 가리키는 곳인 <main_arena+88>
에 +8
을 더해줘야 unsorted bin이다. * 여기서 <main_arena+88>
는 top ptr
이며 따라서 top ptr + 8
은 unsorted bin( bins[0] )
이다.
1
2
3
4
5
6
7
8
9
10
11
free(0x6020f0) // top chunk 아닌 small chunk.
0x602030: 0x0000000000000000 0x0000000000000091
0x602040: 0x00007ffff7dd37b8 0x00007ffff7dd37b8
gdb-peda$ x/4x 0x7ffff7dd37b8
0x7ffff7dd37b8 <main\_arena+88> : 0x0000000000602100 [top ptr] 0x0000000000000000 [last\_remainder]
0x7ffff7dd37c8 <main\_arena+104>: 0x0000000000602030 [fd] 0x0000000000602030 [bk]
* av->last_remainder
는 small request가 들어왔을 때 이를 처리하기 위해 split하는 경우, split하고 이후 남은 부분을 가리킨다.
arena structure
2.25 arena.c’s _heap_info
1
2
3
4
5
6
7
8
typedef struct \_heap\_info
{
mstate ar\_ptr; /\* Arena for this heap. \*/
struct \_heap\_info \*prev;
size\_t size;
size\_t mprotect\_size;
char pad[-6 \* SIZE\_SZ & MALLOC\_ALIGN\_MASK];
} heap\_info;
mstate
는 malloc_state
다.
2.25 malloc_state
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
struct malloc\_state
{
\_\_libc\_lock\_define (, mutex);
int flags;
mfastbinptr fastbinsY[NFASTBINS];
mchunkptr top;
mchunkptr last\_remainder;
mchunkptr bins[NBINS \* 2 - 2];
unsigned int binmap[BINMAPSIZE];
struct malloc\_state \*next;
struct malloc\_state \*next\_free;
INTERNAL\_SIZE\_T attached\_threads;
INTERNAL\_SIZE\_T system\_mem; // \_int\_free's next size check
INTERNAL\_SIZE\_T max\_system\_mem;
};
Note)
- libc 버전에 따라
main_arena
symbol이 없을 수 있다. ( 64bit 2.23, 32bit libc.so에는 없다. ) \_int\_free()
에서 next size check 시 사용하는av->system_mem
이 arena에 있기 때문에, fake arena 등을 사용하는 경우 주의해야 한다.- libc 버전마다 구조체 멤버가 조금씩 다르다. 그래서 항상
<main_arena+88>
이top ptr
인 것은 아니다.
This post is licensed under CC BY 4.0 by the author.