사용자 모드 프로그램이 커널 공간 메모리에 액세스하고 IN 및 OUT 명령을 실행하도록 허용하지 않으면 CPU 모드를 사용하려는 목적을 상실합니까?


19

CPU가 사용자 모드 인 경우 CPU는 권한있는 명령을 실행할 수 없으며 커널 공간 메모리에 액세스 할 수 없습니다.

CPU가 커널 모드 인 경우 CPU는 모든 명령을 실행하고 모든 메모리에 액세스 할 수 있습니다.

이제 Linux에서 사용자 모드 프로그램은 모든 메모리에 액세스 할 수 있으며 (을 사용하여 /dev/mem) 두 가지 권한있는 명령 INOUT( iopl()내 생각에 사용 )을 실행할 수 있습니다 .

따라서 Linux의 사용자 모드 프로그램은 커널 모드에서 수행 할 수있는 대부분의 작업을 수행 할 수 있습니다.

사용자 모드 프로그램이이 모든 힘을 갖도록 허용하지 않으면 CPU 모드를 사용한다는 목적에 위배됩니까?

답변:


23

따라서 Linux의 사용자 모드 프로그램은 커널 모드에서 수행 할 수있는 대부분의 작업을 수행 할 수 있습니다.

모든 사용자 모드 프로그램이 아니라 적절한 권한을 가진 프로그램 만 가능합니다. 그리고 그것은 커널에 의해 결정됩니다.

/dev/mem일반적인 파일 시스템 액세스 권한 및 CAP_SYS_RAWIO기능 으로 보호됩니다 . iopl()ioperm()같은 기능을 통해 제한됩니다.

/dev/mem커널에서 모두 컴파일 할 수도 있습니다 ( CONFIG_DEVMEM).

사용자 모드 프로그램이이 모든 힘을 갖도록 허용하지 않으면 CPU 모드를 사용한다는 목적에 위배됩니까?

아마도 요 권한있는 사용자 공간 프로세스가 수행 할 수있는 작업에 따라 다릅니다. 사용자 공간 프로세스는 /dev/sda스토리지 액세스를 처리하기 위해 파일 시스템 드라이버를 갖는 목적을 상실하더라도 하드 드라이브 전체에 액세스 할 수있는 경우 전체 하드 드라이브 를 폐기 할 수 있습니다.

(따라서 iopl()i386의 CPU 권한 모드를 사용하여 작동 한다는 사실도 있기 때문에 목적을 어기는 것으로 말할 수는 없습니다.)


2
심지어 iopl허용하지 않습니다 모든 아직 확실 실수로 실행되지 않는 버그가 사용자 공간 프로그램을 만들기위한 유용한 그래서, 특권 명령을 invd실행 메모리에 점으로 시작하는 손상된 함수 포인터를 통해 점프에 의해 0F 08바이트. 사용자 공간 프로세스가 권한을 높이는 것이 유용한 비보안 이유에 대한 답변을 추가했습니다.
Peter Cordes

16

modprobe새 코드를 커널에로드하여 보안 을 "파괴" 하는 것과 동일한 방식으로 만 사용 하십시오.

여러 가지 이유로 때로는 커널 스레드가 아닌 사용자 공간에서 실행되는 세미 권한있는 코드 (예 : X 서버의 그래픽 드라이버)가 더 적합합니다.

  • killHW를 잠그지 않는 한 더 쉽게 할 수 있습니다.
  • 파일 시스템의 파일에서 코드 / 데이터를 요구 페이지로 만듭니다. (커널 메모리는 페이징 할 수 없습니다)
  • X 서버의 버그 가 커널을 중단시키지 않고 X 서버와 충돌 할 수 있는 자체 가상 주소 공간을 제공 합니다.

보안에는 그다지 도움이되지 않지만 안정성과 소프트웨어 아키텍처의 장점이 있습니다.

그래픽 드라이버를 커널에 베이킹하면 다른 사용 공간 프로세스로 데이터를 가져 오는 대신 한 명의 사용자-> 커널-> 사용자와 같이 X 클라이언트와 X 서버 간의 컨텍스트 전환이 줄어들 수 있지만 X 서버는 역사적으로 너무 크고 버그가 있습니다. 커널에서 완전히 사용하기를 원합니다.


예,이 privs 및와 악성 코드 는 원한다면 사용하여 커널을 인수 /dev/mem커널 코드를 수정할 수 있습니다.

또는 예를 들어 x86 cli에서는 iopl시스템 호출을 통해 IO 권한 수준을 링 0으로 설정 한 후 해당 코어에서 인터럽트를 비활성화 하는 명령을 실행하십시오 .

그러나 x86 iopl"only" 조차도 in / out (및 문자열 버전 ins / outs) 및 cli / sti와 같은 일부 명령에 액세스 할 수 있습니다 . "모델 특정 레지스터"(예 : x86-64 명령어 의 커널 진입 점 주소 설정) 를 사용 rdmsr하거나 wrmsr읽거나 쓰거나 인터럽트 디스크립터 테이블을 대체 할 수 없습니다 ( 기존 커널의 머신 이상 (적어도 해당 코어에 있음)IA32_LSTARsyscalllidt

제어 레지스터 (예 : 최상위 페이지 디렉토리의 물리적 주소를 보유하는 CR3)도 읽을 수 없으며, 공격 프로세스는 /dev/mem을 ( mmap를) 대체하는 대신 자체 페이지 테이블을 수정하기 위한 오프셋으로 유용 할 수 있습니다 /dev/mem. )

invd( Write-back 없이 모든 캐시 무효화하십시오 ! ( 사용 사례 = 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 항목은 이전 특권 레벨을 기반으로이를 제한 할 수 있으므로 사용자 공간이이를 높이기 위해이를 수행 할 수없는 이유). 또는 당신은 사용 int또는 syscall커널 진입 점에서 링 0으로 전환 할 수 있습니다.


사실, 나는 그것이 인텔 팔레스의 코드 "선택기"라는 것을 확신합니다. 8086/8088의 세그먼트, 아마도 80186의 세그먼트 였지만 80286에 의해 선택기로 불 렸으며 이후 공식적으로 그 용어가 바뀌지 않았다고 생각합니다.
CVn
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.