본문 바로가기

CERT C/표현식

[CERT C/표현식] (2) 단축 평가 방식의 중요성

의미

단축 평가(short-circuit evaluation) 방식은 AND와 OR 논리 연산자에서 자주 사용되는 방식으로

첫 번째 피연산자로 평가가 완료되면 두 번째 피연산자는 평가하지 않고 끝내는 평가 방식이다.

동작 방식

연산자 좌측 피연산자 우측 피연산자
AND 거짓인 경우 평가 안함
OR 참인 경우 평가 안함

※ 첫 번째 피연산자 평가가 완료가 되어서 뒤에 있는 피연산자가 실행되지 않으면서 원하지 않는 동작이 발생할 수 있다.

문제 코드 1. 단축 평가 방식을 신경써서 AND, OR 연산자를 사용하자.

출력을 예상해보기

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define BUF_SIZE 25

int getString(const char *, char **);

int main()
{
    int res;
    char *p;

    if(p || (p = (char *)malloc(BUF_SIZE)))
    {
        res = getString("Input name", &p);
        if(res == 1)
        {
            printf("Name is %s", p);
        }
        free(p);
        p = NULL;
    }
    else{
        printf("Dynamic allocation error\n");
        return 1;
    }
    return 0;
}

int getString(const char *q, char **p)
{
    char *nr = NULL;

    printf("%s : ", q);
    if(fgets(*p, BUF_SIZE, stdin) == NULL)
    {
        return 0;
    }
    nr = strchr(*p, '\n');
    if(nr != NULL) *nr = '\0';

    return 1;
}

출력 : 

1_Short_circuit(1606,0x2007f2e00) malloc: *** error for object 0x304c49878: pointer being freed was not allocated
1_Short_circuit(1606,0x2007f2e00) malloc: *** set a breakpoint in malloc_error_break to debug

취약점 분석 및 해결 코드 1

분석 

 

(1) p가 NULL값일 수도 있고 아닐 수도 있으므로 포인터가 할당되지 않았다는 에러가 발생하게 된다.

 

해결 방법 : p가 NULL값이 아니라면 초기화하라.

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define BUF_SIZE 25

int getString(const char *, char **);

int main()
{
    int res;
    char *p;

    p = (char *)malloc(BUF_SIZE);
    if(p == NULL)
    {
        printf("동적메모리 할당에러!\n");
        return 1;
    }

    res = getString("Input name", &p);
    if(res == 1)
    {
        printf("Name is %s\n", p);
    }
    free(p);
    p = NULL;
    return 0;
}

int getString(const char *q, char **p)
{
    char *nr = NULL;

    printf("%s : ", q);
    if(fgets(*p, BUF_SIZE, stdin) == NULL)
    {
        return 0;
    }
    nr = strchr(*p, '\n');
    if(nr != NULL) *nr = '\0';

    return 1;
}

POINT

  • AND, OR 연산자를 if문에서 사용할 경우 단축 평가 방식을 염두하라.
  • 포인터 값에 대해서는 NULL 값을 반드시 체크해줘라.

참조


EXP02-C. Be aware of the short-circuit behavior of the logical AND and OR operators

 

 

wiki.sei.cmu.edu/confluence/display/c/EXP02-C.+Be+aware+of+the+short-circuit+behavior+of+the+logical+AND+and+OR+operators