▲ 김종하 파수닷컴 선임 [PA사업팀 EA팀]http://story.wisedog.net/

[아이티데일리]  안녕하세요, 파수닷컴 정적분석개발팀입니다.
오늘부터 (비)정기적으로 정적분석이야기를 연재하려고 합니다. 많은 관심 부탁드립니다.
 
첫 번째 이야기는 소프트웨어 에러 유형 중 하나인 ‘Null Pointer Dereference(널 포인터 역참조)’ 에 대해서 이야기하고자 합니다. Null Pointer Dereference는 C, C++, Java, .Net 등의 언어에서 발생할 수 있는 에러인데요. 널 포인터에 어떠한 값을 대입할 때 발생하는 에러입니다.



C나 C++에서 널 포인터는 ‘어떠한 것도 가리키지 않는 포인터’, ‘할당되지 않은’ 것을 의미하는 특별한 포인터로 쓰입니다. 대부분의 운영체제에서는 이 널 포인터를 메모리의 첫 페이지 주소 0(0x00000000)로 사용하고 있습니다. 따라서 여기에 접근하면 보통 프로그램이 비정상적으로 종료합니다. 
 
Null Pointer Dereference 발생 예제



위 샘플 코드는 직접적으로 Null Pointer Dereference가 발생하는 예제입니다. int 형 포인터 p에 주소 0에 접근하는 포인터를 생성하고, 여기에 값을 할당하려고 시도했습니다. 이 경우 많은 운영체제에서는 세그멘테이션 결함이 발생하면서 프로그램이 종료됩니다.
 
그런데 절대다수의 코드에서 Null Pointer Dereference는 이렇게 눈에 빤히 보이는 코드에서 잘 발생하지 않습니다. 보통 라이브러리를 잘못 다룰 때 많이 쓰이죠. 많은 라이브러리 함수는 사용자가 의도한 값이 없거나, 기타 에러 등의 이유로 널 포인터를 리턴하는 경우가 많습니다. 이 리턴된 값을 확인 없이 바로 무언가를 쓸 때 Null Pointer Dereference가 종종 발생합니다. 아래 코드를 보시죠.

7번째 줄에서 malloc 함수를 호출 시 메모리가 부족하면 널 포인터가 리턴됩니다. 이 널 포인터를 그대로 my_strcpy()의 인자로 넘겨주고 my_strcpy 함수에서는 이 메모리 주소에 무언가를 write 하려하기 때문에 Null Pointer Dereference가 발생할 수 있죠. 이해를 돕기 위해 malloc 함수만 예로 들었지만 레퍼런스 상에서 널 포인터를 리턴할 수 있다고 명시한 모든 라이브러리 리턴 값을 잘못 다루거나 인지 값을 잘못 넘겨주면 언제든지 Null Pointer Dereference가 발생할 수 있습니다.

Null Pointer Dereference가 발생하면



일반적으로 Null Pointer Dereference가 발생하면 실행 중인 프로그램이 종료됩니다. 또한 보안적으로 취약해질 수 있습니다. 공격자가 의도적으로 Null Pointer Dereference를 실행하는 경우, 그 결과 발생하는 예외 사항을 추후 공격을 계획하는데 악용할 수 있기 때문입니다.

Null Pointer Dereference를 막으려면
 
왕도가 없습니다. 모든 포인터나 레퍼런스 혹은 널 포인터가 할당될 가능성이 있는 포인터나 레퍼런스에 대해서 사용전 널 포인터 체크를 하고 사용해야 합니다. 아래 소스 코드는 Null Pointer Dereference가 발생할 수 있는 코드입니다.

10번째 줄을 보겠습니다. "CGI_HOME"이라는 환경 변수가 없는 경우 getenv 함수는 널 포인터를 리턴합니다. 이 값을 널 포인터 확인 없이 그대로 strncpy 함수에 사용하면 Null Pointer Dereference가 발생합니다. 앞으로 아래처럼 프로그래밍해야겠죠? : )

현명한 개발자&회사의 해결책!
 
Null Pointer Dereference를 막는 방법은 알았는데, 막막하신가요? 아... 그렇습니다. 100줄, 200줄로 작성된 간단한 프로그램이 아닌 이상에야 사람 손으로 일일이 Null Pointer Dereference를 찾는 것은 비능률적입니다. 리눅스 커널은 수백만 라인이나 되는데 사람이 소스를 뒤져가면서 직접 찾아내는 것은 그야말로 삽질의 결정판이라 할 수 있습니다.
 


이 같은 삽질을 하지 않기 위해 많은 회사에서는 정적분석도구(Static Code Analysis Tool)를 사용합니다. 파수닷컴이 개발한 스패로우(Sparrow) 역시 이 Null Pointer Dereference 오류를 코드 레벨에서 검출할 수 있습니다.(체커 이름 :  NULL_DEREF) 다른 많은 정적 분석 도구와는 달리 문법기반(Syntactic) 분석이 아닌 의미기반(Semantic) 분석을 통해서 깊은 호출 관계 속에서도 정확도 높은 분석 결과를 얻을 수 있습니다.  
 



해당 글은 파수닷컴에서 아이티데일리 블로그 게제용으로 제공한 콘텐츠입니다.
저작권은 파수닷컴 측에 있으며, 무단전제 및 복제를 금합니다.
원문출처 : http://blog.fasoo.com/80195687469


 

저작권자 © 아이티데일리 무단전재 및 재배포 금지