Die Implementierung von 03
ist stark von der Architektur abhängig.
Auf x86 und x86-64 liest es einfach direkt von der Userspace-Adresse und schreibt in die Kernelspace-Adresse, während SMAP (Supervisor Mode Access Prevention) vorübergehend deaktiviert wird, falls es konfiguriert ist. Der knifflige Teil daran ist, dass die 12
Der Code wird in einem speziellen Bereich platziert, sodass der Page-Fault-Handler erkennen kann, wenn darin ein Fehler auftritt. Ein Speicherschutzfehler, der in 20
auftritt beendet den Prozess nicht, wie es der Fall wäre, wenn er durch einen anderen Prozesskontextcode ausgelöst wird, oder versetzt den Kernel nicht in Panik, wie dies bei einem Interruptkontext der Fall wäre - es setzt einfach die Ausführung in einem Codepfad fort, der 34
bezüglich "wie wäre es mit copy_to_user, da der Kernel die Kernel-Space-Adresse weitergibt, wie kann ein User-Space-Prozess darauf zugreifen"
Ein Benutzerbereichsprozess kann versuchen, auf jede Adresse zuzugreifen. Wenn die Adresse jedoch nicht in diesem Prozess-Benutzerbereich abgebildet ist (d. h. in den Seitentabellen dieses Prozesses) oder wenn es ein Problem mit dem Zugriff gibt, wie z. B. einen Schreibversuch auf einen Nur-Lese-Speicherort, dann wird ein Seitenfehler erzeugt. Beachten Sie, dass zumindest auf x86 jeder Prozess den gesamten Kernel-Speicherplatz im untersten 1 Gigabyte des virtuellen Adressraums dieses Prozesses abgebildet hat, während die 3 oberen Gigabyte des 4 GB Gesamtadressraums (ich verwende hier die 32-Bit-Classic Fall) werden für den Prozesstext (d. h. Code) und Daten verwendet. Eine Kopie zum oder vom Benutzerbereich wird vom Kernelcode ausgeführt, der im Namen des Prozesses ausgeführt wird, und tatsächlich ist es die Speicherzuordnung (d. h. Seitentabellen) dieses Prozesses die während des Kopierens verwendet werden. Dies findet statt, während die Ausführung im Kernelmodus ist – d. h. privilegierter/Supervisor-Modus in x86-Sprache. Angenommen, der User-Space-Code hat einen legitimen Zielspeicherort (d. h. eine Adresse, die ordnungsgemäß in diesem Adressraum des Prozesses abgebildet ist) passiert, an den Daten kopiert werden sollen, copy_to_user , aus dem Kernel-Kontext ausgeführt, in der Lage wäre, normalerweise ohne Probleme an diese Adresse/Region zu schreiben, und nachdem die Kontrolle an den Benutzer zurückgegeben wurde, kann der Benutzerbereich auch von diesem Speicherort lesen, der vom Prozess selbst eingerichtet wurde, um damit zu beginnen. Weitere interessante Details können finden Sie in den Kapiteln 9 und 10 von Understanding the Linux Kernel, 3rd Edition, By Daniel P. Bovet, Marco Cesati. Insbesondere access_ok() ist eine notwendige, aber nicht hinreichende Gültigkeitsprüfung. Der Benutzer kann weiterhin Adressen übergeben, die nicht zum Adressraum des Prozesses gehören. In diesem Fall tritt eine Page Fault-Ausnahme auf, während der Kernelcode die Kopie ausführt. Der interessanteste Teil ist, wie der Kernel-Page-Fault-Handler feststellt, dass der Seitenfehler in einem solchen Fall nicht auf einen Fehler im Kernel-Code, sondern auf eine fehlerhafte Adresse des Benutzers zurückzuführen ist (insbesondere, wenn der fragliche Kernel-Code von einem Kernel-Modul stammt). geladen).