티스토리 뷰
https://github.com/andigena/glibc-2.23-0ubuntu3/blob/master/malloc/malloc.c
코드는 해당 github에 존재하는 코드를 가져왔습니다.
Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
|
void *
__libc_malloc (size_t bytes)
{
mstate ar_ptr;
void *victim;
void *(*hook) (size_t, const void *) = atomic_forced_read (__malloc_hook);
// malloc_hook의 address를 가져옵니다.
if (__builtin_expect (hook != NULL, 0))
return (*hook)(bytes, RETURN_ADDRESS (0));
// 가져온 hook값이 NULL이 아니라면 (세팅이 되있다면) 호출합니다.
arena_get (ar_ptr, bytes);
// arena_get함수를 통해 ar_ptr에 아레나의 주소를 받아옵니다.
victim = _int_malloc (ar_ptr, bytes);
// _int_malloc을 호출해서 victim에 넣어줍니다.
if (!victim && ar_ptr != NULL)
//비정상적으로 malloc 할당이 되었고, ar_ptr은 잘 받아져왔다면
{
LIBC_PROBE (memory_malloc_retry, 1, bytes);
ar_ptr = arena_get_retry (ar_ptr, bytes);
victim = _int_malloc (ar_ptr, bytes);
}
if (ar_ptr != NULL)
(void) mutex_unlock (&ar_ptr->mutex);
assert (!victim || chunk_is_mmapped (mem2chunk (victim)) ||
ar_ptr == arena_for_chunk (mem2chunk (victim)));
return victim;
}
|
Flow
1. malloc 요청이 들어옵니다.
2. __malloc_hook의 포인터를 받아옵니다.
3. hook이 존재한다면
3-1. __malloc_hook을 호출하고 종료합니다.
4. ar_ptr에 요청된 byte를 인자로 아레나포인터를 받아옵니다.
5. victim에 받아온 ar_ptr과 요청된 byte로 malloc을 해줍니다.
6. 비정상적으로 malloc할당이 되었고, ar_ptr또한 잘 받아져 왔다면
6-1. ar_ptr을 arena_get_retry로 다시받아옵니다.
6-2. 그뒤 victim에 다시 할당을 해줍니다.
7. ar_ptr이 잘 받아져왔다면
7-1. ar_ptr을 인자로 mutex_unlock을 호출합니다.
8. assert함수로 디버깅 에러를 잡습니다. 검출 조건은 다음과 같습니다.
8-1. _int_malloc이 비정상적으로 받아져 왔다면
8-2. 해당 chunk가 mmap으로 할당되어졌다면
8-3. 해당 chunk가 arena2에서 찾은 청크라면
9. 모든 코드를 맞추고 할당된 chunk의 포인터를 반환합니다.
댓글