IO-Flexpages in L4/Linux

Ähnliche Dokumente
Betriebssysteme KU - Bewertung A2 - WS 15/16

Betriebssysteme Übung 2. Tutorium System Calls & Multiprogramming

x86 Open Source Virtualisierungstechniken Thomas Glanzmann

Die L4-Mikrokern. Mikrokern-Familie. Hauptseminar Ansätze für Betriebssysteme der Zukunft. Michael Steil. Michael Steil

Echtzeitbetriebssysteme

Betriebssysteme KU - Einführungstutorium

Operating System Kernels

Embedded-Linux-Seminare. Linux als Betriebssystem

Einführung. Anwendung. logischer Adreßraum. Kontrollfluß (Thread) = CPU führt Instruktionen aus. Was charakterisiert einen Kontrollfluß?

Echtzeit-Multitasking

Sequentielle Programm- / Funktionsausführung innerhalb eines Prozesses ( thread = Ausführungsfaden )

Linux Paging, Caching und Swapping

A Kompilieren des Kernels B Lineare Listen in Linux C Glossar Interessante WWW-Adressen Literaturverzeichnis...

System Monitoring mit strace. Systemcall tracing

Microkernel-Betriebssysteme Mach, L4, Hurd

Was machen wir heute? Betriebssysteme Tutorium 2. Organisatorisches. Frage 2.1.a. Theorieblätter Abgabe. Antwort. Probleme mit OS/161?

Test (Lösungen) Betriebssysteme, Rechnernetze und verteilte Systeme

Überlegungen beim Entwurf eines Betriebssystems

Geräteverwaltung: Einführung

Betriebssysteme BS-V SS Hans-Georg Eßer. Foliensatz V: Ulix: Interrupts und Faults Ulix: System Calls. Dipl.-Math., Dipl.-Inform.

Systeme I: Betriebssysteme Kapitel 4 Prozesse. Wolfram Burgard

Architektur Verteilter Systeme Teil 2: Prozesse und Threads

Paging. Einfaches Paging. Paging mit virtuellem Speicher

2

Grundlagen Rechnerarchitektur und Betriebssysteme

Systeme I: Betriebssysteme Kapitel 8 Speicherverwaltung

Technische Informatik 1

Übung zu Betriebssystembau (Ü BS)

Übersicht. Virtueller Speicher CPU-Modi Virtuelle Maschinen. ISM SS Teil 4/ProtectionI

Betriebssystembau. 3. Übung. Michael Engel Arbeitsgruppe Eingebettete Systemsoftware. Lehrstuhl für Informatik 12 TU Dortmund

Konzepte und Methoden der Systemsoftware. Aufgabe 1: Polling vs Interrupts. SoSe bis P

Moderne Betriebssysteme. Kapitel 8. Kapitel 8. Folie: 1. Multiprozessorsysteme. Autor: Andrew S. Tanenbaum

CUDA. Jürgen Pröll. Multi-Core Architectures and Programming. Friedrich-Alexander-Universität Erlangen-Nürnberg Jürgen Pröll 1

Was machen wir heute? Betriebssysteme Tutorium 10. Frage 10.1.a. Frage 10.1.a

Name: ES2 Klausur Thema: ARM Name: Punkte: Note:

Linker: Adreßräume verknüpfen. Informationen über einen Prozeß. Prozeß-Erzeugung: Verwandtschaft

Betriebssysteme. 4y Springer. Eine kompakte Einführung mit Linux. Albrecht Achilles. Mit 31 Abbildungen

Kommunikationsmodelle

Systeme I: Betriebssysteme Kapitel 4 Prozesse. Maren Bennewitz

Was machen wir heute? Betriebssysteme Tutorium 12. Organisatorisches. Frage 12.1.a. Programmieraufgaben Vorstellung. Antwort

Wie groß ist die Page Table?

Memory Management Server

Hardware Virtualisierungs Support für PikeOS

Algorithmen und Datenstrukturen

Computeranwendung in der Chemie Informatik für Chemiker(innen) 3. Software

Systemsoftware (SYS) Fakultät für Informatik WS 2008/2009 Christian Baun. Übungsklausur

Einführung in die technische Informatik

PThreads. Pthreads. Jeder Hersteller hatte eine eigene Implementierung von Threads oder light weight processes

Tutorium Rechnerorganisation

Installation und Benutzung AD.NAV.ZipTools

Konzepte von Betriebssystemkomponenten. Gerätetreiber. Mario Körner

Geräte Treiber unter Unix/Linux

Dämon-Prozesse ( deamon )

PVFS (Parallel Virtual File System)

Programmieren in C. Speicher anfordern, Unions und Bitfelder. Prof. Dr. Nikolaus Wulff

RealTime Linux. Paul Seidel Seminar Prozessteuerung und Robotik WS 08/09 Lehrstuhl BS und Middleware Prof. Polze Hasso-Plattner-Institut Potsdam

Betriebssysteme KU - Einführungstutorium

Rechnernutzung in der Physik. Betriebssysteme

SMB / CIFS Protokoll. Ein Blick hinter die Kulissen C O N N E C T I N G B U S I N E S S & T E C H N O L O G Y

Konzepte von Betriebssystem-Komponenten. Microkernel-Betriebssysteme (Mach, L4, Hurd)

Prozesse, Logs und Systemverwaltung

Vorlesung 5: Interrupts

Benutzer- und Rechte-Verwaltung Teil 1

RTOS Einführung. Version: Datum: Autor: Werner Dichler

Prüfung VO Betriebssysteme SS2008 / 7. Juli 2008

In dieser Übung wird auf server01 eine Netzwerkfreigabe erstellt und NTFS Berechtigungen festgelegt.

Systeme I: Betriebssysteme Kapitel 4 Prozesse. Maren Bennewitz

POSIX Echtzeit: Kernel 2.6 und Preempt-RT

2 2. Tag. 2.1 Das Dateisystem. das Dateisystem organisiert die Speicherung von Daten. viele Betriebssysteme haben verschiedene Dateisysteme

Sicherheit von Smartphone-Betriebssystemen im Vergleich. Andreas Jansche Gerhard Klostermeier

Hardware-basierte Virtualisierung

Hardware-basierte Virtualisierung

5.5.5 Der Speicherverwalter

Instruktionssatz-Architektur

4.3 Hintergrundspeicher

Speicherverwaltung (Swapping und Paging)

Betriebssystem-basierte Virtualisierung

Konzepte von Betriebssystem Komponenten. Aufbau eines Modernen Betriebssystems (Windows NT 5.0)

Institut für Informatik

Dongle Generator: Technisches Datenblatt Betriebsanleitung Generieren Sie Ihren Dongle selbst!!! Allgemeine Angaben:

Realisierung: virtueller Prozessor: der reale Prozessor wird periodisch dem Programm zugewiesen Im Prozessor: durch Task-Status Segment (TSS)

Projekt für Systemprogrammierung WS 06/07

6 Speicherorganisation

Windows CE. Process Control and Robotics. Fabian Garagnon

Smartphone Entwicklung mit Android und Java

Assembler - Einleitung

Übung zu Einführung in die Informatik # 10

Enterprise Computing Einführung in das Betriebssystem z/os. Prof. Dr. Martin Bogdan Prof. Dr.-Ing. Wilhelm G. Spruth WS2012/13

kernkonzept L4Re ISOLATION UND SCHUTZ IN MIKROKERNBASIERTEN SYSTEMEN kernkonzept 1

3. Unix Prozesse. Betriebssysteme Harald Kosch Seite 57

Betriebssysteme SS Hans-Georg Eßer Dipl.-Math., Dipl.-Inform. Foliensatz E SB 5 ( ) ACLs und Capabilities

Transkript:

IO-Flexpages in L4/Linux Bernhard Kauer Bernhard.Kauer@inf.tu-dresden.de November 12, 2002 1

Contents 1 Ziel 3 2 Einführung 3 3 Ausgangszustand 3 3.1 DerIOPL... 4 3.2 DieIOPBM... 4 3.3 cli/sti... 4 3.4 popf... 5 3.5 iret... 5 4 L4/Linux 6 4.1 Pagefaults... 6 4.2 Pager... 6 4.3 PageRequest Linux-Kern...... 6 4.4 LinuxSystemcalls... 6 4.4.1 sys ioperm... 6 4.4.2 sys iopl... 7 4.5 DerRechteentzug... 7 5 Implementierung 8 5.1 Root-Pager... 8 5.2 DieIODB... 8 5.3 Servicethread........ 9 5.4 Emulib... 9 5.5 DieSystemcalls... 9 5.6 Fiasco... 9 6 Ausblick 10 7 Anhang 11 7.1 Die verändertendateien... 11 7.2 Bugs... 11 7.3 Tests... 12

1 Ziel Das Ziel dieses Praktikums ist die Implementierung von IO-FlexPages in L4/Linux der Version 2.2.22. 2 Einführung Der Zugriff auf periphäre Geräte kann in der IA-32 Architektur durch Memory Mapped IO oder durch IO-Ports erfolgen. Diese IO-Ports bilden einen eigenen Adressraum, auf den mit den Befehlen in/out zugegriffen werden kann. Da die unsachgemäße Verwendung von IO-Ports zu Datenverlust und Systemabstürzen führen kann, muss der Zugriff auf diese durch das Betriebssystem geschützt werden. Bei Memory Mapped IO kann dies durch die Schutzmechanismen des Virtual Memory erfolgen. Diese stehen für die IO-Ports leider nicht zur Verfügung. Für die Abstraktion eines Memory-Adressraumes werden in L4 Flex-Pages ( Flexibel große Seiten ) verwendet, die als Datentyp des Mapping-Konzeptes dienen. Die Einführung von IO- FlexPages erlaubt die Ausdehnung dieses Konzeptes auf den IO-Adressraum. Dabei steht eine IO-FlexPages für einen bestimmten IO-Portbereich. Durch Einbinden einer IO-FlexPages in den Adressraum der Tasks wird der Zugriff auf diesen Bereich freigegeben. Die Freigabe kann feingranular (byteweise) erfolgen, dennoch sind nur 1:1 Mappings möglich. 3 Ausgangszustand Einige Linuxtasks müssen auf externe Geräte und damit auf IO-Ports zugreifen. Da zur Zeit keine Unterscheidung zwischen den erlaubten und unerlaubten Zugriffen möglich ist, darf jede L4/Linux-Task (also auch jeder Nutzer-Prozess) auf alle 64K Ports zugreifen und die Interrupts sperren. Da dies ein erhebliches Sicherheitsrisiko darstellt, ist ein Implementieren der IO-FlexPages nötig.

3.1 Der IOPL Für den Schutz des Betriebssystemkernes vor Anwenderprogrammen existiert der CPL (Current Privilege Level). Dieser legt in 4 Abstufungen die Privilegien des aktuellen Programmes fest, wobei 0 für den Kernmodus verwendet wird und 3 für die Anwenderprogramme. Durch den IOPL (IO Privilege Level) wird die Maximal-Stufe des CPL (Current Privilege Level) festgelegt, die ein Thread haben darf, um auf alle IO-Ports zuzugreifen und cli/sti ausführen zu können. L4/Linux-Tasks werden ohne IO-FlexPages mit einem IOPL von 3 ausgeführt. Ein direktes Setzen des IOPL aus einer Task heraus ist nicht möglich. Erst durch das Anfordern aller IO-Ports kann in L4 der IOPL erhöht werden. Dies geschieht lazy, d.h. erst nach einem Pagefault wird der IOPL geändert. 3.2 Die IOPBM Die IOPBM (IO Privilege Bitmap) legt per Bitmaske diejenigen Ports fest, auf die trotz IOPL-Verletzung zugegriffen werden darf. Eine vollständige IOPBM belegt 8k, wobei auch kleinere Bitmap s existieren können. Diese IOPBM wird für jede Task in L4 geführt, die IO- FlexPages verwendet. Damit kann der Prozessor den Schutz einzelner Ports gewährleisten. 3.3 cli/sti Die ASM Befehle cli/sti sperren bzw. geben die maskierbaren Interrupts frei, indem sie das IF (Interrupt Flag) löschen bzw. setzen. Diese Befehle werden z.z. vor allem an folgenden Stellen in L4/Linux eingesetzt: bei der Emulation(L4 TAMED) von cli/sti in den Funktionen global sti() zur Synchronisation einer Warteschlange 1 global cli() und in l4 idle() 2 beim Auslesen des RTC 3 beim Programmieren der PIC s 4 Eine Verwendung dieser Befehle birgt ein erhebliches Sicherheitsrisiko. Da keine Timerinterrupts mehr generiert werden, findet kein Scheduling statt. Wenn dann der laufende Thread blockiert, führt dies zum Stillstand des gesamten Systems. 1 linux22/arch/l4/x86/kernel/irq.c 2 linux22/arch/l4/x86/kernel/dispatch.c 3 linux22/arch/l4/x86/kernel/time.c 4 linux22/arch/l4/x86/kernel/irq.c

3.4 popf Weiterhin existiert der Befehl popf, der alle Flags (auch das IF ) vom Stack neu lädt. Ein Ändern des IF ist auch hier nur möglich, wenn der IOPL größerodergleichdemcpl ist. Fehlen die Rechte, so ignoriert der Prozessor die IO-Flags beim Setzen, anstatt eine Exception auszulösen. 3.5 iret Die Flags können auch vom iret-befehl zurückgeladen werden. benutzt, um eine Task im aktuellen User-Kontext fortzusetzen. Dieser wird im L4-Kern

4 L4/Linux 4.1 Pagefaults Zugriffe auf nicht vorhandenen (eingetragenen) virtuellen Speicher erzeugen Seitenfehler (Pagefaults). Diese Seitenfehler werden von L4 an den Pager des aktuellen Threads per IPC geschickt. Dieser kann die Seitenfehler auflösen, indem er die entsprechenden Seiten an den Thread als Antwort der IPC zurücksendet. Die nichterlaubten Zugriffe im IO-Adressraum werden auch durch l4 in Pagefaults umgewandelt 5, so dass sie entsprechend den Speicherseitenfehlern behandelt werden können. 4.2 Pager Der Servicethread im Linux-Server 6 dient als Pager für die Linuxanwendungen. Für den L4/Linux-Kern existiert ein sogenannter Root-Pager 7, der das Paging für alle L4/Linux- Kernthreads übernimmt. Bei der Initialisierung des L4/Linux-Kernes bekommt dieser seinen gesamten Speicher vom RMGR, der ihn wiederum von Sigma0, dem intialen Pager des Systems, hat. 4.3 PageRequest Linux-Kern Die Anforderung von Seiten für den Kern findet durch die Routinen request{ virtual, dev}- page from sigma0 statt 8. Trotz dieses Namens wird der aktuelle Pager des Threads verwendet 9.Für den Root-Pager ist dies der RMGR. 4.4 Linux Systemcalls Für das Ändern der Zugriffsrechte auf IO-Ports von Linux-Prozessen aus existieren die Systemcalls sys ioperm() und sys iopl() 10. Zum Erhöhen der IO-Privilegien ist die Capability CAP SYS RAWIO nötig, die normalerweise nur Prozesse mit UID 0, also mit Root-Rechten, besitzen. 4.4.1 sys ioperm Der Linux-Systemcall sys ioperm() erlaubt das Setzen der Zugriffsrechte für die ersten 1024 Ports. Dabei kann man mit einem Aufruf der Zugriff auf einen beliebigen Port-Bereich (portgranular) erlaubt bzw. verboten werden. Die Speicherung der Zugriffsdaten erfolgt bei Linux/i386 in einer Bitmap (thread struct.io bitmap), die eine Größe von 1024 Bit hat. 5 l4/kernel/fiasco/src/kern/thread-io.cpp 6 linux22/arch/l4/x86/kernel/dispatch.c 7 linux22/arch/l4/x86/lib/l4 pager.c 8 linux22/arch/l4/x86/lib/l4 memory.c 9 checkpager() 10 linux22/arch/i386/kernel/ioport.c

4.4.2 sys iopl Soll der Zugriff auf höhere Port-Bereiche erlaubt werden, so ist das Ändern der IOPL durch sys iopl() nötig. Da ein hoher IOPL neben dem Zugriff auf alle Ports auch das Recht zum Sperren der Interrupts einschließt, ist dies ein unsicheres Verfahren. Dennoch verwenden z.b. einige X-Server dies, um auf die benötigten Ports zuzugreifen. 4.5 Der Rechteentzug Die Systemcalls können die Rechte wieder entziehen. Dazu sind die IO-FlexPages mit l4 fpage unmap() zu entfernen. Dies setzt jedoch eine funktionierende 11 Mappingdatenbank voraus und ist durch die (potentiell hohe) Anzahl der beteiligten Tasks aufwendig. Um dennoch die Rechte zu entziehen, existieren zwei Möglichkeiten: Man kann erstens den Signalthread verwenden, um das Austragen durchzuführen. Dazu schickt man eine bestimmte IPC, die zur Ausführung der Methode führt. Dieses Verfahren setzt ein kooperierenden Thread voraus und ist deswegen sicherheitstechnisch ungünstig. Zweitens ist es möglich, direkt nach dem Systemcall in der Emulib die Seiten zu entfernen, da jeder Systemcall durch die Emulib gekapselt wird. Die Sicherheit wird nicht weiter beeinträchtigt. Eine kooperierende Emulib muß schon für die Systemcalls vorausgesetzt werden. Die Verwendung einer modifizierten glibc für das direkte Ausführen des Syscalls ohne den Trampolinmechanismus der Emulib ist jedoch hier nicht möglich. Aus oben genannten Gründen und wegen des geringsten Implementierungsaufwandes ist die zweite Möglichkeit implementiert worden. 11 IO-FlexPages sind dort nicht eintragbar.

5 Implementierung 5.1 Root-Pager Weil der IOPL in Fiasco lazy erhöht wird, verursacht jeder L4/Linux-Kernel-Thread ein Pagefault beim ersten cli/sti. Der Pagefault kann ignoriert werden, da der L4/Linux-Task zur Zeit mit hoher IOPL läuft Das Eintragen aller IO-Ports in den Adressraum des Kernel-Task findet bereits beim ersten printk() während der Initialisierung statt 12, da dies zur Synchronisation ein Spinlock verwendet, welches mit cli arbeitet. Ein Request an RMGR ist daher hier momentan nicht nötig. 5.2 Die IODB Für die Speicherung der erlaubten IO-Rechte in L4/Linux wurde thread struct um einen Zeiger io db erweitert 13. Der Zugriff auf die Rechte erfolgt durch zwei Routinen namens iodb read portrange() und iodb write portrange. Dies erlaubt eine einfache Auswechslung der dahinter liegenden Datenstruktur. Gespeichert werden nicht die einzelnen Ports, sondern nur der Anfang und das Ende der erlaubten Port-Bereiche. Diese Speicherung erlaubt bei wenigen Port-Bereichen eine effizientere Nutzung als die übliche Port-Bitmap. Die Bereiche sind der Größe nach sortiert und werden minimal gehalten, d.h. Überlappungen oder angrenzende Bereiche werden beim Eintragen verschmolzen. Außerdem existiert ein Kopf in dieser Struktur, der neben der Anzahl der Einträge und der Größe auch die IOPL enthält. Da in Linuxdie bitweise Freigabe der Ports vom IOPL unabhängig ist, ist hier, anders als in L4, eine getrennte Speicherung des IOPL nötig. Der Kopf dieser Datenstruktur belegt, genau wie ein Element, 4 Byte. Der Speicher dafür wird in Potenzen von 2 angefordert. Mindestens 16 Byte (Kopf+3 Elemente) werden für Threads, die Einträge in der IODB haben, benötigt. 12 linux22/init/main.c 13 linux22/include/asm/l4arch/processor.h

5.3 Servicethread Der Servicethread in dispatch.c 14 wurde in der Routine handle page fault() um die Möglichkeit der Behandlung eines IO-Page-Faults erweitert. Hat ein User-Prozess den IOPL von 3 in der IODB durch sys iopl() eingetragen oder den Port durch sys ioperm() freigegeben, so wird ihm die benötige IO-FlexPage zugesandt. Andernfalls löst ein seg fault above task size() ein SIGSEGV aus. 5.4 Emulib Das Austragen der IO-FlexPages findet in der Emulib 15 statt. Dazu wurde die Struktur shared data um einen Eintrag flush page für eine FlexPage erweitert. Ist dieser Eintrag ungleich null wird ein unmap() aufgerufen. 5.5 Die Systemcalls Die Systemcalls sys iopl() und sys ioperm() wurden analog der i386 Variante implementiert. Nach Abfragen der Rechte (capability CAP SYS RAWIO) und dem Testen auf einige Fehler werden mit iodb write portrange() die IO-Zugriffsrechte gespeichert. Werden die Rechte eingeschränkt, wird in shared data.flush page eine Seite über alle IO-Ports eingetragen und später durch die Emulib wie beschrieben entfernt. 5.6 Fiasco Bisher ist in Fiasco das Entfernen von IO-FlexPages nicht implementiert 16. Dies liegt hauptsächlich an einer Einschränkung der Mappingdatenbank, die zur Zeit mit IO-FlexPages nicht umgehen kann. Unter der Annahme, daß Usertasks keine IO-FlexPagesweitergeben, ist die Kenntnis der Mappinghierarchie unwichtig. Daher reicht hier eine einfache Implementierung des Entfernens nur für den aktuellen Task aus. Das Problem des Entziehens des IOPL in allen Threads einer Task ist bisher noch nicht gelöst. Dazu ist ein Iterieren über alle Threads in Fiasco nötig, um die EFLAGS zu ändern, die für jeden Thread, und nicht für jeden Task gespeichert werden. 14 linux22/arch/l4/x86/kernel/dispatch.c 15 linux22/arch/l4/x86/emulib/int entry.s 16 l4/kernel/fiasco/src/kern/map util.cpp

6 Ausblick Werden in L4/Linux keine Interrupts mehr gesperrt, kann man auch im Linux-Kern auf einen hohen IOPL verzichten. Dazu sollte 17 : die zur Speicher-Synchronisation eingesetzten cli/sti durch geeignete Synchronisationsprimitive (Semaphorethread) ersetzt werden die zur Hardware-Synchronisation eingesetzten cli/sti in Omega0 verlagert werden die Verwendung von popf im Linux-Kern zum Verändern des IF ausgeschlossen sein Wird die Verwaltung der IO-FlexPages durch die Mappingdatenbank übernommen, so könnte auch ein direkter l4 fpage unmap()-aufruf in den Syscalls erfolgen, der dann keine Kooperation mehr voraussetzen würde. 17 Der entsprechende Code existiert, ist jedoch noch nicht im CVS enthalten.

7 Anhang 7.1 Die veränderten Dateien Im Rahmen der Implementierung wurden folgende Dateien verändert: Datei linux22/arch/l4/x86/lib/l4 pager.c linux22/include/asm/l4arch/processor.h linux22/arch/l4/x86/kernel/makefile linux22/arch/l4/x86/kernel/unimpl.c linux22/arch/l4/x86/kernel/dispatch.c linux22/arch/l4/x86/kernel/ioports.c linux22/include/l4linux/x86/ioports.h linux22/arch/l4/x86/emulib/int entry.s l4/kernel/fiasco/src/kern/map util.cpp Grund IO-Pagefaults in Kernelthreads ignorieren thread struct erweitern file ioports.c hinzugefügt sys iopl() und sys ioperm() entfernen IODB abfragen und reply setzen IODB und Systemcalls implementiert IODB header file UnMap-Syscall wenn flush-page vorhanden UnMapping der IO-FlexPages für einzelnen Task 7.2 Bugs Während der Implementierung sind einige, mehr oder weniger bekannte, Bugs aufgetreten. Bezeichnung Grund Behebung VMWareBug 6338 Vmware versteht FIASCO mit Option erweiterte PIC-Programmierung nicht -vmware starten TimeOut Bug Vmware liefert nur alle 10ms FIASCO mit Timer Interrupts SCHED PIT compilieren

7.3 Tests Um die Implementation zu testen wurde ein einfaches C-Programm geschrieben, was folgende Tests ausführt: Routine test clisti Beschreibung cli bei iopl=0 lazy iopl switching sti bei iopl=3 reset iopl sti bei iopl=0 test ioport() test fork() out ohne Rechte Freigabe für einen Port und Zugriff um diesen Port Freigabe von 4 Ports und 32-Bit Portzugriff Freigabe von 3 Ports und 32-Bit Portzugriff IOPL und Portzugriff Unabhängigkeit von iopl und ioperm Freigabe von Port und iopl fork() Rücksetzen des IOPL in Parent sti in child bei iopl=3 sti in child bei iopl=0 Portzugriff auf vor fork() freigegebenen Port