2010-11-09 10 views
5

Wie im Linux-Design auf x86 und ppc ist der virtuelle 4g-Adressraum in 3: 1 unterteilt. Benutzer virtuelle Adresse sind bis 3g.Warum ist copy_to/from_user erforderlich?

Nun, wenn Benutzer App ein ioctl übergeben einen Zeiger auf Puffer, das Kernel-Modul, kann direkt eine memcpy tun, ich habe versucht, und es hat funktioniert. => Warum brauchen wir dann einen copy_to/copy_from Benutzer?

Hinweis: Wenn die Seite ausgelagert wird, würde der kernel pagefault-Handler das zurückbringen und ist für das Kernel-Modul unsichtbar.

brauchen yr Ideen ... Kommentare

Antwort

9

Es gibt mehrere gute Gründe dafür, dass copy_to_user/copy_from_user die richtigen Funktionen zu nutzen:

  • Auf einigen Architekturen eine einfache memcpy() tut nicht Arbeit, so dass diese Funktionen verwenden, können Sie den Code dort zu arbeiten. Ich glaube, sogar x86 mit der HIGHMEM Konfig Option ausgewählt ist in diesem Boot.

  • Diese Funktionen führen eine access_ok() Prüfung durch, um sicherzustellen, dass die wirklich adressierten Benutzerraumadressen echte Benutzerraumadressen sind. Wenn Sie nur eine memcpy() tun, kann der Aufrufer der ioctl() einen Adressbereich, der Kernel-Adressen überlappt, die eine Sicherheitslücke ist.

  • Allerdings ist der Haupt Grund, um schlechte Benutzeradressen richtig zu behandeln. Wenn Sie einfach einen blanken memcpy() verwenden, führt der unbehandelte Fehler zu einem Kernel oops. Die Benutzerzugriffsfunktionen verwenden "fixup" mechanism, wodurch der Fehler behandelt werden kann (das Lesen oder Schreiben ist kurz, und in diesem Fall wird normalerweise EFAULT an den Benutzerbereich zurückgegeben).

+0

ok, also der Hauptgrund ist die Behandlung von ** schlechten ** Adressen. – mSO

+0

und wenn die Adressen gültig sind (sagen wir den besten Fall, niemand macht irgendeinen Unfug), sollte das Memcpy funktionieren. – mSO

+0

@Manish: Es ist nicht unbedingt "Unfug", es könnte einfach ein einfacher alter Bug im Userspace sein - solche Bugs sollten vom Kernel gut behandelt werden. Und das 'memcpy()' funktioniert nur auf einigen Architekturen überhaupt. – caf

0

Sie hatten Glück, es funktionierte.

Benutzerbereich und Kernelspeicherbereich arbeiten in völlig unterschiedlichen Adressräumen. Wenn Sie copy_to_user verwenden, übersetzt der Kernel die virtuelle Adresse des Benutzerbereichs in eine reale physikalische Adresse und kopiert die Daten dorthin. Ein ähnlicher Prozess tritt umgekehrt auf.

Es ist möglich, die Kopie zu/von Schritten direkt zu überspringen, wenn Ihre Hardware DMA unterstützt. Hier ordnen Sie einen zusammenhängenden Teil des virtuellen Speichers einer Reihe von physischen Seiten zu und verwenden diese Informationen dann direkt im Benutzerbereich für DMA. Dies hat natürlich Probleme, wenn der virtuelle Adressraum derzeit nicht dem physischen Speicher zugeordnet ist (Think Swap oder dateiunterstützte mmaps).

+0

die 3g: 1g Split sollte darauf achten. Der AFAIK-Kernel muss va nicht zum Kopieren in Pa umwandeln. – mSO

Verwandte Themen