본문 바로가기

System/Heap

House of Force

`malloc()`의 메모리 할당 과정

/* finally, do the allocation */
p = av->top;
size = chunksize (p);
 
/* check that one of the above allocation paths succeeded */
if ((unsigned long) (size) >= (unsigned long) (nb + MINSIZE))
  {
    remainder_size = size - nb;
    remainder = chunk_at_offset (p, nb);
    av->top = remainder;
    set_head (p, nb | PREV_INUSE | (av != &main_arena ? NON_MAIN_ARENA : 0));
    set_head (remainder, remainder_size | PREV_INUSE);
    check_malloced_chunk (av, p, nb);
    return chunk2mem (p);
  }
  • `p = av->top;` : `main_arena->top`이 가지고 있는 값을 `p`에 저장
    • `av` : `main_arena`
  • `size = chunksize (p);` : Top chunk의 크기를 `size`에 저장
  • `if ((unsigned long) (size) >= (unsigned long) (nb + MINSIZE))`: Top chunk의 `size`가 새로 요청된 메모리의 크기(`nb`) + chunk의 최소 크기(`MINSIZE`) 보다 크거나 같은 경우 Top chunk의 공간을 사용
  • `remainder_size = size - nb;` : 할당한 후 Top chunk의 남은 메모리를 계산
  • `remainder = chunk_at_offset (p, nb);` : Top chunk와 새로 요청된 메모리의 오프셋의 합부터 남은 메모리가 된다.
  • `av->top = remainder;` : 계산된 남은 메모리가 다시 Top chunk가 된다.
  • `set_head()`를 이용하여 새로 요청된 메모리의 크기를 `p->size`에 저장하고, `remainder_size`가 가지고 있는 값을 `remainder->size`에 저장

House of Force 필요 조건

  • top chunk의 size에 저장된 값을 다른 값으로 변경 가능
  • 원하는 크기의 메모리 할당을 요청 가능

 

House of Force 과정

  • `malloc()`을 호출한 후 Top chunk의 `size`을 `0xffffffffffffffff`으로 덮어쓴다.
  • 원하는 메모리 영역을 할당받기 위해 다음과 같이 계산된 값을 `malloc()` 함수의 `size`로 전달한다.
    • "할당받기를 원하는 메모리의 주소" - "Chunk header size(16 or 8)" - "Top chunk 주소" - "Chunk header size(16 or 8)"
  • 메모리 할당 요청 후에 할당 받고 싶은 메모리의 주소가 Top chunk에 저장된다.
  • 메모리 할당을 `malloc()`에 요청하면 해당 메모리를 반환한다.

 

"할당 받기를 원하는 메모리의 주소" - "Chunk header size(16 or 8)" - "Top chunk 주소" - "Chunk header size(16 or 8)"

위와 같은 계산이 나오게 된 이유는 `remainder = chunk_at_offset (p, nb);`에 있다.

 

만약 Top chunk의 주소가 0x602110이고, 할당받기 원하는 주소가 0x601010이라고 할 때, `malloc()`의 `size` 값이 0xffffffffffffeee0이라면

 

이후에 다시 `malloc()`을 요청하면 Top chunk의 주소인 0x601000 + chunk header(0x10) = 0x601010을 반환하게 된다.