Wie funktioniert mmap ' ing / dev / mem, obwohl es sich im nicht privilegierten Modus befindet?
On Februar 9, 2021 by adminNach meinem Verständnis werden User Space-Programme im nicht privilegierten Modus ausgeführt und haben daher keinen direkten Zugriff auf Speicher oder E / A.
Wie genau können wir dann direkt auf Speicher oder E / A-Speicherorte zugreifen, wenn wir / dev / mem in User Space-Programmen mmap?
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 sehr häufig in eingebetteten Geräten verwendet wird.
Jetzt kann die Variable leds
im laufenden Betrieb verwendet werden, um darauf zuzugreifen Jedes Gerät, das unter 0x80840000 vorhanden sein könnte.
Wir verwenden keinen Systemaufruf mehr, um auf diese Adresse zuzugreifen.
Sogar so etwas wie
leds[0x20] = val;
würde funktionieren.
Privilegierte Vorgänge wie das direkte Lesen / Schreiben in / von einer E / A-Adresse sollten jedoch nur möglich sein, wenn der Prozessor durch einen Systemaufruf in den privilegierten Modus versetzt wird.
Quelle .
Kommentare
- Zeigen Sie ein Beispiel, wo dies geschieht als nicht privilegierter Benutzer?
- Ich denke, Sie ' vermissen eine
*
in der Deklaration vonleds
, aber das ' ist nur Code, kein Beweis dafür, dass dies tatsächlich als nicht privilegierter Benutzer funktioniert. Nach meiner (begrenzten) Erfahrung läuft alles als root auf eingebettete Geräte. - @wurtel – meine schlechte, möglicherweise ' Kopie schlecht eingefügt … Ja, alles funktioniert als root, aber meine Frage geht an das Herzstück des Betriebssystems Wenn Sie Root sind, erhalten Sie genauso viele Berechtigungen wie der Kernel selbst?
- Der Benutzer
root
verfügt über viele Berechtigungen, einschließlich der Berechtigung, herkömmliche Berechtigungen zu überschreiben Dateisystemberechtigungen. Einige " -Dateien " haben wirklich Zugriff auf Geräte (wie Festplatte oder Speicher), die für normale Benutzer nicht zulässig sind. Nichtroot
.root
wird jedoch im Userspace ausgeführt, sodass ' nicht die vollen Berechtigungen des Systemmodus genießt (meistens privilegierte Anweisungen ausführen).
Antwort
Ermöglicht den Zugriff auf /dev/mem
durch nicht privilegierte Prozesse wäre in der Tat ein Sicherheitsproblem und sollte nicht zugelassen werden.
Auf meinem System sieht ls -l /dev/mem
folgendermaßen aus:
crw-r----- 1 root kmem 1, 1 Sep 8 10:12 /dev/mem
root
kann es also lesen und schreiben, Mitglieder der kmem
group (von denen es zufällig keine gibt) kann es lesen, aber nicht schreiben, und alle anderen können es überhaupt nicht öffnen. Dies sollte also sicher sein.
Wenn Ihre /dev/mem
so etwas wie meine ist, sollte Ihr nicht privilegierter Prozess die Datei überhaupt nicht öffnen können, geschweige denn mmap
it.
Überprüfen Sie die Berechtigungen von /dev/mem
auf Ihrem System, um sicherzustellen, dass sie sicher sind!
Kommentare
- Unter der Annahme, dass ich dies als root tue, bedeutet dies, dass ein von root ausgeführter Prozess den Kernel erhält Zugriffsrechte auf Ebene?
- Wenn Sie ' dies als root tun, haben Sie Zugriff auf alles. Ich ' bin mir nicht sicher, was Sie unter " Zugriffsberechtigungen auf Kernelebene " verstehen, aber root kann auf die eine oder andere Weise alles tun, was es will (insbesondere durch Erstellen und dynamisches Laden eines neuen Kernelmoduls).
- Ja, das ' s korrekt: Wenn Sie eine Datei zuordnen, können Sie anschließend & lesen und die Datei ohne Verwendung von Stammaufrufen schreiben. Das ' ist wahr, ob Sie ' eine reguläre Datenträgerdatei oder ein spezielles Gerät wie
/dev/mem
. Wenn Sie möchten, können Sie/dev/mem
öffnen undread()
undwrite()
Systemaufrufe ausgeben. Dann würden Sie keine E / A ohne die Verwendung von Systemaufrufen senden. Das Endergebnis ist das gleiche, aber wenn Sie viele kleine E / A-Vorgänge ausführen müssen, sindmmap()
und der direkte Zugriff wahrscheinlich besser, da Sie nicht ' brauche keine Systemaufrufe! Dies gilt auch für reguläre Dateien! - @ Stark07 Ich denke, Sie ' haben den Punkt verpasst. Die
mmap
(und/dev/mem
) selbst bietet NICHT direkten Zugriff auf die Systemspeicher, und dies ist in Ring 4 nicht möglich. Stattdessen wird lediglich eine Datei (oder Ressource) einer bestimmten virtuellen Adresse im aufrufenden Prozess zugeordnet, genau wie beim Laden eines Programms /exec
ed (in diesem Fall wird das Programmabbildmmap
in den virtuellen Speicher übertragen). - TL; DR Ein nicht privilegierter Prozess hat keinen direkten Zugriff auf die Systemressource, kann dies jedoch , wenn diese Ressource ihrem virtuellen Adressraum zugeordnet ist . ' gibt es keinen Unterschied zwischen dem Zugriff auf seinen Stack / Heap / Rodata / und dem Zugriff auf den Kernel-Speicher. Beide greifen schließlich auf den tatsächlichen physischen Speicher zu, während sich der letztere Fall zufällig unter dem befindet Programm ' s Steuerung.
Antwort
Die sichtbaren Adressen Zu einem Benutzerprozess (unabhängig davon, ob er als Root- oder als nicht privilegierter Benutzer ausgeführt wird) gehören virtuelle Adressen, die von der MMU über die Seitentabellen physischen Adressen zugeordnet werden. Das Einrichten der Seitentabellen ist eine privilegierte Operation und kann nur von Kernel-Code ausgeführt werden. Sobald die Seitentabellen festgelegt sind, ist der Zugriff auf den Speicher im Benutzermodus zulässig.
Konkret verwendet Ihr Code mmap
, um den Kernel aufzufordern, die einzurichten Seitentabellen, um den Zugriff auf einen bestimmten Bereich des physischen Speichers zu ermöglichen. Der Kernel überprüft die Berechtigungen des Prozesses (er hat Lese- / Schreibzugriff auf /dev/mem
) und richtet die Seitentabellen ein, damit er auf den physischen Speicher zugreifen kann.
Antwort
Der Wert von leds
ist eine virtuelle Adresse. Solange sie sich im Benutzerbereich befindet Der Prozess des aktuellen Prozesses kann direkt über Anweisungen wie leds[0] = val
darauf zugreifen, ohne sich im privilegierten Modus befinden zu müssen, unabhängig davon, wo im RAM diese virtuelle Adresse
zugeordnet ist
Schreibe einen Kommentar