1. Arena란?
- ptmalloc2는 각 스레드가 서로 간섭하지 않고, 서로 다른 메모리 영역에 액세스 할 수 있게 하는데 이러한 메모리 영역을 "Arena"라고 한다.
- Arena는 멀티 쓰레드 환경을 지원하기 위해 도입된 개념이다.
- 각 Arena는 하나 이상의 힙 메모리를 얻는다.
- main arena는 프로그램의 초기 힙을 사용한다. (.bss 등 직후 시작)
- main arena는 프로그램의 초기 힙을 사용한다. (.bss 등 직후 시작)
- 단일 스레드 프로세스 경우에는 하나의 Arena를 가지지만, 멀티 스레드 프로세스 경우 하나 이상의 Arena를 가진다.
- 서로 다른 Arena안에 존재하는 각각의 스레드는 정지하지 않고, 힙 작업을 수행할 수 있다.
- 모든 스레드마다 각각의 Arena를 자원고갈 문제로 갖고 있는 것은 아니며, 32bit 또는 64bit system과 system core의 갯수에 따라 Arena의 개수가 제한된다.
- 제한된 크기만큼 Arena개수가 증가하여, 더이상 늘릴 수 없다면 여러 스레드가 하나의 Arena안에서 공유하며 힙 작업을 수행해야한다.
- 각각의 Arena안에 여러 스레드가 존재할 수 있으며, 뮤텍스를 사용하여 액세스를 제어한다.
2. Arena 종류
(1) Main Arena
- malloc.c 코드내에 "main_arena"라는 변수가 존재하는데, 이 변수는 "main arena"이다.
- 단일 스레드용 프로그램을 위해 존재하며, malloc()과 같은 힙 작업을 요구하는 코드를 실행하지 않아도 기본적으로 132KB 크기의 initial heap을 가진다.
- Main Arena가 감당할 수 있을 만큼의 동적할당 요구가 들어오면, sbrk()를 통해 heap segment를 확장한다.
만약 너무 큰 사이즈의 동적할당 요구일 경우 mmap()을 통해, 새로운 힙 메모리를 할당해준다. - Main_arena는 하나의 힙만 가질 수 있으며, heap_info 구조체를 가질 수 없다.
이때, 하나의 힙은 여러 개의 chunk로 나누어지며, 각 chunk는 각각의 header를 갖는다. - 해당 main_arena변수는 struct malloc_state구조체를 사용한다.
/* glibc-2_5/malloc/malloc.c */
2348 /* There are several instances of this struct ("arenas") in this
2349 malloc. If you are adapting this malloc in a way that does NOT use
2350 a static or mmapped malloc_state, you MUST explicitly zero-fill it
2351 before using. This malloc relies on the property that malloc_state
2352 is initialized to all zeroes (as is true of C statics). */
2353
2354 static struct malloc_state main_arena =
2355 {
2356 .mutex = _LIBC_LOCK_INITIALIZER,
2357 .next = &main_arena,
2358 .attached_threads = 1
2359 };
- malloc_state구조체에 선언된 mutex는 해당 arena에 대해 액세스를 제어할 때 사용되며, mutex를 이용하여 여러 스레드간에 arena 사용 충돌이 발생하는 것을 방지한다.
(2) Main Arena를 제외한 다른 Arena
- 새로운 스레드가 생성되어 힙 작업을 수행하고자 할 때, 다른 스레드의 대기 시간을 줄이기 위해 새로운 Arena를 생성하는데 이를 Sub Arena라고 한다.
- mmap()을 통해, 새로운 힙 메모리에 할당받으며 mprotect()를 사용하여 확장한다.
- Main Arena에서는 sbrk()를 사용하는 것과 달리, mmap()을 사용한다.
- Main Arena에서는 sbrk()를 사용하는 것과 달리, mmap()을 사용한다.
- Main Arena와 달리, 여러개의 sub heap과 heap info 구조체를 가질 수 있다.
※ 참고 ① brk( ) - 프로세스의 data segment에 할당 메모리량을 변경하기 위해 사용된다. - program break 위치를 이동시키기 위해, 메모리를 획득하며 성공시 0, 실패시 -1을 반환한다. - 예를 들어, brk(주소값)일 경우는 '요청한 주소값까지 메모리 할당'이라는 의미이다. ② sbrk( ) - sbrk의 기능은 내부적으로 brk system call을 사용한다. - brk와 동일하게 작업하며, 성공시 세그먼트 break주소를 반환하고 실패하면 -1을 반환한다. - 예를 들어, sbrk(메모리 크기)일 경우는 '이전 세그먼트부터 메모리 크기만큼 메모리 할당'이라는 의미이다. |
3. Arena 전체적인 구조
※ 참고 ① top - top에는 Top chunk가 배치되며, Top chunk는 Arena의 가장 상위 영역에 있는 Chunk이고 bin에 포함되지 않는다. - Top chunk는 PREV_INUSE 플래그가 설정된다. - Top chunk는 요청한 힙을 할당할 수 있는 충분한 청크가 bin에 없는 경우에 사용된다. - Top chunk의 크기는 사용자가 요청한 크기보다 큰 경우, Top chunk는 2개로 분리된다. (사용자가 요청한 크기의 청크와 분할되고 남은 크기의 나머지 청크인 Remainder chunk로 나뉜다.) - Remainder chunk는 새로운 Top chunk가 된다. - Top chunk의 크기가 사용자가 요청한 크기보다 작은 경우, 조건에 따라 Top chunk의 크기를 증가시키거나 새로운 힙 영역을 할당한다. ② next - 여러 arena가 있는 경우에, 추가 arena를 연결하는 포인터를 의미한다. |
# 참고주소
'System Hacking' 카테고리의 다른 글
Malloc(2) - Bin (glibc의 ptmalloc2) (0) | 2022.09.14 |
---|---|
Malloc(1) - chunk (glibc의 ptmalloc2) (0) | 2022.09.04 |
Fake EBP (0) | 2022.08.03 |
RTC (Return To CSU) (0) | 2022.07.04 |
RTL (Return to Library) (0) | 2022.06.29 |