전에 scanf와 gets 함수의 버퍼 오버플로우 취약점에 대해 얘기한 적이 있었다.
나는 주로 Visual Studio Code(VS Code)를 쓰지만 Visual Studio IDE(VS IDE)를 쓰면 VS IDE에서 기본적으로 제공하는 scanf_s 함수로 scanf의 버퍼 오버플로우를 해결할 수 있다.
gets도 똑같은 취약점을 가지고 있고 gets_s 함수를 제공하길래 써봤는데 내가 못 쓰는 건지 해결이 안 된다.
그래서 scanf와 scanf_s 기준으로 글을 작성해 보려고 한다. (전에도 gets는 뒷전이었지만..)
전에 썼던 코드를 그대로 컴파일 해보았다.
응..? 그런데 컴파일 에러가 뜬다.
'scanf': This function or variable may be unsafe. Consider using scanf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
번역하면
'scanf': 이 함수 또는 변수는 안전하지 않을 수 있습니다. 대신 scanf_s를 사용하는 것을 고려해 보십시오. 더 이상 사용하지 않도록 설정하려면 _CRT_SECURE_NO_WARNINGS를 사용하십시오. 자세한 내용은 온라인 도움말을 참조하십시오.
요약하면
scanf는 안전하지 않다.
scanf_s를 써라
그래도 쓸거면 _CRT_SECURE_NO_WARNINGS를 사용하라고 한다.
마이크로소프트에서는 scanf의 취약점을 인지하고 2010년대 초반부터 VS IDE에서 scanf를 사용하지 못하도록 하였다.
scanf_s? 쓰면 되지
C11 표준에 scanf_s가 수록되었다곤 하는데 10년이 지난 지금도 VS IDE의 컴파일러 cl 이외 컴파일러에서 scanf_s를 지원하지 않는 컴파일러들이 있다.
모두 다 VS IDE를 쓰면 상관이 없지만 개개인마다 다른 컴파일러를 쓰는 경우가 있어서 VS IDE에서 잘 컴파일 됐던 파일을 다른 팀원이 받아서 컴파일 했는데 안되는 경우가 생길 수 있다.
나 같은 경우도 GCC, G++ 컴파일러를 사용하는데 GCC 컴파일러를 사용하는 C 파일에서 작성된 scanf_s는 잘 컴파일 됐는데 G++ 컴파일러를 사용하는 CPP 파일에서 컴파일 하니 안된 기억이 있다.
이런 경우들 때문에 그들을 위해 scanf를 사용하는 일이 생긴다.
scanf 한번 써보자
경고 메시지에서는 _CRT_SECURE_NO_WARNINGS를 사용하라고 한다.
#define _CRT_SECURE_NO_WARNINGS
코드 상단에 복붙해주면 VS IDE에서도 scanf를 사용할 수 있다.
컴파일 되었다.
이왕 여기까지 온 거 VS IDE에서 디버깅도 한번 해보자
그때처럼 다른 str 메모리 영역을 침범해 덮어씌우지 않고 다른쪽 메모리를 손상시켜 VS IDE는 런타임 에러를 띄운다.
Run-Time Check Failure #2 - Stack around the variable 'str_1' was corrupted.
런타임 검사 실패 #2 - 변수 'str_1' 주변 스택이 손상되었습니다.
이번엔 scanf_s를 써보자
scanf_s("%s", str, sizeof(str) / sizeof(str[0]));
기존 scanf 인수에서 버퍼 사이즈를 추가로 지정해주면 된다.
디버깅을 해보면 입력 자체를 안 받은 걸 확인할 수 있다.
이렇게 입력 자체를 안 받아버리면 테스트 중 문제점을 발견하기도 쉽고 메모리 침범도 없어 디버깅이 쉬워지는데......
왜 printf("Hello World"); 마냥 킹표준이 되지 못하는 걸까 하는 생각이다.
'공부 > C언어, C++' 카테고리의 다른 글
[C언어/C++] 출력 함수 간단 요약 총정리(printf, puts, fprintf, fputs, putchar, putc, fputchar, fputc, cout 객체) (0) | 2023.03.13 |
---|---|
[C언어/C++] VS Code에서 헤더 파일 분할 구현 간단 설명(undefined reference to Error 에러 오류) (0) | 2023.03.09 |
[C언어] 입력 함수 scanf, gets 버퍼 오버플로우 (0) | 2023.03.08 |
[C언어] 입력 함수 scanf, gets (0) | 2023.03.07 |
[C언어] 출력 함수 printf, puts (0) | 2023.03.07 |