메모리 오염 취약점 : 공격자가 메모리를 악의적으로 조작해, 조작된 메모리 값에 의해 CPU가 잘못된 동작을 하는 상황을 유발하는 취약점
세그먼트
세그먼트(segment) : 적재되는 데이터의 용도별로 메모리의 구획을 나눈 것
크게 코드 세그먼트, 데이터 세그먼트, BSS 세그먼트, 힙 세그먼트, 스택 세그먼트로 구분된다.
운영체제가 메모리를 용도별로 나누면, 각 용도에 맞게 적절한 권한을 부여할 수 있다.
권한은 읽기, 쓰기, 실행이 존재하며, CPU는 메모리에 대해 권한이 부여된 행위만 할 수 있다.

코드 세그먼트
코드 세그먼트(Code Segment) : 실행 가능한 기계 코드가 위치하는 영역, 텍스트 세그먼트(Text Segment)라고도 불린다.
읽기 권한과 실행 권한이 부여된다.
int main() { return 31337; }
31337을 반환하는 main함수가 컴파일 되면 554889e5b8697a00005dc3로 변환되는데, 이 기계 코드가 코드 세그먼트에 위치한다.
데이터 세그먼트
데이터 세그먼트(Data Segment) : 컴파일 시점에 값이 정해진 전역 변수 및 전역 상수들이 위치한다.
CPU가 이 세그먼트의 데이터를 읽을 수 있어야 하므로, 읽기 권한이 부여된다.
data 세그먼트 : 쓰기가 가능한 세그먼트, 전역 변수와 같이 프로그램이 실행되면서 값이 변할 수 있는 데이터들이 위치한다.
rodata(read-only data) 세그먼트 : 쓰기가 불가능한 세그먼트, 프로그램이 실행되면서 값이 변하면 안되는 데이터들이 위치한다.
int data_num = 31337; // data
char data_rwstr[] = "writable_data"; // data
const char data_rostr[] = "readonly_data"; // rodata
char *str_ptr = "readonly"; // str_ptr은 data, 문자열은 rodata
BSS 세그먼트
BSS 세그먼트(BSS Segment, Block Started By Symbol Segment) : 컴파일 시점에 값이 정해지지 않은 전역 변수가 위치한다.
프로그램이 시작될 때, 모두 0으로 값이 초기화되므로 초기화되지 않은 전역 변수의 값은 0이다.
BSS 세그먼트는 읽기 권한 및 쓰기 권한이 부여된다.
스택 세그먼트
스택 세그먼트(Stack Segment) : 프로세스의 스택이 위치한다.
함수의 인자나 지역 변수와 같은 임시 변수들이 실행중에 이곳에 저장된다.
스택 프레임(Stack Frame)이라는 단위로 사용되어 함수가 호출될 때 생성되고, 반환될 때 해제된다.
어떤 프로세스가 실행될 때, 이 프로세스가 얼마 만큼의 스택 프레임을 사용하게 될 지를 미리 계산하는 것은 일반적으로 불가능하기 때문에 프로세스를 시작할 때 작은 크기의 스택 세그먼트를 먼저 할당해주고, 부족해 질 때마다 이를 확장하는 방식이고, 이를 아래 방향으로 자란다고 표현한다.
스택 세그먼트는 읽기와 쓰기 권한이 부여된다.
힙 세그먼트
힙 세그먼트(Heap Segment) : 힙 데이터가 위치하는 세그먼트
스택과 마찬가지로 실행중에 동적으로 할당될 수 있으며, 리눅스에서는 스택 세그먼트와 반대 방향(위)으로 자란다.
C언어에서 malloc(), calloc() 등을 호출해서 할당받는 메모리가 이 세그먼트에 위치한다.
힙 세그먼트는 읽기와 쓰기 권한이 부여된다.
리눅스는 스택을 메모리의 끝에 위치시키고, 힙과 스택을 반대로 자라게 해 힙과 스택은 메모리를 최대한 자유롭게 사용할 수 있으며, 충돌 문제로부터도 비교적 자유롭다.
요약
세그먼트
|
역할
|
일반적인 권한
|
사용 예
|
코드 세그먼트
|
실행 가능한 코드가 저장된 영역
|
읽기, 실행
|
main() 등의 함수 코드
|
데이터 세그먼트
|
초기화된 전역 변수 또는
상수가 위치하는 영역
|
읽기와 쓰기 또는 읽기 전용
|
초기화된 전역 변수, 전역 상수
|
BSS 세그먼트
|
초기화되지 않은 데이터가
위치하는 영역
|
읽기, 쓰기
|
초기화되지 않은 전역 변수
|
스택 세그먼트
|
임시 변수가 저장되는 영역
|
읽기, 쓰기
|
지역 변수, 함수의 인자 등
|
힙 세그먼트
|
실행중에 동적으로 사용되는 영역
|
읽기, 쓰기
|
malloc(), calloc() 등으로
할당 받은 메모리
|