운영체제 - 인터럽트

김유진·2023년 4월 21일
0

CS지식 정리

목록 보기
2/7

인터럽트

인터럽트란?

* 소프트웨어나 하드웨어로 인해 발생하는, CPU의 처리가 필요한 이벤트를 CPU에 알려서 처리하도록 하는 기술
* 일종의 이벤트로, 발생하는 이벤트에 맞게 운영체제에서 처리
* 인터럽트를 실행하기 위한 opcode(명령 코드)는 int
* 인터럽트는 컴퓨터 부팅 시 미리 정의되어 이벤트와 실행코드 주소가 IDT에 기록되어 있음.
* 인터럽트는 CPU에 직접 전달되지 않는다.
 	* PIC(Programmable Interrupt Controller)에 의해서 인터럽트 요청을 순차적으로 처리
    * 최근에는 Advanced(고급) PIC를 활용하여 Local/I/O APIC로 나누어 활용
    * I/O APIC: CPU 코어들 사이의 외부 Interrupt를 분산하기 위해 사용.
    * Local APIC: CPU 코어들 사이의 외부 Interrupt를 분산하기 위해 사용.

IDT ( Interrupt Descriptor Table )
미리 정의되어 있는 인터럽트들의 번호 와 실행 코드 를 가리키는 주소 들이 저장되어 있는 Table.
APIC(Advancesd Programmable Interrupt Controller)
APIC(Advanced Programmable Interrupt Controller)는 더 많은 출력, 더 복잡한 우선 순위 계획, 고급 IRQ 관리를 포함하는 더 섬세한 프로그래머블 인터럽트 컨트롤러(PIC)이다.

인터럽트 사용 예시

  • 선점형 스케줄러 구현 시 (타이머 인터럽트)
    • 프로세스 Running 중 이를 중단시키고 다른 프로세스로 교체하기 위해 running -> ready 상태로 만들기 위해 인터럽트를 사용
  • I/o Device와 커뮤니케이션을 위해서 인터럽트가 필요
    • 저장매체에서 데이터 처리 완료시, 프로세스를 깨워야 합니다.(block state에서 ready state로)그렇게 하기 위해서는 인터럽트가 필요한 것입니다.
  • 예외 상황 핸들링
    • CPU가 프로그램을 실행하던 도중 이상 동작(0으로 나누는것)이 발생하는 경우 CPU가 해당 처리를 할 수 있도록 CPU에 고지함.

인터럽트의 종류

  • 내부 인터럽트(트랩/소프트웨어 인터럽트)
    • 주로 소프트웨어 내부에서 잘못된 명령 혹은 잘못된 데이터 사용 시 발생
  • 외부 인터럽트
    • 주로 하드웨어에서 발생하는 이벤트

주요 인터럽트 우선순위

  • 하드웨어 리셋 혹은 장치 검사
    • reset/machine check
  • 태스크 스위치의 T 플래그 셋(1)
    • TSS의 T플래그가 1로 세팅
  • 외부 하드웨어 간섭
    • FLUSH/STOPCLK/SMI(system management interrupt)/INIT(초기화)등
  • 이전 명령어에서 소프트웨어적인 인터럽트 발생 시
    • Breakpoint 혹은 Debug 관련 예외사항
  • 요청 거부를 할 수 없는 인터럽트(Nonmaskable)
  • 요청 거부가 가능한 하드웨어 인터럽트(Maskable Hardware Interrupts)
  • Code Breakpoint에서의 폴트 발생
  • 다음 명령어 페치 과정에서의 폴트
    • Code Segment Limit 오류
    • Code Page 폴트 발생
  • 다음 명령어의 디코딩 과정에서의 폴트
    • 명령어의 길이가 15바이트보다 긴 경우
    • 유효하지 않은 Opcode(명령어)
    • 코프로세서의 사용이 불가능한 경우
  • 명령어 실행 시 발생하는 폴트
    • 오버플로우
    • 바운드 에러
    • 유효하지 않은 TSS
    • 존재하지 않는 세그먼트
    • 스택 폴트
    • 보호 기법에 의한 폴트
    • 데이터 페이지 폴트
    • 정렬되지 않은 피연산자 감지
    • X87 부동소수점 예외
    • SIMD 부동소수점 예외
    • 가상화 예외

RAM상에 태스크의 상태를 보존 할 영역, 즉 모든 레지스터 값들이 보존될 영역을 TSS(Task State Segment)라고 합니다. 코프로세서(영어: coprocessor)는 CPU의 기능을 보충하기 위해 사용되는 컴퓨터 프로세서이다.

인터럽트의 발생 및 처리

인터럽트 실행 흐름

* 커널은 현재 프로세스의 실행을 중지(작업에 대한 선점)
* 인터럽트 핸들러와 인터럽트 전송 컨트롤러를 찾아서 핸들러 실행
* 인터럽트 핸들러의 동작이 완료된 이후 중지된 프로세스 실행 재개

IDT

  • Interrupt들과 exception handler(예외 처리)의 엔트리 포인트(진입점)를 저장하는 구조체로, gate 형태(자료구조 중 하나)를 이루고 있음
  • 서로 다른 권한 레벨의 Interrupt Handler 혹은 프로시저를 호출할 수 있도록 해주는 gateway 역할을 하는 구조체이다.
  • IDT에 들어갈 수 있는 게이트의 종류는 Task Gate/Trap Gate/Interrupt Gate로 총 3가지가 있다.
  • IDT는 최대 256개의 gate를 포함할 수 있고, 이 내부에는 다음과 같은 정보들이 포함되어 있다.
    - Handler Offset: 인터럽트 혹은 Exception Handler의 엔트리 포인트
    • Segment Selector : 인터럽트 혹은 Exception Handler 수행 시 코드 세그먼트를 교체해 동작에 필요한 권한으로 상승시킴
    • Interrupt Stack Table: 동작 수행 시 생성되는 별도의 스택 공간. 스택 공간 부족 및 데이터 덮어쓰기 방지를 위한 장치
    • Type: 어떤 IDT 게이트인지 설정해주는 비트로, 0110 - 인터럽트 게이트, 0111 - 트랩 게이트이다.
    • Descriptor Privilege Level(DPL): 디스크립터 사용에 필요한 권한으로, 0~3(Ring)의 범위를 가지며 접근 권한을 제어
    • P: 현재 사용하는 디스크립터가 유효한지(1) 혹은 유효하지 않은지(0)를 나타낸다.

프로시저: 일련의 쿼리를 마치 하나의 함수처럼 실행하기 위한 쿼리의 집합입니다.

[1]: 인터럽트 게이트로 Type이 세팅되면 핸들러 수행 도중 방해받지 않으며, 트랩 게이트로 설정 시 다른 인터럽트가 발생할 수 있다.
IST는 x86_64에서 새로 도입된 스택 스위칭 메커니즘이다. 인터럽트 혹은 exception 상황은 코드 수행 도중

IST x86_64에서 새로 도입된 스택 스위칭 매커니즘이다. 인터럽트 혹은 exception 상황은 코드 수행 도중 발생하는 것이므로, 이를 처리하기 위한 핸들러가 동작할 때의 스택 상태를 예측할 수 없다. 기존 스택이 다 할당된 상태에서 코드가 수행되면 다른 영역을 침범할 수 있으므로 이를 해결하기 위한 방식이 IST다. 다만 모든 인터럽트의 핸들링에 사용되는 것은 아니고, 일부 인터럽트에서 레거시 스택 스위칭 방식을 사용한다. IST 스택 전환 메커니즘을 위해서 TSS에서는 최대 7개의 IST 포인터를 제공하고, 이는 IDT의 인터럽트 게이트에 의해서 참조된다.


* IST : 인터럽트 서비스 쓰레드(interrupt Service Thread) 장치 관리자를 통해 쓰레드 동작되며, 응용프로그램에서 가장 높은 쓰레드로 동작한다. * ISR : 인터럽트 서비스 루틴(Interrupt Service Routine)
  • kernal address sanitizer의 약자로 동적 메모리 관련 버그(oob, uaf)를 찾기 위한 도구입니다.
  • OOB (Out Of Boundary)는 버퍼의 길이 범위를 벗어나는 인덱스에 접근할 때 발생하는 취약점 입니다.
  • Use After Free (UAF)
    줄여서 UAF라 부름. Heap 영역에서 할당된 (malloc) 공간을 free로 영역을 해제하고, 메모리를 다시 할당 시 같은 공간을 재사용 하면서 생기는 취약점임
    ex) 문제를 풀 때 어떤 heap영역을 free를 해주는 걸 본다면, 이를 UAF를 이용하여 새로운 heap을 할당해주고, 내가 원하는 값을 입력한 후 기존 heap을 실행시켜서 exploit시킬 수 있습니다. 이게 기본적인 UAF의 개념입니다.

KASAN - 런타임 메모리 디버거디다.
https://hyeyoo.com/165


인터럽트 스택 - https://eclipsemode.tistory.com/73

IRET: 인터럽트 리턴
EP: 엔드 포인트

  • 세그먼트 레지스터
    CS(Code Sefment)
    SS(Stack Segment)
    DS(Data Segment)
    ES(Ectra Segment)

세그먼트 레지스터 - https://ezbeat.tistory.com/143
특권 레벨 - https://stdnstr.tistory.com/199

  • Flag Register(플래그 레지스터)
    : EFLAGS로 칭하며 32비트 크기이다.(접두사 E를 보기 바람)
    : 각각의 비트마다 1 OR 0의 값을 갖는다(Boolean)
    : 리버싱 입문에선, 3가지 정도만 이해하고 넘어가면 된다고함(ZF, OF, CF)

ZF (Zero Flag)
: 연산 명령 후에 결과 값이 0이 되면 ZF가 1로 세팅된다.

OF (Overflow Flag)
: 부호 있는 수(signed integer)의 오버플로우가 발생했을 때, 1로 세팅된다. 부호를 나타내는 비트, 즉 MSB도 변경되었을 때도 1.

CF (Carry Flag)
: 부호 없는 수(unsigned)의 오버플로우가 발생했을 때 1로 세팅된다.

Insturction Pointer
: CPU가 처리할 명령어의 주소를 나타내는 레지스터이다. (크기 32비트)
: 다른 레지스터와는 다르게, 직접 값을 변경할 수 없다.

EIP
: gdb로 디버깅할 때 많이 본 거. 다음 실행할 명령의 주소를 가리키고 있음.

  • 포인터 레지스터 - https://yechoi.tistory.com/10
    RSP(Extended Stack Pointer)
    현재 스택 주소. 그러니까 스택 맨 윗쪽 주소. 스택에 있는 데이터의 주소를 지정. 계산, 데이터 전송에는 거의 사용되지 않는다
RIP
  현재 명령 실행 주소

profile
끊임없이 발전하는 개발자

0개의 댓글