Wie funktioniert mmap'ing /dev/mem trotz des nicht privilegierten Modus?

Wie funktioniert mmap'ing /dev/mem trotz des nicht privilegierten Modus?

Soweit ich es verstehe, werden User-Space-Programme im nicht privilegierten Modus ausgeführt und haben daher keinen direkten Zugriff auf den Speicher oder die E/A.

Wie genau können wir dann direkt auf den Speicher oder die E/A-Speicherorte zugreifen, wenn wir in Benutzerbereichsprogrammen /dev/mem mmap verwenden?

Zum Beispiel:

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);

Dies ist ein Hack, der in eingebetteten Geräten sehr häufig verwendet wird.

Jetzt kann die Variable ledsspontan verwendet werden, um auf jedes Gerät zuzugreifen, das bei 0x80840000 vorhanden sein könnte.

Wir werden keinen Systemaufruf mehr verwenden, um auf diese Adresse zuzugreifen.

Sogar so etwas wie

leds[0x20] = val;

würde funktionieren.

Privilegierte Vorgänge wie das direkte Lesen/Schreiben von/zu einer E/A-Adresse sollten jedoch nur möglich sein, indem der Prozessor durch einen Systemaufruf in den privilegierten Modus versetzt wird.

Quelle.

Antwort1

Den Zugriff /dev/memnicht privilegierter Prozesse zuzulassen, wäre tatsächlich ein Sicherheitsproblem und sollte nicht zugelassen werden.

Auf meinem System ls -l /dev/memsieht es folgendermaßen aus:

crw-r----- 1 root kmem 1, 1 Sep  8 10:12 /dev/mem

Sie können es also rootlesen und schreiben, Mitglieder der kmemGruppe (von denen es zufällig keine gibt) können es lesen, aber nicht schreiben, und alle anderen können es überhaupt nicht öffnen. Das sollte also sicher sein.

Wenn es bei Ihnen /dev/memähnlich ist wie bei mir, sollte Ihr nicht privilegierter Prozess nicht einmal in der Lage sein, die Datei überhaupt zu öffnen, geschweige denn, mmapsie auszuführen.

Überprüfen Sie die Berechtigungen /dev/memauf Ihrem System, um sicherzustellen, dass sie sicher sind!

Antwort2

Die für einen Benutzerprozess sichtbaren Adressen (egal, ob er als Root oder als unprivilegierter Benutzer ausgeführt wird) sind virtuelle Adressen, die von der MMU über die Seitentabellen physischen Adressen zugeordnet werden. Das Einrichten der Seitentabellen ist eine privilegierte Operation und kann nur durch Kernelcode ausgeführt werden. Sobald die Seitentabellen jedoch eingerichtet sind, ist der Zugriff auf den Speicher im Benutzermodus zulässig.

Konkret fordert Ihr Code mmapden Kernel auf, die Seitentabellen so einzurichten, dass auf einen bestimmten Bereich des physischen Speichers zugegriffen werden kann. Der Kernel überprüft die Berechtigungen des Prozesses (er hat Lese-/Schreibzugriff auf /dev/mem) und richtet die Seitentabellen so ein, dass auf den physischen Speicher zugegriffen werden kann.

Antwort3

Der Wert von ledsist eine virtuelle Adresse. Solange sie sich im Benutzerbereich des aktuellen Prozesses befindet, kann der Prozess direkt über Anweisungen wie darauf zugreifen, leds[0] = valohne sich im privilegierten Modus befinden zu müssen, unabhängig davon, wo im RAM diese virtuelle Adresse abgebildet ist.

verwandte Informationen