구글에서 2012년쯤에 컴파일러단에 아주 참한걸 배포했어.
보통 버퍼가 넘친다던지해도 프로그램이 중단이라도 되야 알기 마련이잖아?
이런 코드가 있다고 해보자
int main() {
char *a = malloc(1);
a[1] = 1;
}
malloc의 경우 보통 사이즈를 4 또는 8단위로 올림해서 할당하기때문에 프로그램의 흐름에는 별 영향을 주지 않는 경우가 대부분이야
따라서 이 자체로만 보면 운영에 심각한 버그는 아니라고 할 수 있겠지. 하지만 이런 경우는 어떨까?
int main(int argc, char *argv[]) {
int size = atoi(argv[1]);
char *a = malloc(size);
a[size] = 1;
}
그리고 여기에 size를 1로 줘보자. 아마 맨 위의 코드와 동작은 같을거야. 프로그램 흐름에도 영향을 안주고.
하지만 여기서 만약 8 등의 사이즈를 주면 이 코드는 향후 프로그램의 동작에 심각한 영향을 미쳐.
할당 관련 데이터가 보통 malloc 한 버퍼의 앞뒤에 딱 붙어서 위치하기 때문이야. (힙의 metadata라고 하기도 해)
한 발 물러서서 8글자가 할당이 될 일이 보통 없다고 해보자.
하지만 누가 8글자를 할당해버리면? 잘하면 프로그램이 아예 털려서 서버까지 털릴 수 있어. [1]
뭐 그러면 버그를 잡는 게 낫겠지? 코드가 잘 숨어있으면 찾기도 힘들겠지
물론 버그를 미리 잡아주는 도구들이 꽤 많이 있지만, 여러 가지 이유로 잡지 못하는 경우도 있어. (알림이 너무 많다던지, ...)
개발자들은 생각했어. 모든 메모리 접근 명령어에 체크를 하나씩 둬서, 이게 읽거나 써도 되는 영역인지 확인할 수 있게 하면 어떨까?
물론 속도도 빠른게 좋겠지.
이게 원래 소스고,
a[size] = 1;
이게 대충 체크를 넣어준 소스.
char *tmp = a + size;
if(SHADOW[tmp / 8]) check_slowpath(tmp);
a[size] = 1;
check_slowpath에서는 해당 영역이 써도 되는 영역인지 느리지만 조금 더 진중하게 바라보는 역할을 해줘
가령 이게 지역 변수인지, malloc으로 할당된 영역인지, 이미 free된 영역인지, ...
그래서 체크에 실패하면 그 즉시 프로그램을 종료시켜줘.
게다가
free된 영역에 쓰는 경우에는 어디서 alloc했고 어디서 free했고 어디서 접근했는데 오류났는지까지 스택트레이스까지 보여주면서 엄청 잘 알려줘.
조금 더 까다로운 메모리 쓰기같은거야.
오류가 있으면 바로 프로그램을 종료시켜주니까.
사실 근데 이러면 퍼포먼스가 떨어질만도 하잖아? 음
물론 떨어져
하지만 엄청 많이는 아냐
일단 체크를 해야될 부분에만 체크를 넣기도 하고,
memcpy같은 몇몇 자주 쓰이는 함수에 대해서는 범위가지고 체크하는 함수를 따로 만들어두고, ...
그리고 사실 실제 서버에다가 이걸 붙여놓고 돌리는건 케바케로 추천/비추천이야.
속도가 쪼금 떨어질뿐만 아니라 프로그램이 이어나갈 가능성이 있음에도 프로그램을 종료시키는건 장/단점이 있거든.
그래서 보통 이런건 랜덤하게 입력을 넣어보는 테스트(퍼징이라고 하는 사람들도 있어)에서 붙여놓고 해
아마 예제 목록 보면 입력을 많이받는 꽤 굵직굵직한 프로젝트에서 많이 쓸거야
브라우저 등..
물론 학교 과제같은거 할때도 꽤 유용하게 쓸 수 있었던거 같아
버그 잡을때 이거만큼 꿀인게 없었지
더 자세한 원리는 [2]에서 보도록 해
한줄 요약: 컴파일 옵션에서 -fsanitize=address를 붙이면 버그잡기 좋다
[1]: https://bpsecblog.wordpress.com/2016/10/06/heap_vuln/ (리눅스 기준. 윈도는 중단은 되지만 잘 털리지는 않음)
[2]: https://bit.ly/2vfGpzR
개추욧
너무 길어서 읽진 않았는데 valgrind 같은 건가요?
Valgrind의 컴파일타임버전인데 빨라용
정보글은 개추야
힙의 메타데이터는 힙 청크같은데 청크를 덮어쓰면서 발생하는 버그나 취약점을 방지해주는건가요? 가령 uaf나 더블 프리 버그 같은?
AddressSanitizer 깃헙에 쓰여져잇내요.. 죄송함니다
이거 구글이 만든거? - 164260의 휘발성 계정
ㅇㅇ
https://www.usenix.org/system/files/conference/atc12/atc12-final39.pdf
이렇게 논문도 구글이름으로 나와있네