본문 바로가기

CERT C/표현식

[CERT C/표현식] (4) 함수 반환 값의 중요성

의미

여러 API와 라이브러리에서 제공해주는 함수의 반환 값은 함수가 작업을 성공 또는 실패했는지를 판단할 수 있는 지표이다.

 

많은 사람들이 라이브러리를 사용할 때 사용하는 많은 함수들에 리턴값이 있고 그 리턴값들이 의미하는 값들을 처리해주는 것이 프로그램을 작성할 때 매우 중요하다.

동작 방식

man 명령어 (UNIX/LINNUX의 경우) 구글링, document를 통해 함수의 반환값을 확인하고 여러 상황에서 일어날 수 있는 반환값에 대한 처리를 해주어야한다.

문제 코드 1. 함수의 리턴 값을 반드시 확인하자

출력을 예상해보기

#include <stdio.h>
void myflush();

int main()
{
    int age;
    printf("Input age : ");
    scanf("%d", &age);
    myflush();
    printf("age : %d\n", age);

    return 0;
}

void myflush()
{
    while (getchar() != '\n'){}
}

출력 : 입력에서 문자가 입력되면 원하지 않은 출력이 발생한다. 즉, 사용자가 어떤 값을 입력할지 모르기 때문에 그에 맞는 처리를 해주어야하는데 그런 부분을 입력받은 값에 대해서 여러 검사를 하는 방법도 있겠지만, scanf라는 함수에서 반환되는 값으로 확인을 할 수 있다. 

취약점 분석 및 해결 코드 1

분석 

 

1. man 명령어를 통해서 scanf의 반환값에 대해서 찾아본다.

-> 포맷의 형식에 맞는 입력이 들어온 개수를 반환하고 틀릴 경우 EOF값을 반환한다고도 적혀있다. 그러므로 우리는 입력값 1개를 받으므로 아래와 같이 처리할 수 있다.

 

해결 방법 : 함수의 리턴값 처리

#include <stdio.h>
#include <assert.h>

void myflush();
void process(int);

int main()
{
    int age;
    int res;

    printf("Input age : ");
    res = scanf("%d", &age);

    if(res != 1)
    {
        printf("scanf error occur!\n");
    }
    else{
        printf("age : %d\n", age);
    }
    myflush();
    return 0;
}

void myflush()
{
    while (getchar() != '\n'){}
}

출력 : 아래와 같이 문자 입력을 적절히 예외처리하는 것을 확인할 수 있다. 

※ 입력값에 대한 복잡한 처리 없이 함수의 반환값으로 간단하고 확실히 오류를 처리할 수 있다.

 

POINT

  • 함수들의 리턴값을 무시하지 않고 확인해서 일어날 수 있는 여러 상황에 대비한다.

참조


EXP12-C. Do not ignore values returned by functions

 

wiki.sei.cmu.edu/confluence/display/c/EXP12-C.+Do+not+ignore+values+returned+by+functions