본문 바로가기

Heap analysis/glibc 2.29

(glibc 2.29) _int_malloc

glibc 2.26버전에 대한 이해가 있다라고 가정하고 바뀐 코드 위주로 정리할 것이다

각 소제목에 해당되는 상세 설명은 각 리스트 아래 더보기 참고

전체 코드는 아래 더보기

인자 및 변수 (삭제)


변경 및 추가된 코드

  • errstr변수 삭제
더보기
  const char *errstr = NULL;

이전에 버전에서 에러 문자열을 저장하는 errstr을 더 이상 사용하지 않는다

initical check (동일)


glibc 2.26버전과 동일

 

 

 

fastbin (변경, 추가)


변경 및 추가된 코드

  • 초기에 REMOVE_FB 매크로로 vicitm에 값을 저장하는 것이 아닌 *fb로 최상단 청크를 저장
  • fastbinsY를 갱신과 freed chunk 재사용을 하기 전에 freed chunk가 있는지 검사
  • fastbin에 있는 청크를 tcache로 옮기는 과정에서 단일 스레드일 때 처리되는 코드 추가
더보기

변수


      mchunkptr pp;
      victim = *fb;

fb를 통해 해당 fastbin의 최상단에 있는 freed chunk를 pp가 아닌 victim에 저장한다 ( 이전에는 pp에 저장했다 )

pp는 초기화하지 않는다

 

※ fastbinsY를 갱신하고 fastbin 및 tcache를 재사용하는 코드를 수행하기 전에 freed chunk가 있는지 확인하는 조건문이 수행된다

fastbinsY 갱신


 if (victim != NULL)
	{
	  if (SINGLE_THREAD_P)
	    *fb = victim->fd;
	  else
	    REMOVE_FB (fb, pp, victim);
      
                 ...

fastbinsY배열을 갱신하기 전에 freed chunk가 있는지 검사한다

단일 스레드일때와 아닐때 fastbinsY를 갱신하는 코드가 추가 되었다

  • 단일 스레드일 경우 : *fb에 victim의 다음 freed chunk를 저장한다 ( fastbinsY에 최상단 청크를 제거 )
  • 단일 스레드 아닐 경우 : REMOVE_FB 매크로를 통해 pp에 최상단 청크를 저장하고 fastbinsY를 갱신한다 

tcache 재사용할 때


		  /* While bin not empty and tcache not full, copy chunks.  */
		  while (tcache->counts[tc_idx] < mp_.tcache_count
			 && (tc_victim = *fb) != NULL)
		    {
		      if (SINGLE_THREAD_P)
			*fb = tc_victim->fd;
		      else
			{
			  REMOVE_FB (fb, pp, tc_victim);
			  if (__glibc_unlikely (tc_victim == NULL))
			    break;
			}
		      tcache_put (tc_victim, tc_idx);
		    }

fastbin에 있는 freed chunk를 tcache를 옮기는 과정에서 단일 스레드일 경우 처리해주는 코드가 추가 되었다 ( fastbinsY 갱신과 동일한 과정 )

 

추가된 보안 검사

  • 없음

small bin (동일)


glibc 2.26버전과 동일

large bin (동일)


glibc 2.26버전과 동일

 

 

using unsorted bin (추가, 변경)


변경 및 추가된 코드

  • 보안 검사를 위한 변수 선언 및 size구하는 코드 검사 이전으로 이동 
더보기

변수


          size = chunksize (victim);
          mchunkptr next = chunk_at_offset (victim, size);

bck를 구한 뒤 위 코드가 추가 되었다

size가 관련된 검사가 추가 되면서 검사 이후에 size를 구하는 코드가 bck를 구한 뒤 바로 수행된다

검사를 위해 next 변수를 선언하고 victim의 다음 청크 주소를 저장한다

 

추가된 보안 검사

  • while문 초입 부분
    • next의 size 검사
    • next의 prev_size와 victim의 size 동일한지 검사
    • victim->bk의 fd가 vicitm이고 victim->fd가 해당 bins주소인지 검사
    • next에 prev_inuse 비트가 설정되어 있는지 검사
  • unsorted bin에서 victim 제거하기 전
    • bck의 fd가 victim인지 검사
더보기

while문 초입 부분


          if (__glibc_unlikely (chunksize_nomask (next) < 2 * SIZE_SZ)
              || __glibc_unlikely (chunksize_nomask (next) > av->system_mem))
            malloc_printerr ("malloc(): invalid next size (unsorted)");
            
          if (__glibc_unlikely ((prev_size (next) & ~(SIZE_BITS)) != size))
            malloc_printerr ("malloc(): mismatching next->prev_size (unsorted)");
          
          if (__glibc_unlikely (bck->fd != victim)
              || __glibc_unlikely (victim->fd != unsorted_chunks (av)))
            malloc_printerr ("malloc(): unsorted double linked list corrupted");
          
          if (__glibc_unlikely (prev_inuse (next)))
            malloc_printerr ("malloc(): invalid next->prev_inuse (unsorted)");

unsorted bin에서 victim 제거하기 전


          /* remove from unsorted list */
          if (__glibc_unlikely (bck->fd != victim))
            malloc_printerr ("malloc(): corrupted unsorted chunks 3");
          unsorted_chunks (av)->bk = bck;
          bck->fd = unsorted_chunks (av);

리스트에서 victim을 제거하기 전에 검사가 추가 되었다

large bin으로 재할당 (동일)


glibc 2.26버전과 동일

binmap 탐색을 통해 재할당 (동일)


glibc 2.26버전과 동일

top chunk로 재할당 (추가)


추가된 보안 검사

  • top chunk로 재할당하기 전
    • top 청크의 size 검사
더보기
      victim = av->top;
      size = chunksize (victim);

      if (__glibc_unlikely (size > av->system_mem))
        malloc_printerr ("malloc(): corrupted top size");

      if ((unsigned long) (size) >= (unsigned long) (nb + MINSIZE))
        {
        
        				...

top 청크를 통해 재할당을 하기 전에 top 청크 size가 av->system_mem보다 큰지 검사한다

 

 

이를 제외한 코드는 2.26버전과 동일하다

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

(glibc 2.29) tcache_get  (0) 2022.05.19
(glibc 2.29) tcache_init  (0) 2022.05.19
(glibc 2.29) _int_free  (0) 2022.05.15
(glibc 2.29) free  (0) 2022.05.15
(glibc 2.29) malloc  (0) 2022.05.07