Linux의 메모리 구조에는 Code 세그먼트, Data 세그먼트, BSS 세그먼트, Heap 세그먼트, Stack 세그먼트
이렇게 5가지의 세그먼트가 있다. 각 세그먼트마다 읽기, 쓰기, 실행에 대한 권한이 부여되어 있어 취약점을 어느 정도 방지할 수 있다.
Code 세그먼트
Text 세그먼트라고도 불리며, 프로그램에서 실행 가능한 코드가 Text 세그먼트에 위치하게 된다. 코드 세그먼트는 CPU가 코드를 읽고 실행할 수 있도록 읽기 권한과 실행 권한이 부여된다.
하지만 쓰기 권한은 부여되지 않는다 왜일까?
누군가가 악의 적으로 실행 흐름을 바꿀 수도 있기 때문에 쓰기 권한은 부여되지 않는다고 한다
Data 세그먼트
Data 세그먼트는 컴파일 할때 코드에서 초기화된 전역 변수또는 전역 상수를 저장한다. Data 세그먼트에는 알아야 할 것이 하나 있다.
위에서 말했듯이 Data세그먼트는 전역 변수 또는 전역 상수를 저장하는데 여기서 살짝 헷갈리는 부분이 나온다.
그것이 (read only data; rodata)이다
Rodata 세그먼트는 쓰기가 불가능한 전역 상수 변수를 저장한다
int a = 10 //Data Segment
char b[] = "Hello wolrd" //Data Segment
const char c[] = "I Love You" //Rodata
char *ptr = "it's me rodata?" //Rodata
int main(void){...}
아마 *ptr부분이 왜 그런지 헷갈릴 것이다. 그럼 이유를 설명해 볼 테니 정신 바짝 차리길 바란다.
s1은 프로그램이 로딩될 때 정적 영역(rodata)에 "hello world"를 저장한 다음 문자열의 시작 주소를 s1포인터 변수에 대입한다. 문자열 포인터 s1에는 나중에 다른 주소 값을 대입할 수 있다, 즉 s1자체는 Data 세그먼트이다 그런데 s1의 "hello world"는 Rodata에 저장되어 있어 값을 변경할 수 없다
이런 느낌이 아닐까?
그렇다면 s2는 뭐가 다르길래?? 이러는 것일까??? 매우 다르다
s2는 이따 설명할 Heap 메모리를 할당한 후 "hello world"를 Heap 메모리에 저장했다
s2는 Heap 메모리에 있는 "hello world"의 시작 주소를 가지고 있는 것이다!!