Jak działa mmap ' ing / dev / mem, mimo że znajduje się w trybie nieuprzywilejowanym?
On 9 lutego, 2021 by adminO ile wiem, programy przestrzeni użytkownika działają w trybie nieuprzywilejowanym, a zatem nie mają bezpośredniego dostępu do pamięci ani we / wy.
W takim razie, jak dokładnie możemy uzyskać bezpośredni dostęp do pamięci lub lokalizacji we / wy, gdy używamy mmap / dev / mem w programach przestrzeni użytkownika?
Na przykład:
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);
To hack bardzo często używany w urządzeniach wbudowanych.
Teraz zmienna leds
może być używana w locie, aby uzyskać dostęp dowolne urządzenie, które może być obecne pod adresem 0x80840000.
Nie będziemy już używać żadnego wywołania systemowego do uzyskania dostępu do tego adresu.
Nawet coś takiego jak
leds[0x20] = val;
działałoby.
Ale operacje uprzywilejowane, takie jak odczyt / zapis bezpośrednio do / z adresu I / O, powinny być możliwe tylko poprzez przełączenie procesora w tryb uprzywilejowany poprzez wywołanie systemowe.
Źródło .
Komentarze
Odpowiedź
Zezwalanie na dostęp do przez nieuprzywilejowane procesy rzeczywiście stanowiłoby problem z bezpieczeństwem i nie powinno być dozwolone.
W moim systemie ls -l /dev/mem
wygląda następująco:
crw-r----- 1 root kmem 1, 1 Sep 8 10:12 /dev/mem
Więc root
może czytać i zapisywać, członkowie kmem
group (której tak się składa, że nie ma) może go przeczytać, ale nie zapisać, a wszyscy inni w ogóle nie mogą go otworzyć. Więc to powinno być bezpieczne.
Jeśli Twój /dev/mem
jest podobny do mojego, Twój nieuprzywilejowany proces nie powinien w ogóle być w stanie otworzyć pliku, a co dopiero mmap
it.
Sprawdź uprawnienia /dev/mem
w swoim systemie, aby upewnić się, że są bezpieczne!
Komentarze
- Ale zakładając, że robię to jako root … Czy to oznacza, że proces uruchamiany przez roota otrzymuje jądro uprawnienia poziomu?
- Cóż, jeśli ' robisz to jako root, masz dostęp do wszystkiego. Nie jestem ' nie wiem, co masz na myśli przez " uprawnienia dostępu na poziomie jądra ", ale root z pewnością może zrobić wszystko, co zechce, w ten czy inny sposób (w szczególności, na przykład, tworząc i dynamicznie ładując nowy moduł jądra).
- Tak, że ' jest poprawne: kiedy mapujesz plik, później możesz przeczytać & zapisać plik bez użycia jakichkolwiek wywołań stem. To ' jest prawdą niezależnie od tego, czy ' zmapowałeś zwykły plik na dysku, czy specjalne urządzenie, takie jak
/dev/mem
. Jeśli wolisz, możesz otworzyć/dev/mem
i wykonać wywołania systemoweread()
iwrite()
. Wtedy nie wysyłałbyś I / O bez użycia jakichkolwiek wywołań systemowych. Wynik końcowy jest taki sam, ale jeśli masz dużo małych operacji we / wy do zrobienia,mmap()
i dostęp bezpośredni prawdopodobnie będzie działać lepiej, ponieważ nie ' nie potrzeba wywołań systemowych! Dotyczy to również zwykłych plików! - @ Stark07 Myślę, że ' przegapiłeś sedno.
mmap
(i/dev/mem
) same NIE zapewniają bezpośredniego dostępu do pamięci systemowej, a nie jest to możliwe w Ring 4. Zamiast tego po prostu mapuje plik (lub zasób) na określony adres wirtualny w procesie wywoływania, tak jak to się dzieje, gdy program jest ładowany /exec
ed (w tym przypadku obraz programu jestmmap
wprowadzany do pamięci wirtualnej). - TL; DR Nieuprzywilejowany proces nie ma bezpośredniego dostępu do zasobów systemowych, ale może to zrobić, gdy zasób ten jest zmapowany do ich wirtualnej przestrzeni adresowej . Nie ' nie ma różnicy między dostępem do stosu / sterty / rodata / cokolwiek a dostępem do pamięci jądra – w końcu oba uzyskują dostęp do rzeczywistej pamięci fizycznej, podczas gdy ten drugi przypadek znajduje się pod program ' s.
Odpowiedź
Adresy widoczne do procesu użytkownika (niezależnie od tego, czy działa jako root, czy nieuprzywilejowany użytkownik) to adresy wirtualne, które są mapowane na adresy fizyczne przez MMU za pośrednictwem tabel stron. Konfigurowanie tabel stron jest operacją uprzywilejowaną i może być wykonywane tylko przez kod jądra; jednak po ustawieniu tablic stron dostęp do pamięci jest dozwolony w trybie użytkownika.
Konkretnie, twój kod używa mmap
do zażądania, aby jądro skonfigurowało tabele stron, aby umożliwić dostęp do określonego zakresu pamięci fizycznej. Jądro sprawdza uprawnienia procesu (ma dostęp do odczytu / zapisu do /dev/mem
) i ustawia tablice stron, aby umożliwić mu dostęp do pamięci fizycznej.
Odpowiedź
Wartość leds
to adres wirtualny. Dopóki znajduje się w przestrzeni użytkownika bieżącego procesu proces może uzyskać do niego bezpośredni dostęp za pomocą instrukcji, takich jak leds[0] = val
, bez konieczności przebywania w trybie uprzywilejowanym, bez względu na to, gdzie w pamięci RAM ten wirtualny adres jest mapowany
*
w deklaracji , ale to ' to tylko kod, nie ma dowodów na to, że faktycznie działa on jako użytkownik nieuprzywilejowany; z mojego (ograniczonego) doświadczenia wynika, że wszystko działa jako root urządzenia wbudowane.root
ma wiele przywilejów, w tym możliwość zastąpienia tradycyjnych uprawnienia systemu plików. Niektóre " pliki " w rzeczywistości zapewniają dostęp do urządzeń (takich jak dysk lub pamięć), które są niedostępne dla zwykłych użytkowników. Nieroot
. Aleroot
działa w przestrzeni użytkownika , więc nie ' nie korzysta z pełnych uprawnień trybu systemowego (głównie wykonywanie uprzywilejowanych instrukcji).