![사용자 모드 프로그램이 커널 공간 메모리에 액세스하고 IN 및 OUT 명령어를 실행하도록 허용하면 CPU 모드의 목적이 무효화됩니까?](https://linux55.com/image/149666/%EC%82%AC%EC%9A%A9%EC%9E%90%20%EB%AA%A8%EB%93%9C%20%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%A8%EC%9D%B4%20%EC%BB%A4%EB%84%90%20%EA%B3%B5%EA%B0%84%20%EB%A9%94%EB%AA%A8%EB%A6%AC%EC%97%90%20%EC%95%A1%EC%84%B8%EC%8A%A4%ED%95%98%EA%B3%A0%20IN%20%EB%B0%8F%20OUT%20%EB%AA%85%EB%A0%B9%EC%96%B4%EB%A5%BC%20%EC%8B%A4%ED%96%89%ED%95%98%EB%8F%84%EB%A1%9D%20%ED%97%88%EC%9A%A9%ED%95%98%EB%A9%B4%20CPU%20%EB%AA%A8%EB%93%9C%EC%9D%98%20%EB%AA%A9%EC%A0%81%EC%9D%B4%20%EB%AC%B4%ED%9A%A8%ED%99%94%EB%90%A9%EB%8B%88%EA%B9%8C%3F.png)
CPU가 사용자 모드에 있으면 CPU는 권한 있는 명령을 실행할 수 없으며 커널 공간 메모리에 액세스할 수 없습니다.
그리고 CPU가 커널 모드에 있을 때 CPU는 모든 명령을 실행할 수 있고 모든 메모리에 액세스할 수 있습니다.
이제 Linux에서 사용자 모드 프로그램은 모든 메모리에 액세스할 수 있으며( 사용하여 ) 권한 있는 명령 과 및 ( 사용하는 것 같습니다)을 /dev/mem
모두 실행할 수 있습니다 .IN
OUT
iopl()
따라서 Linux의 사용자 모드 프로그램은 커널 모드가 할 수 있는 대부분의 작업을 수행할 수 있습니다(제가 생각하는 대부분의 작업).
사용자 모드 프로그램이 이러한 모든 기능을 갖도록 허용하면 CPU 모드를 갖는 목적이 무효화됩니까?
답변1
따라서 Linux의 사용자 모드 프로그램은 커널 모드가 할 수 있는 대부분의 작업을 수행할 수 있습니다(제가 생각하는 대부분의 작업).
글쎄, 모든 사용자 모드 프로그램이 가능한 것은 아니며 적절한 권한이 있는 프로그램만 가능합니다. 이는 커널에 의해 결정됩니다.
/dev/mem
일반적인 파일 시스템 액세스 권한 및 CAP_SYS_RAWIO
기능으로 보호됩니다. iopl()
또한 ioperm()
동일한 능력에 의해 제한됩니다.
/dev/mem
또한 커널( CONFIG_DEVMEM
)에서 완전히 컴파일될 수도 있습니다.
사용자 모드 프로그램이 이러한 모든 기능을 갖도록 허용하면 CPU 모드를 갖는 목적이 무효화됩니까?
아마도. 이는 권한 있는 사용자 공간 프로세스에서 수행할 수 있는 작업에 따라 다릅니다. 사용자 공간 프로세스는 /dev/sda
액세스 권한(또는 이에 상응하는 권한)이 있는 경우 전체 하드 드라이브를 손상시킬 수도 있습니다. 이는 스토리지 액세스를 처리하는 파일 시스템 드라이버의 목적을 상실하더라도 마찬가지입니다.
iopl()
( i386에서 CPU의 특권 모드를 활용하여 작동한다는 사실도 있으므로 그들의 목적을 무너뜨린다고 말할 수는 없습니다.)
답변2
modprobe
커널에 새 코드를 로드하여 보안을 "파괴"하는 것과 같은 방식입니다.
여러 가지 이유로 때로는 반특권 코드(예: X 서버 내의 그래픽 드라이버)를 커널 스레드가 아닌 사용자 공간에서 실행하는 것이 더 합리적입니다.
kill
하드웨어가 잠겨 있지 않으면 구현하기가 더 쉽습니다 .- 파일 시스템의 파일에서 코드/데이터의 페이징을 요청하도록 합니다. (커널 메모리는 페이징할 수 없습니다)
- 자체 가상 주소 공간을 제공합니다. X 서버에 버그가 있습니다.가능한커널을 종료하지 않고 X 서버를 충돌시키기만 하면 됩니다.
보안에는 큰 도움이 되지 않지만 안정성과 소프트웨어 아키텍처 측면에서 큰 이점이 있습니다.
그래픽 드라이버를 커널에 굽으면 X 클라이언트와 서버 사이의 컨텍스트 전환이 줄어들 수 있습니다. 서버는 역사적으로 너무 크고 완전히 코어로 갔으면 좋겠다는 오류가 너무 많았습니다.
예, 이러한 권한을 가진 악성 코드입니다할 수 있다필요한 경우 커널을 인수하고 /dev/mem
커널 코드를 수정할 수 있습니다.
또는 예를 들어 x86에서 시스템 호출을 수행하여 IO 권한 수준을 Ring 0 으로 설정한 후 cli
해당 코어에서 인터럽트를 비활성화하는 명령을 실행합니다.iopl
그러나 x86 iopl
"만"이 특정 명령어에 대한 액세스를 허용 하더라도: 입력/출력(및 문자열 버전 입력/출력) 및 cli/sti. "모델별 레지스터"(예: x86-64 명령어에 대한 커널 진입점 주소 설정 )를 사용 rdmsr
하거나 읽거나 쓰는 것을 허용하지 않으며 , 인터럽트 설명자 테이블을 교체하는 것도 허용하지 않습니다. 기존 커널이 있는 머신, 적어도 해당 커널에서는).wrmsr
IA32_LSTAR
syscall
lidt
제어 레지스터(예: 공격 프로세스가 more 를 사용하는 대신 /dev/mem
자체 페이지 테이블을 수정하기 위한 오프셋으로 유용할 수 있는 최상위 페이지 디렉토리의 물리적 주소를 보유하는 CR3)도 읽을 수 없습니다 . )mmap
/dev/mem
invd
(모든 캐시를 무효화아니요다시 쓰기! ! (예= RAM 구성 전 초기 BIOS))는 또 다른 흥미로운 점으로, IOPL뿐만 아니라 항상 전체 CPL 0(현재 권한 수준)이 필요합니다. 심지어wbinvd
매우 느리고 중단할 수 없으며 플러시해야 하기 때문에 특권이 있습니다.모두모든 코어에 걸쳐 캐시합니다. (바라보다프로그램과 관련된 전체 CPU 캐시를 플러시하는 방법이 있습니까?그리고WBINVD 명령어 사용법)
코드로 실행되는 데이터의 잘못된 주소로 점프하는 버그로 인해 사용자 공간 X 서버에서 이러한 명령을 실수로 실행할 수 없습니다.
현재 권한 수준(보호 모드 및 장기 모드)cs
(코드 조각 선택기)의 하위 2비트입니다.. mov eax, cs
/ and eax, 3
모든 모드에서 읽기 권한 수준.
권한 수준을 작성하려면 jmp far
또는 call far
설정을 수행 할 수 있습니다 CS:RIP
(그러나 대상 세그먼트의 GDT/LDT 항목은 이전 권한 수준을 기반으로 이를 제한할 수 있으므로 사용자 공간이 스스로 상승하기 위해 이를 수행할 수 없습니다). 또는 커널 진입점에서 링 0으로 전환하거나 int
를 사용할 수 있습니다 .syscall