#include<cstring>
#include<iostream>usingnamespacestd;intmain(){charbuffer[4];constchar*input="12345678";if(strlen(input)>=sizeof(buffer)){cout<<"입력 값이 너무 깁니다"<<endl;returnEXIT_FAILURE;}strncpy(buffer,input,sizeof(buffer)-1);buffer[sizeof(buffer)-1]='\0';cout<<buffer<<endl;returnEXIT_SUCCESS;}
스택 오버플로우
버퍼 오버플로우의 한 종류
스택 포인터가 스택의 경계를 넘어설 때 발생
원인
무한 재귀 호출: 재귀 함수가 종료 조건 없이 계속 호출되어 스택 프레임이 쌓임
지역 변수 과다 할당: 함수 내에서 매우 큰 크기의 지역 배열 선언
스레드 스택 크기 초과: 스레드는 기본적으로 제한된 스택을 가짐 (Linux 기본 8MB)
결과
프로그램 비정상 종료 (Segmentation Fault)
인접한 스택 프레임의 데이터 변조 가능
대처
재귀 함수를 반복문으로 대체
큰 데이터는 스택이 아닌 힙(new, malloc)에 할당
재귀 깊이 제한 (최대 깊이 검사)
예시
무한 재귀 (스택 소진)
// ❌ 종료 조건 없는 무한 재귀voidfunc(){func();}intmain(){func();}// Segmentation fault
올바른 재귀 (종료 조건 포함)
// ✅ 종료 조건 있는 재귀voidfunc(intdepth){if(depth==0)return;func(depth-1);}intmain(){func(100);}
#include<cstring>
#include<cstdlib>
#include<iostream>usingnamespacestd;intmain(){// 4바이트만 할당char*heapBuffer=newchar[4];// 8바이트 복사 → 힙 오버플로우: 인접 힙 청크 침범strcpy(heapBuffer,"AAAABBBB");cout<<heapBuffer<<endl;delete[]heapBuffer;returnEXIT_SUCCESS;}
정수 오버플로우로 인한 힙 오버플로우
// 악의적인 입력으로 size 값을 조작하면 할당 크기가 0이 될 수 있음voidprocess(size_tcount){// count = 0x40000001이면 count * 4 = 4 (32비트 오버플로우)char*buf=newchar[count*4];// 이후 count 기준으로 쓰기 → 힙 오버플로우memset(buf,0,count*4);delete[]buf;}
#include<iostream>
#include<cfloat>usingnamespacestd;intmain(){// 부동소수점 언더플로우floatf=FLT_MIN;// 약 1.175e-38 (최소 정규화 수)cout<<f/1e20<<endl;// 0 또는 매우 작은 비정규화 수// 부호 없는 정수 언더플로우 (래핑)unsignedintu=0;cout<<u-1<<endl;// 4294967295 (UINT_MAX)returnEXIT_SUCCESS;}