의미
C 언어 같은 경우, 함수 포인터를 이용한 함수들은 타입을 읽을 때 가독성이 떨어지는 경우가 많다. 아래 signal 함수로 예를 들어본다.
void(*signal(int signum, void (*handler)(int)))(int)
signal 함수를 반환하는 부분과 매개변수 부분으로 나누어보면
(1) signal 함수는 두 개의 파라미터를 가진다.
signal(int signum, void (*handler)(int))
(2) signal 함수가 반환하는 값은
void (*)(int);
-> 함수 포인터 형이며 반환 값이 없고 int 매개변수를 받는 함수를 가르리키는 포인터이다.
문제 코드 1. 함수의 선언이 읽기도 어렵고 이해하기 힘들다.
#include <stdio.h>
int (*getFunction(int))(void);
int getFruits();
int getGrains();
int main()
{
int (*func)(void);
func = getFunction(1);
func();
func = getFunction(2);
func();
return 0;
}
int (*getFunction(int type))(void)
{
int (*func)(void);
switch(type)
{
case 1:
func = getFruits;
break;
case 2:
func = getGrains;
break;
}
return func;
}
int getFruits()
{
printf("getFruits() 함수가 선택되었습니다.\n");
return 1;
}
int getGrains()
{
printf("getGrains() 함수가 선택되었습니다.\n");
return 1;
}
취약점 분석 및 해결 코드 1
해결 방법 : int (*)(void) 타입을 따로 정의해서 사용한다.
#include <stdio.h>
//int (*getFunction(int))(void);
typedef int(*Func)(void);
Func getFunction(int);
int getFruits();
int getGrains();
int res;
int main()
{
Func func;
func = getFunction(1);
res = func();
if(res != 1) printf("문제 발생\n");
func = getFunction(2);
res = func();
if(res != 1) printf("문제 발생\n");
return 0;
}
Func getFunction(int type)
{
Func func;
switch(type)
{
case 1:
func = getFruits;
break;
case 2:
func = getGrains;
break;
}
return func;
}
int getFruits()
{
printf("getFruits() 함수가 선택되었습니다.\n");
return 1;
}
int getGrains()
{
printf("getGrains() 함수가 선택되었습니다.\n");
return 1;
}
POINT
- 가독성이 떨어지는 타입(함수형 포인터 등)은 상황에 적절한 타입으로 재정의해서 사용한다.
참조
DCL01-C. Do not reuse variable names in subscopes
wiki.sei.cmu.edu/confluence/display/c/PRE00-C.+Prefer+inline+or+static+functions+to+function-like+macroswiki.sei.cmu.edu/confluence/display/c/PRE06-C.+Enclose+header+files+in+an+include+guardwiki.sei.cmu.edu/confluence/display/c/PRE10-C.+Wrap+multistatement+macros+in+a+do-while+loopwiki.sei.cmu.edu/confluence/display/c/DCL01-C.+Do+not+reuse+variable+names+in+subscopes
'C, C++ > 선언과 초기화' 카테고리의 다른 글
[CERT C/선언과 초기화] (3) 기억클래스 취약성 (0) | 2021.01.23 |
---|---|
[CERT C/선언과 초기화] (2) 가변인자 함수 사용 시 주의할 점 (0) | 2021.01.22 |