2012-08-17 3 views
5

Ich schreibe ein Kernelmodul, das Zugriff auf den Speicher eines bestimmten Prozesses hat.Ändern der Benutzerspeicher-Schutzflags vom Kernelmodul

#define MAP_FLAGS (MAP_PRIVATE | MAP_FIXED | MAP_ANONYMOUS) 

prot = PROT_WRITE; 
retval = do_mmap(NULL, vaddr, vsize, prot, MAP_FLAGS, 0); 

vaddr und vsize gesetzt früher, und der Aufruf erfolgreich ist: Ich habe eine anonyme Mapping auf einen Teil des User-Space-Speicher mit do_mmap() getan. Nachdem ich von dem Kernelmodul in diesen Speicherblock geschrieben habe (über copy_to_user), möchte ich die PROT_WRITE Erlaubnis darauf entfernen (wie ich mit mprotect im normalen Benutzerraum) würde. Ich kann keine Funktion finden, die dies erlaubt.

Ich habe versucht, die Region aufzulösen und sie mit den richtigen Schutzfunktionen neu zuzuordnen, aber das löscht den Speicherblock aus und löscht alle Daten, die ich gerade geschrieben habe; MAP_UNINITIALIZED Einstellung könnte die in Ordnung bringen, aber von dem Manpages:

MAP_UNINITIALIZED (seit Linux 2.6.33)

nicht klar anonyme Seiten tun. Dieses Flag soll die Leistung eingebetteter Geräte verbessern. Dieses Flag wird nur berücksichtigt, wenn der Kernel mit der Option CONFIG_MMAP_ALLOW_UNINITIALIZED konfiguriert wurde. Wegen der Sicherheitsimplikationen wird diese Option normalerweise nur auf eingebetteten Geräten aktiviert (d. H. Auf Geräten, bei denen eine vollständige Kontrolle über den Inhalt des Benutzerspeichers vorliegt).

so, während das könnte tun, was ich will, wäre es nicht sehr portabel sein. Gibt es einen Standardweg, um das zu erreichen, was ich vorgeschlagen habe?

+0

Warum oh warum machst du das alles in deinem Kernel-Modul? Bei einer klar definierten API gibt es keinen Grund, der nicht durch den Userspace-Prozess selbst verursacht werden könnte. – mpe

+0

@mpe Der Grund, warum ich es nicht in Benutzerraum tun kann, ist, dass das Modul, das ich schreibe, ein Prozesslader ist; Ich habe keinen Einfluss auf den User Space Code. – nosuchthingasstars

+0

Was meinen Sie mit Prozesslader? Meinst du einen binfmt Handler? – mpe

Antwort

1

Nach einigen mehr Forschung, fand ich eine Funktion namens get_user_pages() (beste Dokumentation ich gefunden habe, ist here), die an einer bestimmten Adresse eine Liste von Seiten aus dem Userspace zurückgibt, die abgebildet werden kann Raum auf Kernel mit kmap() und geschrieben, dass Weg (in meinem Fall mit kernel_read()). Dies kann als Ersatz für copy_to_user() verwendet werden, da es Schreibrechte für die abgerufenen Seiten erzwingt. Der einzige Nachteil ist, dass Sie Seite für Seite statt alle auf einmal schreiben müssen, aber es löst das Problem, das ich in meiner Frage beschrieben habe.

0

Im Benutzerbereich gibt es einen Systemaufruf mprotect, der die Schutzkennzeichen für vorhandenes Mapping ändern kann. Sie müssen wahrscheinlich von der Implementierung dieses Systemaufrufs folgen oder ihn einfach direkt von Ihrem Code aus aufrufen. Siehe mm/protect.c.