본문 바로가기

System Hacking

Malloc(3) - Arena (glibc의 ptmalloc2)

1. Arena란?

  • ptmalloc2는 각 스레드가 서로 간섭하지 않고, 서로 다른 메모리 영역에 액세스 할 수 있게 하는데 이러한 메모리 영역을 "Arena"라고 한다.
  • Arena는 멀티 쓰레드 환경을 지원하기 위해 도입된 개념이다.
  • 각 Arena는 하나 이상의 힙 메모리를 얻는다.
    • 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와 달리, 여러개의 sub heap과 heap info 구조체를 가질 수 있다.

출처 :https://rninche01.tistory.com/entry/heap2-glibc-malloc1-feat-Arena


   ※ 참고

   ① brk( )
    - 프로세스의 data segment에 할당 메모리량을 변경하기 위해 사용된다.
    - program break 위치를 이동시키기 위해, 메모리를 획득하며 성공시 0, 실패시 -1을 반환한다.
    - 예를 들어, brk(주소값)일 경우는 '요청한 주소값까지 메모리 할당'이라는 의미이다.

   ② sbrk( )
    - sbrk의 기능은 내부적으로 brk system call을 사용한다.
    - brk와 동일하게 작업하며, 성공시 세그먼트 break주소를 반환하고 실패하면 -1을 반환한다.
    - 예를 들어, sbrk(메모리 크기)일 경우는 '이전 세그먼트부터 메모리 크기만큼 메모리 할당'이라는 의미이다.

3. Arena 전체적인 구조

출처 : http://core-analyzer.sourceforge.net/index_files/Page335.html


   ※ 참고
   
   ① 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