레이스 컨디션
A A

1. 레이스 컨디션이란?

- 하나의 공유 데이터를 여러 개의 프로세스가 동시에 접근하려고 할 때 생기는 문제

CPU 하나만 있을 때 레이스 컨디션이 발생할 수 있을까?

- 프로세스는 자기 자신의 주소 공간 내부에 있는 데이터만 접근할 수 있음

- CPU1의 프로세스A는 A의 주소 공간에 있는 데이터만 접근할 수 있고, CPU2의 프로세스B는 B의 주소 공간에 있는 데이터만 접근할 수 있음

-> CPU가 하나든 여러 개든, 다른 프로세스의 주소 공간에 있는 데이터는 접근 불가능

 

그럼 레이스 컨디션이 왜 생기느냐?

-> 운영체제가 끼어드는 경우. 이때는 CPU가 하나 있어도 문제가 생긴다.

 

- A라는 프로그램이 실행 중인 상태

- 프로세스는 본인이 할 수 없는 일을 운영체제에게 해달라고 요청할 수 있음 -> 시스템 콜

- 시스템 콜 중, 커널의 데이터를 읽고 변경하려는 찰나에 A의 CPU 할당 시간이 끝남

- CPU가 A로부터 프로세스 B로 넘어감

- B가 시스템 콜을 함

- B의 요청에 의해서 운영체제 코드가 실행됨

- A가 건드리던 동일한 데이터를 B의 요청에 의해서 건드려야 하는 상황이 됨

- B의 요청으로 운영체제가 해당 데이터를 변경함

- 나중에 CPU가 A로 다시 넘어감

- 하다 만 시스템 콜을 마저 진행하는데, 아까 데이터 읽기는 수행했으므로 다음 기계어가 수행됨

 

OS에서 레이스 컨디션은 언제 발생하는가?

1. 커널 수행 중 인터럽트 발생 시

2. 프로세스가 시스템 콜을 하여 커널 모드로 수행 중인데, context switch가 일어나는 경우

3. 멀티 프로세서에서 공유 메모리 내의 커널 데이터

 

- 두 프로세스의 주소 공간 간에는 데이터 공유가 없음

- 그러나 시스템 콜을 하는 동안에는(커널 모드 전환) 커널 주소 공간의 데이터 구조(프로세스 테이블, 파일 테이블 등)를 접근하게 됨

- 이 작업 중간에 CPU를 선점해가면(preempt) 레이스 컨디션 발생

 

But, 명시적으로 공유하도록 설계한 경우:

- 공유 메모리 (Shared Memory)

- fork() 후 Copy-On-Write (COW)

- 메모리 맵 파일 (mmap)

- IPC 구조 (파이프, 소켓, 메시지큐)

 

프로세스 간에는 주소 공간이 독립적이지만, 커널에 있는 자원은 여러 프로세스가 공유할 수 있다.

때문에 주로 유저 모드보다 커널 모드일 때 레이스 컨디션이 발생한다.

 

두 프로세스는 기본적으로 서로 완전히 분리된 주소공간을 가지며,

명시적으로 공유 설정을 하지 않으면 데이터 공유는 절대 불가능하다.

 

 

OS에서 발생하는 대표적인 레이스 컨디션 종류

1. TOCTOU (Time-of-Check to Time-of-Use)

2. 프로세스 테이블 레이스

3. signal과 시스템 콜 간 경쟁

4. shared memory 또는 memory-mapped file

5. 디바이스 드라이버 레이스

6. fork-exec 사이의 레이스

 

 

2. 레이스 컨디션 공격

 

3. 실제 취약점 CVE

CVE 번호 설명
CVE-2022-0847 Dirty Pipe: Linux 파이프 처리 race → 비루트 사용자도 임의 파일 덮어쓰기
CVE-2007-4573 setuid-root race via /proc 상태값
CVE-2020-8835 BPF에서 커널 heap race를 통한 권한 상승
CVE-2017-1000112 Linux 터널 디바이스 race로 arbitrary memory write



Copyright 2024. GRAVITY all rights reserved