본문 바로가기

Heap analysis/glibc 2.23

(glibc 2.23) do_check_chunk

전체 코드는 아래 더보기

더보기
/*
   Properties of all chunks
 */

static void
do_check_chunk (mstate av, mchunkptr p)
{
  unsigned long sz = chunksize (p);
  /* min and max possible addresses assuming contiguous allocation */
  char *max_address = (char *) (av->top) + chunksize (av->top);
  char *min_address = max_address - av->system_mem;

  if (!chunk_is_mmapped (p))
    {
      /* Has legal address ... */
      if (p != av->top)
        {
          if (contiguous (av))
            {
              assert (((char *) p) >= min_address);
              assert (((char *) p + sz) <= ((char *) (av->top)));
            }
        }
      else
        {
          /* top size is always at least MINSIZE */
          assert ((unsigned long) (sz) >= MINSIZE);
          /* top predecessor always marked inuse */
          assert (prev_inuse (p));
        }
    }
  else
    {
      /* address is outside main heap  */
      if (contiguous (av) && av->top != initial_top (av))
        {
          assert (((char *) p) < min_address || ((char *) p) >= max_address);
        }
      /* chunk is page-aligned */
      assert (((p->prev_size + sz) & (GLRO (dl_pagesize) - 1)) == 0);
      /* mem is aligned */
      assert (aligned_OK (chunk2mem (p)));
    }
}

 

청크를 검사하는 함수로 주요 검사 항목은 아래와 같다

  • top청크가 아니면 청크의 위치와 다음 청크가 top 청크보다 작은지 검사 ( NONCONTIGUOUS_BIT 설정 된 경우 )
  • top청크일 경우 청크의 사이즈와 prev_inuse가 설정되어 있는지 검사

 


  unsigned long sz = chunksize (p);
  /* min and max possible addresses assuming contiguous allocation */
  char *max_address = (char *) (av->top) + chunksize (av->top);
  char *min_address = max_address - av->system_mem;

함수의 초입에는 변수 선언과 초기화를 해준다

  • sz : 청크 p의 사이즈
  • max_address :  힙의 끝 주소
  • min_address :  힙의 시작 주소

 

  if (!chunk_is_mmapped (p))
    {
      	...
    }
  else
    {
    	...
    }

p가 mmap으로 할당되었는지 체크하고 조건문에 들어가게 된다

 

  if (!chunk_is_mmapped (p))
    {
      /* Has legal address ... */
      if (p != av->top)
        {
          if (contiguous (av))
            {
              assert (((char *) p) >= min_address);
              assert (((char *) p + sz) <= ((char *) (av->top)));
            }
        }
      else
        {
          /* top size is always at least MINSIZE */
          assert ((unsigned long) (sz) >= MINSIZE);
          /* top predecessor always marked inuse */
          assert (prev_inuse (p));
        }
    }

p가 mmap으로 할당되지 않았다면 위의 조건문이 수행된다 

  • p가 top 청크가 아닌 경우 (청크 p가 힙 영역내에 존재하는지 검사)
    • 아레나의 flag에 NONCONTIGUOUS_BIT가 설정 되었는지 확인하고 설정되어있으면 아래 검사를 수행한다
      • 청크 p가 min_address보다 큰지 검사
      • 청크 p + sz가 top chunk보다 작은지 검사
  • p가 top 청크인 경우
    • sz가 MINSIZE보다 큰지 검사
    • p의 PREV_INUSE 비트 검사

 

  else
    {
      /* address is outside main heap  */
      if (contiguous (av) && av->top != initial_top (av))
        {
          assert (((char *) p) < min_address || ((char *) p) >= max_address);
        }
      /* chunk is page-aligned */
      assert (((p->prev_size + sz) & (GLRO (dl_pagesize) - 1)) == 0);
      /* mem is aligned */
      assert (aligned_OK (chunk2mem (p)));
    }

만약 mmap을 통해 p가 할당되었다면 위의 코드가 수행된다 

 

 

 

 

reference

https://chenyuzhuwhiskey.github.io/glibc-malloc-analysis/

 

'Heap analysis > glibc 2.23' 카테고리의 다른 글

(glibc 2.23)check_malloced_chunk  (0) 2022.03.30
(glibc 2.23) free  (0) 2022.03.23
(glibc 2.23) do_check_free_chunk  (0) 2022.03.22
(glibc 2.23) do_check_inuse_chunk  (0) 2022.03.01
(glibc 2.23) check_remalloced_chunk  (0) 2022.03.01