운영체제 기본/보호: 두 판 사이의 차이
총론 재작성: 보호 경계와 인자 검증의 필요성, 격리와 통신 비용 |
출처를 이름 있는 MediaWiki 각주와 문서 말미 참고 문헌으로 정리 |
||
| 6번째 줄: | 6번째 줄: | ||
'''보호'''는 프로그램이 접근할 수 있는 자원과 허용된 연산에 경계를 두고 이를 강제하는 일이다. 파일이나 주소 공간이라는 추상화를 제공하더라도 프로그램이 그 아래의 저장장치나 다른 주소 공간에 직접 접근할 수 있다면 경계는 무너진다. 따라서 자원을 관리하는 운영체제에는 요청을 거부할 수단과, 프로그램이 그 수단을 우회하지 못하게 하는 구조가 함께 필요하다. | '''보호'''는 프로그램이 접근할 수 있는 자원과 허용된 연산에 경계를 두고 이를 강제하는 일이다. 파일이나 주소 공간이라는 추상화를 제공하더라도 프로그램이 그 아래의 저장장치나 다른 주소 공간에 직접 접근할 수 있다면 경계는 무너진다. 따라서 자원을 관리하는 운영체제에는 요청을 거부할 수단과, 프로그램이 그 수단을 우회하지 못하게 하는 구조가 함께 필요하다. | ||
보호 규칙 자체도 보호해야 한다. 프로그램이 자신의 접근 권한을 기록한 메모리를 마음대로 수정할 수 있다면 권한 검사는 의미가 없어진다. 규칙을 집행하는 코드와 상태를 보호 대상과 분리해야 한다. [https://web.mit.edu/saltzer/www/publications/protection/Basic.html | 보호 규칙 자체도 보호해야 한다. 프로그램이 자신의 접근 권한을 기록한 메모리를 마음대로 수정할 수 있다면 권한 검사는 의미가 없어진다. 규칙을 집행하는 코드와 상태를 보호 대상과 분리해야 한다. <ref name="source-1">[https://web.mit.edu/saltzer/www/publications/protection/Basic.html Jerome H. Saltzer·Michael D. Schroeder, The Protection of Information in Computer Systems (1975), §I].</ref> | ||
== 실행 권한, 주소, 자원의 경계 == | == 실행 권한, 주소, 자원의 경계 == | ||
| 13번째 줄: | 13번째 줄: | ||
주소 공간은 접근 가능한 메모리의 범위를 나눈다. MMU를 사용하는 시스템에서는 운영체제가 주소 변환과 접근 권한을 설정하고, 하드웨어가 메모리 접근 때 이를 검사한다. 프로그램이 다른 주소를 계산했다고 해서 해당 메모리에 접근할 권한까지 생기지는 않는다. 잘못된 접근은 예외를 일으킬 수 있고, 운영체제는 이를 처리하거나 해당 프로그램의 실행을 중단한다. | 주소 공간은 접근 가능한 메모리의 범위를 나눈다. MMU를 사용하는 시스템에서는 운영체제가 주소 변환과 접근 권한을 설정하고, 하드웨어가 메모리 접근 때 이를 검사한다. 프로그램이 다른 주소를 계산했다고 해서 해당 메모리에 접근할 권한까지 생기지는 않는다. 잘못된 접근은 예외를 일으킬 수 있고, 운영체제는 이를 처리하거나 해당 프로그램의 실행을 중단한다. | ||
자원별 권한은 별도로 판단한다. 사용자 모드라는 이유만으로 모든 파일 접근이 금지되는 것은 아니며, 어떤 파일을 읽을 수 있다고 해서 수정도 허용되는 것은 아니다. CPU 권한 모드는 어떤 종류의 동작을 직접 실행할 수 있는지, 주소 공간은 어떤 메모리에 접근할 수 있는지, 자원 권한은 어떤 대상에 어떤 연산을 허용할지를 나눈다. [https://mit-pdos.github.io/xv6-riscv-book/first.html xv6: Operating system organization | 자원별 권한은 별도로 판단한다. 사용자 모드라는 이유만으로 모든 파일 접근이 금지되는 것은 아니며, 어떤 파일을 읽을 수 있다고 해서 수정도 허용되는 것은 아니다. CPU 권한 모드는 어떤 종류의 동작을 직접 실행할 수 있는지, 주소 공간은 어떤 메모리에 접근할 수 있는지, 자원 권한은 어떤 대상에 어떤 연산을 허용할지를 나눈다. <ref name="source-2">[https://mit-pdos.github.io/xv6-riscv-book/first.html xv6: Operating system organization].</ref> | ||
== 경계를 넘는 요청도 검증해야 한다 == | == 경계를 넘는 요청도 검증해야 한다 == | ||
격리된 프로그램도 파일을 읽고 다른 프로그램과 통신해야 한다. '''시스템 호출'''은 프로그램이 정해진 진입점을 통해 커널에 작업을 요청하는 경로다. 하드웨어가 제어를 커널로 넘기면 커널 코드가 요청을 처리하고 결과를 돌려준다. 호출자는 요청할 작업과 인자를 고를 수 있지만 커널에서 실행할 임의의 명령을 지정할 수는 없다. | 격리된 프로그램도 파일을 읽고 다른 프로그램과 통신해야 한다. '''시스템 호출'''은 프로그램이 정해진 진입점을 통해 커널에 작업을 요청하는 경로다. 하드웨어가 제어를 커널로 넘기면 커널 코드가 요청을 처리하고 결과를 돌려준다. 호출자는 요청할 작업과 인자를 고를 수 있지만 커널에서 실행할 임의의 명령을 지정할 수는 없다. | ||
예를 들어 데이터를 읽어 달라는 요청에는 대상, 결과를 저장할 주소, 최대 길이가 들어간다. 커널은 그 대상을 읽을 권한이 있는지와 결과를 돌려줄 메모리 범위가 유효한지 확인해야 한다. 주소와 길이를 합산할 때 정수 범위를 넘는 경우도 고려해야 한다. 호출자가 넘긴 숫자나 포인터를 신뢰하면 커널이 자신의 권한으로 금지된 접근을 대신 수행할 수 있다. [https://mit-pdos.github.io/xv6-riscv-book/trap.html xv6: Traps and system calls | 예를 들어 데이터를 읽어 달라는 요청에는 대상, 결과를 저장할 주소, 최대 길이가 들어간다. 커널은 그 대상을 읽을 권한이 있는지와 결과를 돌려줄 메모리 범위가 유효한지 확인해야 한다. 주소와 길이를 합산할 때 정수 범위를 넘는 경우도 고려해야 한다. 호출자가 넘긴 숫자나 포인터를 신뢰하면 커널이 자신의 권한으로 금지된 접근을 대신 수행할 수 있다. <ref name="source-3">[https://mit-pdos.github.io/xv6-riscv-book/trap.html xv6: Traps and system calls].</ref> | ||
검사 시점과 사용 시점 사이의 변화도 문제다. 다른 스레드가 인자가 담긴 메모리를 바꿀 수 있다면, 검사한 내용과 실제 처리한 내용이 달라질 수 있다. 필요한 값을 커널의 관리 영역에 복사하거나, 대상의 수명을 유지하고 동기화하는 등 처리 과정 내내 가정이 유지되도록 만들어야 한다. | 검사 시점과 사용 시점 사이의 변화도 문제다. 다른 스레드가 인자가 담긴 메모리를 바꿀 수 있다면, 검사한 내용과 실제 처리한 내용이 달라질 수 있다. 필요한 값을 커널의 관리 영역에 복사하거나, 대상의 수명을 유지하고 동기화하는 등 처리 과정 내내 가정이 유지되도록 만들어야 한다. | ||
| 30번째 줄: | 30번째 줄: | ||
== 참고 문헌 == | == 참고 문헌 == | ||
<references /> | |||
---- | ---- | ||
[[운영체제 기본|목차]] · 이전: [[운영체제 기본/추상화|추상화]] · 다음: [[운영체제 기본/프로세스와 스레드|프로세스와 스레드]] | [[운영체제 기본|목차]] · 이전: [[운영체제 기본/추상화|추상화]] · 다음: [[운영체제 기본/프로세스와 스레드|프로세스와 스레드]] | ||
2026년 10월 31일 (토) 07:03 판
약속을 지키지 않는 프로그램
이미지 변환 프로그램이 잘못된 포인터에 결과를 쓴다고 하자. 모든 프로그램이 메모리를 자유롭게 건드릴 수 있다면 이 실수가 편집 중인 문서나 운영체제의 관리 정보까지 훼손할 수 있다. 악의적인 프로그램은 같은 자유를 의도적으로 악용할 수 있다. 프로그램에 올바른 사용법을 알려 주는 것만으로는 이런 접근을 막을 수 없다.
보호는 프로그램이 접근할 수 있는 자원과 허용된 연산에 경계를 두고 이를 강제하는 일이다. 파일이나 주소 공간이라는 추상화를 제공하더라도 프로그램이 그 아래의 저장장치나 다른 주소 공간에 직접 접근할 수 있다면 경계는 무너진다. 따라서 자원을 관리하는 운영체제에는 요청을 거부할 수단과, 프로그램이 그 수단을 우회하지 못하게 하는 구조가 함께 필요하다.
보호 규칙 자체도 보호해야 한다. 프로그램이 자신의 접근 권한을 기록한 메모리를 마음대로 수정할 수 있다면 권한 검사는 의미가 없어진다. 규칙을 집행하는 코드와 상태를 보호 대상과 분리해야 한다. [1]
실행 권한, 주소, 자원의 경계
하드웨어의 권한 모드를 사용하는 운영체제에서는 일반 프로그램을 제한된 권한으로 실행하고, 메모리 매핑이나 장치 제어처럼 시스템 전체에 영향을 주는 동작은 커널이 담당한다. 사용자 모드에서도 산술 연산과 허용된 메모리 접근은 CPU가 직접 실행한다. 모든 명령을 커널이 대신 실행하면 보호를 위해 지나치게 큰 비용을 치르게 된다.
주소 공간은 접근 가능한 메모리의 범위를 나눈다. MMU를 사용하는 시스템에서는 운영체제가 주소 변환과 접근 권한을 설정하고, 하드웨어가 메모리 접근 때 이를 검사한다. 프로그램이 다른 주소를 계산했다고 해서 해당 메모리에 접근할 권한까지 생기지는 않는다. 잘못된 접근은 예외를 일으킬 수 있고, 운영체제는 이를 처리하거나 해당 프로그램의 실행을 중단한다.
자원별 권한은 별도로 판단한다. 사용자 모드라는 이유만으로 모든 파일 접근이 금지되는 것은 아니며, 어떤 파일을 읽을 수 있다고 해서 수정도 허용되는 것은 아니다. CPU 권한 모드는 어떤 종류의 동작을 직접 실행할 수 있는지, 주소 공간은 어떤 메모리에 접근할 수 있는지, 자원 권한은 어떤 대상에 어떤 연산을 허용할지를 나눈다. [2]
경계를 넘는 요청도 검증해야 한다
격리된 프로그램도 파일을 읽고 다른 프로그램과 통신해야 한다. 시스템 호출은 프로그램이 정해진 진입점을 통해 커널에 작업을 요청하는 경로다. 하드웨어가 제어를 커널로 넘기면 커널 코드가 요청을 처리하고 결과를 돌려준다. 호출자는 요청할 작업과 인자를 고를 수 있지만 커널에서 실행할 임의의 명령을 지정할 수는 없다.
예를 들어 데이터를 읽어 달라는 요청에는 대상, 결과를 저장할 주소, 최대 길이가 들어간다. 커널은 그 대상을 읽을 권한이 있는지와 결과를 돌려줄 메모리 범위가 유효한지 확인해야 한다. 주소와 길이를 합산할 때 정수 범위를 넘는 경우도 고려해야 한다. 호출자가 넘긴 숫자나 포인터를 신뢰하면 커널이 자신의 권한으로 금지된 접근을 대신 수행할 수 있다. [3]
검사 시점과 사용 시점 사이의 변화도 문제다. 다른 스레드가 인자가 담긴 메모리를 바꿀 수 있다면, 검사한 내용과 실제 처리한 내용이 달라질 수 있다. 필요한 값을 커널의 관리 영역에 복사하거나, 대상의 수명을 유지하고 동기화하는 등 처리 과정 내내 가정이 유지되도록 만들어야 한다.
격리와 협력의 비용
경계를 넘을 때는 실행 상태를 보존하고 복원하며 인자와 권한을 확인하는 비용이 든다. 데이터를 복사해야 할 수도 있다. 다만 커널에 진입했다고 반드시 다른 스레드로 문맥 교환하는 것은 아니다. 요청을 바로 끝내면 같은 스레드가 돌아오고, 기다려야 한다면 다른 스레드에 CPU를 넘길 수 있다.
이미지 처리 기능을 별도 프로세스에 두면 그 기능의 잘못된 메모리 쓰기가 편집기의 메모리를 직접 훼손하는 일을 막을 수 있다. 대신 큰 이미지와 결과를 주고받는 통신 비용이 생긴다. 공유 메모리로 복사를 줄이면 같은 영역에 대한 동기화와 변경 권한을 관리해야 한다. 경계를 나누는 단위와 데이터를 교환하는 방식은 함께 설계해야 한다.
최소 권한 원칙은 각 구성 요소에 필요한 자원과 연산만 허용하여 오류나 침해의 피해 범위를 줄인다. 그러나 허용된 출력 파일에 잘못된 결과를 쓰는 것까지 막아 주지는 않는다. 보호는 프로그램의 정확성, 공유 데이터의 동시성, 장애 후 복구를 모두 보장하는 말이 아니다. 어떤 실패를 경계 안에 가두고 어떤 협력을 허용할지 정하는 설계다.