W jaki sposób jądro uniemożliwia szkodliwemu programowi odczytanie całej fizycznej pamięci RAM?

10

Jeśli napiszę program, który próbuje odczytać pamięć pod każdym możliwym adresem i uruchomię go na „pełnym” Uniksie, nie będzie on mógł uzyskać dostępu do całej fizycznej pamięci RAM. Ale w jaki sposób system operacyjny temu temu zapobiega?

Bardziej zaznajomiłem się z małymi architekturami procesorów, w których dowolny element kodu asemblera może uzyskać dostęp do wszystkiego. Nie rozumiem, w jaki sposób program (jądro) może wykrywać takie złośliwe operacje.

nowox
źródło
2
Zazwyczaj MMU dba o to, abyś nie mógł uzyskać dostępu do pamięci poza dozwolonymi obszarami.
ott--
1
MMU jest konfigurowany przez zespół. W ten sposób kod zestawu może zmienić konfigurację MMU i uzyskać dostęp do innej strony pamięci, prawda?
nowox
Jest to prawdą tylko wtedy, gdy uruchomisz kod jako root.
ott--
2
Powinieneś przeczytać o tabelach stron i abstrakcji jądra.
Clarus
@ott: nawet root nie może modyfikować MMU (przynajmniej nie w Linuksie). Tylko jądro działa.
Basile Starynkevitch,

Odpowiedzi:

12

To nie jądro uniemożliwia zły dostęp do pamięci, to procesor. Rola jądra polega jedynie na prawidłowym skonfigurowaniu procesora.

Dokładniej, komponent sprzętowy, który zapobiega złemu dostępowi do pamięci, to MMU . Gdy program uzyskuje dostęp do adresu pamięci, adres jest dekodowany przez CPU na podstawie zawartości MMU. MMU ustanawia tłumaczenie z adresów wirtualnych na adresy fizyczne: gdy CPU ładuje lub przechowuje pod pewnym adresem wirtualnym, oblicza odpowiedni adres fizyczny na podstawie zawartości MMU. Jądro ustawia konfigurację MMU w taki sposób, że każdy program może uzyskać dostęp tylko do pamięci, do której jest uprawniony. Rejestry pamięci i sprzętu innych programów w ogóle nie są mapowane w pamięci programu: te adresy fizyczne nie mają odpowiadającego adresu wirtualnego w konfiguracji MMU dla tego programu.

Podczas przełączania kontekstu między różnymi procesami jądro modyfikuje konfigurację MMU, tak aby zawierała pożądane tłumaczenie dla nowego procesu.

Niektóre adresy wirtualne w ogóle nie są mapowane, tj. MMU tłumaczy je na specjalną wartość „brak takiego adresu”. Gdy procesor wyreżyseruje niezapisany adres, powoduje to pułapkę: procesor rozgałęzia się do wstępnie zdefiniowanej lokalizacji w kodzie jądra. Niektóre pułapki są uzasadnione; na przykład adres wirtualny może odpowiadać stronie znajdującej się w przestrzeni wymiany , w którym to przypadku kod jądra załaduje zawartość strony z wymiany, a następnie przełączy się z powrotem do oryginalnego programu w taki sposób, że instrukcja dostępu do pamięci zostanie ponownie wykonana. Inne pułapki są nieuzasadnione, w którym to przypadku proces odbiera sygnał, który domyślnie zabija program natychmiast (a jeśli nie, to rozgałęzia się do procedury obsługi sygnału w programie: w każdym razie instrukcja dostępu do pamięci nie jest zakończona).

Gilles „SO- przestań być zły”
źródło
Czy mógłbyś podać nieco stwierdzenie „adres jest dekodowany przez CPU na podstawie zawartości MMU” ? Czy w uruchomionym programie jest kod, który dekoduje adresy? Lub kiedy procesor uzyskuje dostęp do adresu - dostęp jest realizowany do MMU, który tłumaczy / obsługuje go poprawnie (uzyskuje dostęp do pamięci lub pamięci podręcznej i zwraca wynik lub uruchamia procedurę jądra)? Z punktu widzenia mikrokontrolera / montażu MMU to nowa część. Procesor nie jest podłączony bezpośrednio do pamięci, jest podłączony do MMU i tam odbywa się abstrakcja pamięci wirtualnej.
xealits
3
@xealits Tłumaczenie z adresu wirtualnego na adres fizyczny odbywa się w MMU, który jest obwodem sprzętowym. Nie ma takiego kodu w programie ani w jądrze. Jądro jest wywoływane tylko w wyjątkowych przypadkach, gdy program próbuje uzyskać dostęp do adresu wirtualnego, dla którego wpis MMU mówi „niepoprawny adres”. Jądro wykonuje również konfigurację rejestrów i tabel w pamięci RAM używanych przez MMU.
Gilles „SO- przestań być zły”