Wie kann ich vom Linux-Kernel auf Benutzerspeicher zugreifen?

8

Ich weiß, dass copy_to_user / copy_from_user , get_user / put_user Funktionen für diesen Zweck sind.

Meine Frage ist, wie kann ich bei einer User Space Adresse / Zeiger auf die Daten zugreifen, auf die die Adresse vom Kernel im Allgemeinen zeigt?

Ich kann mir vorstellen, dass ich zuerst sicherstellen muss, dass die enthaltende Seite sich im physischen Speicher befindet (anstatt auf der Festplatte).

Was ist der nächste Schritt? Kann ich *p verwenden, wobei p der Zeiger ist, der auf einige Benutzerraumdaten verweist, um direkt auf die Daten zu verweisen?

Oder muss ich zuerst kmap aufrufen, um den enthaltenden physischen Seitenrahmen dem virtuellen Adressraum des Kernels zuzuordnen? Warum?

    
Infinite 09.05.2012, 04:27
quelle

4 Antworten

4

Der Zeiger allein ist nicht genug! Sie müssen wissen, zu welchem ​​Prozess dieser Zeiger "gehört".

Wenn der Prozess beendet wird, zeigt der Zeiger in den Adressraum eines anderen Prozesses. Die Adresse darf nicht mehr zugeordnet werden, yadda yadda,

Wenn dieser Prozess beim Zugriff auf die Daten der aktuelle Prozess ist, sollten Sie die Funktionen copy_to_user / copy_from_user verwenden.

Wenn der Prozess geplant werden kann, können Sie versuchen, die Seite im RAM zu mock () und herauszufinden, welche physische RAM-Adresse der Seite ist. Wann immer Sie darauf zugreifen möchten, ordnen Sie diese physische Seite einer virtuellen Kernel-Adresse zu.

HINWEIS:

  • Ein böswilliger Prozess kann die Seite munlock () und Sie dazu bringen, auf eine falsche RAM-Seite zuzugreifen.
  • Ich bin mir nicht sicher, ob die semantische mlock () -Spezifikation verlangt, dass die unterstreichende RAM-Seite sich NICHT ändern darf.
  • Der Kernel sollte in der Lage sein, eine Seite in den Arbeitsspeicher zu sperren, ich kenne das mm-Subsystem nicht.
Lucian Adrian Grijincu 09.05.2012 08:17
quelle
3

Unterschiedliche Benutzerraumanwendung hat unterschiedliche Seitentabelle. 1) Sie müssen User-Space-Programm pid bekommen. 2) suche addresse in der Seitentabelle der pid.

Im Folgenden finden Sie einen Beispielcode, um virtuelle Adressen von Benutzerbereichen in physische Adressen zu übersetzen. Es funktioniert auf x86-Plattform.

%Vor%     
richliu 09.05.2012 16:15
quelle
3

Vielleicht finden Sie das nützlich.

  

Wiederholen wir, dass das Buff-Argument für die Lese- und Schreibmethoden ist   ein Benutzerraumzeiger. Daher kann es nicht direkt dereferenziert werden   Kernel-Code. Für diese Einschränkung gibt es einige Gründe:

     
  • Je nachdem, auf welcher Architektur Ihr Treiber ausgeführt wird und wie   Kernel wurde konfiguriert, der Zeiger für den Benutzer-Space ist möglicherweise nicht gültig   läuft im Kernel-Modus überhaupt. Möglicherweise gibt es dafür keine Zuordnung   Adresse, oder es könnte auf einige andere, zufällige Daten zeigen.

  •   
  • Auch wenn der Zeiger im Kernel-Bereich dasselbe bedeutet,   User-Space-Speicher wird ausgelagert, und der fragliche Speicher ist möglicherweise nicht   resident im RAM, wenn der Systemaufruf erfolgt. Versuch zu referenzieren   Der User-Space-Speicher könnte direkt einen Seitenfehler erzeugen, was   etwas, was Kernel-Code nicht tun darf. Das Ergebnis wäre   ein "oops", was zum Tod des Prozesses führen würde   der Systemaufruf.

  •   
  • Der betreffende Zeiger wurde von einem Benutzerprogramm geliefert, das   könnte fehlerhaft oder bösartig sein. Wenn dein Fahrer jemals blind deneferenziert   ein vom Benutzer zur Verfügung gestellter Zeiger, der eine offene Türöffnung ermöglicht   User-Space-Programm, um auf Speicher zuzugreifen oder zu überschreiben   System. Wenn Sie nicht für die Kompromittierung verantwortlich sein wollen   Sicherheit der Systeme Ihrer Benutzer, können Sie niemals eine dereferenzieren   User-Space-Zeiger direkt.

  •   

Quelle: Ссылка

Das heißt, ich bin selbst neugierig zu wissen, was passiert, wenn die Benutzerraumadresse tatsächlich gültig ist und keine der obigen Bedingungen zutrifft ...

    
gjain 10.05.2012 09:42
quelle
0

Sie müssen follow eine Adresse angeben, um eine entsprechende page struct zu erhalten (siehe follow_page für das Beispiel). Als nächstes, um die page Struktur zu erhalten, müssen Sie sie dem Adressraum des Kerns über kmap oder kmap_atomic zuordnen.

    
Ilya Matveychikov 09.05.2012 23:44
quelle