
내가 이해하는 한, 사용자 공간 프로그램은 비특권 모드에서 실행되므로 메모리나 I/O에 직접 액세스할 수 없습니다.
그렇다면 사용자 공간 프로그램에서 /dev/mem을 mmap할 때 정확히 어떻게 메모리나 I/O 위치에 직접 액세스할 수 있습니까?
예를 들어:
int fd = 0;
u8 leds = 0;
fd = open("/dev/mem", O_RDWR|O_SYNC);
leds = (u8 *)mmap(0, getpagesize(), PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0x80840000);
이는 임베디드 장치에서 매우 일반적으로 사용되는 해킹입니다.
이제 이 변수를 leds
사용하여 0x80840000에 존재할 수 있는 모든 장치에 즉시 액세스할 수 있습니다.
우리는 더 이상 해당 주소에 액세스하기 위해 시스템 호출을 사용하지 않을 것입니다.
심지어는
leds[0x20] = val;
작동 할 것이다.
그러나 I/O 주소에서 직접 읽기/쓰기와 같은 특권 작업은 시스템 호출을 통해 프로세서를 특권 모드로 전환해야만 가능해야 합니다.
원천.
답변1
권한이 없는 프로세스 에 대한 액세스를 허용하는 것은 /dev/mem
실제로 보안 문제이므로 허용해서는 안 됩니다.
내 시스템에서는 ls -l /dev/mem
다음과 같습니다.
crw-r----- 1 root kmem 1, 1 Sep 8 10:12 /dev/mem
따라서 root
읽고 쓸 수 있고, 그룹 구성원 kmem
(아무도 없음)은 읽을 수 있지만 쓸 수는 없으며, 다른 모든 사람은 전혀 열 수 없습니다. 그래서 이것은 안전해야 합니다.
당신이 /dev/mem
나와 같은 것이라면, 당신의 권한이 없는 프로세스는 파일은커녕 아예 열 수도 없어야 합니다 mmap
.
/dev/mem
시스템 의 권한이 안전한지 확인하세요 !
답변2
사용자 프로세스(루트로 실행하든 권한이 없는 사용자로 실행하든)에 표시되는 주소는 페이지 테이블을 통해 MMU에 의해 물리적 주소에 매핑되는 가상 주소입니다. 페이지 테이블 설정은 특권 작업이며 커널 코드로만 수행할 수 있습니다. 그러나 페이지 테이블이 설정되면 사용자 모드에서 메모리에 액세스하는 것이 허용됩니다.
구체적으로, 코드는 mmap
주어진 범위의 물리적 메모리에 대한 액세스를 허용하도록 커널이 페이지 테이블을 설정하도록 요청하는 데 사용됩니다. 커널은 프로세스의 권한(에 대한 읽기/쓰기 액세스 권한이 있음 /dev/mem
)을 확인하고 물리적 메모리에 액세스할 수 있도록 페이지 테이블을 설정합니다.
답변3
값은 leds
가상 주소입니다. 현재 프로세스의 사용자 공간에 있는 한 프로세스는 leds[0] = val
이 가상 주소가 RAM의 어느 위치에 매핑되어 있든 특권 모드에 있을 필요 없이 명령을 통해 직접 액세스할 수 있습니다.