2009-11-08 11 views
9

Ich habe eine Art von Zeichen-Gerät implementiert und ich brauche Hilfe mit copy_ from_user Funktion.Linux Kernel: copy_from_user - Struktur mit Zeigern

Ich habe eine Struktur:

struct my_struct{ 

int a; 

int *b; 
}; 

ich es im User-Space initialisieren und übergeben Zeiger auf mein char Gerät my_struct Funktion ‚schreiben‘. In der Funktion "Schreiben" des Space-Zeichens des Kernels werfe ich es von einem * char auf diese Art von Struktur um. Ich ordne Speicher für eine Struktur mit kmalloc und tun copy_from_user hinein.

Es ist in Ordnung für einfache 'int a', aber es kopiert nur Zeiger (Adresse) von b-Wert, nicht Wert von b, so bin ich jetzt im Kernel Space und ich arbeite mit einem Zeiger, der auf zeigt ein Benutzerraumspeicher. Ist das falsch und ich sollte nicht direkt auf User Space Zeiger zugreifen und ich muss copy_from_user jeden einzelnen Zeiger in meiner Struktur und dann jeden Zeiger in "lesen" -Funktion mit copy_to_user Funktion zurück kopieren?

Antwort

6

Sie haben Ihre Vermutung richtig. Wenn Sie auf den Wert *b zugreifen müssen, müssen Sie copy_from_user (und copy_to_user verwenden, um es im Benutzerprozess zu aktualisieren).

+2

Ich würde auch darauf hinweisen, dass ich an keine syscalls oder ioctls denken kann, die Strukturen mit Zeigern in ihnen nehmen. Selbst diejenigen, die Zeichenfolgen haben, werden stattdessen eine Reihe von Zeichen in der Struktur haben. Die Tatsache, dass es sehr ärgerlich ist, Code für jedes Zeigerelement zu schreiben, könnte damit etwas zu tun haben. :-) – asveikau

+0

@asveikau: 'readv()' und 'writev()'? – caf

13

Sie müssen immer copy_from_user und ähnliches verwenden, um auf den Benutzer-Space-Speicher vom Kernel-Space zuzugreifen, unabhängig davon, wie Sie den Zeiger erhalten haben. Da b ein Zeiger auf Benutzerspeicher ist, müssen Sie copy_from_user verwenden, um darauf zuzugreifen.

Diese Funktionen machen zwei weitere wichtige Aufgaben:

  1. Sie sicher, dass der Zeiger in Benutzerraum machen und keinen Platz Kernel. Ohne diese Überprüfung können Benutzer-Space-Programme möglicherweise in den Kernel-Speicher schreiben oder lesen, wobei die normale Sicherheit umgangen wird.
  2. Sie behandeln Seitenfehler korrekt. Normalerweise führt ein Seitenfehler im Kernel-Modus zu einer OOPS oder Panik - die copy_*_user Familie von Funktionen hat eine spezielle Überschreibung, die dem PF-Handler mitteilt, dass alles in Ordnung ist, und der Fehler sollte normal behandelt werden; und für den Fall, dass der Fehler nicht von IO erfüllt werden kann (dh was normalerweise SIGSEGV oder SIGBUS verursacht), geben Sie stattdessen einen Fehlercode zurück, damit der Aufrufer alle notwendigen Bereinigungen vornehmen kann, bevor er mit -EFAULT zum Benutzerbereich zurückkehrt.