


fixes 폴더로 들어가면 여러개의 폴더가 있음
파일 03,04,06을 제외하곤 2번의 fix요청이 있었음을 알 수 있다.
fix요청이 받아드려지고 고쳐진 소스파일은 targets에 저장된다.
report폴더에서 커버리지를 비교해볼 수 있다.

02,04,05의 코드 커버리지이다.

01,03,06 파일의 코드 커버리지이다.
우선 coverage report에서 볼 수 있듯이 다른 퍼징 타겟에 비해 매우 높은 커버리지 달성 비율을 보인다. 소스코드를 살펴보았더니

다양한 플래그 조합으로 JSON 파싱을 하고 있음을 알 수 있다.
무작위 입력 데이터를 핸들링할 수 있는 fuzz target을 만들어야 한다. 중간에 리턴을 하거나 에러가 나서 함수가 종료하지 않아야 커버리지가 높아진다.(아마..)
그런데 주목할 점은, 01~06의 소스 코드가 거의 비슷함에도 커버리지 부분에서는 큰 차이를 보인다.
앞서 언급했듯이 02,04,05의 커버리지는 매우 높은 반면, 01,03,05 는 상대적으로 저조하다.
차이점을 살펴보니, cJSON_PrintPreallocated 함수를 어떻게 활용했느냐 이다.
전자는 cJSON_PrintPreallocated(json,NULL,0,0)으로, 후자는
length = strlen(printed_json); cJSON_PrintPreallocated(json, printed_json, length, 0);으로 작성했다. 후자는 print_json의 길이만큼 실제로 버퍼를 할당하여 JSON 데이터를 포맷팅된 상태로 출력한다. 반면 전자는 'NULL'과 '0'을 사용하므로 포맷팅이나 실제로 출력이 수행되지 않는다. 이는 단순히 메모리 관련 작업을 피하고 JSON 객체를 정리하는 목적이다.(문자열을 버려버림)
그런데 한가지 궁금증이 생긴다. 메모리 할당을 추가하면 메모리 할당 실패시 처리 경로를 테스트 할 수 있어 커버리지가 증가하고, 할당된 메모리를 사용하는 다양한 경로를 테스트 하게 되어 커버리지가 증가하는 것이 아닌가? 그런데 왜 메모리 할당을 하지 않은 전자의 케이스에서 훨씬 높은 커버리지가 나오는 것일까?
이유를 생각해보면, 메모리 할당을 하지 않아 관련 예외 상황을 전면적으로 피할 수 있긴 하다.
(메모리 오류가 났을 때 바로 리턴해버리거나 exit이 발생하는 상황을 염두하긴 했다)
가정의 상황을 생각해보았다.
1.06파일

length = strlen(printed_json); 이 부분에서,
만약 print_json이 NULL이면 strlen은 NULL포인터를 참조하려고 하기 때문에 예기치 않은 동작이 발생할 수 있다.(segmentation fault or access violation)
퍼징을 하면서 위의 상황을 잦은 횟수로 맞닥뜨렸다면 함수는 종료될 것이다. 그렇다면 커버리지가 낮은게 설명이 된다.
(++따라서 06파일에 print_json이 NULL인지 확인하는 부분을 추가해야 할 듯 하다. )
2.03파일

cJSON 객체가 사용한 메모리를 해제하였다. 그런데 CJSON_PrintPreallocated함수에서 받는 'json' 객체는 반드시 유효해야 한다. 하지만 메모리 해제가 된 'json'객체가 NULL이기 때문에 함수호출은 NULL포인터 역참조 오류를 일으킬 수 있다. 이는 프로그램의 비정상적인 종료가 될 수 있음을 의미한다. 그래서 라인 커버리기자 낮은 것인가?