AddressSanitizer(ASan) 사용법

AddressSanitizer(ASan)는 C/C++ 용 메모리 버그를 감지하는 컴파일러 기반 도구이다. AddressSanitizer는 프로그램을 실행하는 동안 메모리 오류를 식별하여 버그를 조기에 발견하고 수정할 수 있도록 도와준다. 이 글에서는 AddressSanitizer 사용법에 대해 알아본다.

ASan 장점

  • 조기 감지: ASan은 프로그램을 실행하는 동안 메모리 오류를 식별하여 버그를 조기에 발견하고 수정할 수 있도록 도와준다.
  • 자세한 보고서: ASan은 발생한 오류에 대한 자세한 보고서를 제공하여 개발자가 문제를 신속하게 진단하고 해결할 수 있도록 도와준다.
  • 낮은 오버헤드: ASan은 강력한 검사를 수행하지만 실행 시간 성능에 미치는 오버헤드가 낮아 실제 환경에서 사용하기에 비교적 적합하다.

감지하는 메모리 오류

AddressSanitizer가 인지하는 메모리 오류는 다음과 같다.

동작 방식

ASan은 프로그램을 컴파일할 때 코드에 추가적인 보조 코드를 삽입하여 메모리 접근을 검사한다. 다음은 ASan의 동작 방식이다.

  1. 메모리 주입: ASan은 컴파일 중에 프로그램의 코드에 메모리 접근을 검사하는 추가적인 코드를 삽입한다.
  2. 섀도 메모리: ASan은 메모리 상태를 추적하는 별도의 섀도 메모리를 사용한다. 섀도 메모리의 각 바이트는 프로그램 메모리의 바이트와 대응되며 해당 바이트의 메타데이터를 포함한다.
  3. 런타임 검사: 프로그램이 메모리를 읽거나 쓸 때 ASan은 해당 접근을 가로채고 섀도 메모리를 확인하여 접근이 유효한지 확인한다.
  4. 오류 보고: ASan은 메모리 오류가 발생할 때 오류 유형과 메모리 주소, 스택 추적 등 자세한 정보를 보고(report)한다.

ASan 사용법

ASan을 사용하려면 코드를 컴파일할 때 -fsanitize=address 플래그를 사용하여 ASan을 활성화해야 한다. 예를 들어:

gcc -o my_program -fsanitize=address my_program.c

컴파일된 이후에는 프로그램을 실행하면 ASan이 메모리 오류를 검출하고 자세한 보고서를 출력한다.

Use after free 예제:

다음은 free 이후에 액세스 하는 예제이다.

#include <stdlib.h>
int main() {
  char *x = (char*)malloc(10 * sizeof(char*));
  free(x);
  return x[5];
}

ASan 적용을 위해 컴파일 옵션으로 -fsanitize=address 를 주고, 스택 트레이스를 위해 -fno-omit-frame-pointer 역시 준다.

$ gcc use-after-free.c -fsanitize=address -fno-omit-frame-pointer

실행 결과:

실행 결과는 heap-use-after-free 를 detect 한 내용을 보여준다.

GDB 사용

일반적으로 GDB를 사용하여 ASan에서 빌드한 바이너리를 디버깅할 수 있다. ASan 버그를 발견하면 발견한 __asan_report_{load,store}{1,2,4,8,16} 함수 중 하나를 호출하여 __asan::ReportGenericError가 호출되도록 한다.

만약 ASan가 에러를 리포트하기 전에 stop을 원한다면, __asan::ReportGenericError 에 breakpoint를 설정한다.

그렇지 않고, 에러 리포트 후에 stop을 원한다면, __sanitizer::Die 에 breakpoint를 설정하던가, 바이너리 실행시에 ASAN_OPTIONS=abort_on_error=1를 환경설정하여 실행한다.

gdb 내에서 메모리 위치에 대해 설명하도록 요청할 수 있는데, 다음과 같다.

(gdb) set overload-resolution off
(gdb) p __asan_describe_address(0x7ffff73c3f80)
0x7ffff73c3f80 is located 0 bytes inside of 10-byte region [0x7ffff73c3f80,0x7ffff73c3f8a)
freed by thread T0 here: 
...

참고 사이트

답글 남기기