User-Mode-Linux ist eine Software, die sowohl in die Bereiche Benutzerprogramme, als auch Betriebssysteme zugeordnet werden kann. UML ist der Kategorie der Systemvirtualisierung zuzuordnen, dessen Funktionalität sich von weiteren Virtualiserungstechnologien stark unterscheidet. Eine UML-
Instanz wird vom Benutzer in einem Hostsystem als Benutzerprogramm gestartet und ohne Root-Privilegien am Hostsystem ausgeführt. UML verzichtet auf eine Virtualisierungsschicht. Die Architekturschnittstelle des UML-
Kernels ist die einzige Komponente, die sich von herkömmlichen Linuxkernel unterscheidet. Diese Schicht kommuniziert nicht mit der Hardware, sondern fordert Ressourcen vom Hostbetriebssystem als Benutzerprozess an. Diese Vorgehensweise beschränkt den Einsatz von UML auf Hostsystemen, die unter Linux betrieben werden.
Das erste Kapitel betrachtet die wesentlichen Komponenten eines Betriebssystems. Eingeleitet wird mit der Funktionsweise des Linuxkernels und die Differenzen der eingesetzten Architekturen. UML erzeugt für eigene Zwecke Prozesse am Host, weshalb auch das Thema Prozessmanagement betrachtet wird. Ein weiterer Punkt ist das Speichermanagement, da UML als Betriebssystem Haupt- und Festplattenspeicher benötigt, der vom Host zur Verfügung gestellt werden muss. Abgeschlossen wird dieses Kapitel mit einem Exkurs in die Funktionsweise alternativer Virtualisierungstechnologien.
Der Hauptteil umfasst die Funktionsweise und Eingliederung von UML auf einem Hostsystem. Es existieren unterschiedliche Varianten, wie UML am Host betrieben werden kann, weshalb deren Funktionsweisen analyisiert werden. Behandelt wird auch die Virtualisierung von Ressourcen durch UML.
Im letzten Kapitel werden die Sicherheitsaspekte von UML untersucht. Möglichkeiten, die einem Benutzer den Ausbruch aus UML auf das Hostsystem ermöglichen, werden aus unterschiedlichen Blickwinkeln erklärt, sowie Möglichkeiten, um Ausbrüche zu verhindern. Abschließend werden Einsatzgebiete er örtert, deren Erschließung durch UML in Zukunft geplant ist.
Inhaltsverzeichnis
Motivation
Kurzfassung
Abstract
1 Grundlagen
1.1 Linux-Kernel
1.1.1 Einleitung
1.1.2 Aufbau und Funktionsweise des monolithischen Kernels
1.2 Prozessmanagement
1.2.1 Prozesse vs. Threads
1.2.2 Erstellen & Beenden von Prozessen
1.2.3 Prozesszustande
1.2.4 User- & Kernelmode
1.2.5 Interrupts
1.3 Speichermanagement
1.3.1 Speicheradressierung
1.3.2 Paging
1.4 I/O
1.4.1 Hardwareschichten
1.4.2 Softwareschichten
1.5 Virtual Machines
1.5.1 Techniken
1.5.2 Virtual Machine Monitor
1.5.3 CPUs mit Virtualisierungstechnologien
2 UML Theorie
2.1 Architektur
2.1.1 Aufbau
2.1.2 Systemcalls
2.1.3 Traps
2.2 Managmentkonsole
2.2.1 Aufbau
2.3 Ausfuhrungsmodi
2.3.1 tt-Modus
2.3.2 Skas3-Modus
2.3.3 Skas0-Modus
2.4 Speichermanagement
2.4.1 Hauptspeicher
2.4.2 Filesysteme
2.4.3 hostfs
2.4.4 humfs
2.5 Security
2.5.1 Ausbruchsmoglichkeiten
2.5.2 Chroot
2.5.3 Ausbruch aus einem UML-Jail
3 UML-Praxis - Ausbruchsmoglichkeiten
3.1 Ausbruch durch das Filesystem
3.1.1 Vorgehensweise
3.1.2 Abwehr
3.2 Kernelmodul
3.2.1 Idee
3.2.2 Charakteristik von Modulen
3.2.3 Funktion
3.2.4 Modulerstellung
3.3 UML-Hauptspeicher
3.3.1 Idee
3.3.2 Ablauf
3.4 Systemcallhacking
3.4.1 lcall
3.4.2 ptrace
3.5 Shellcodeinjection
3.5.1 Vorgehensweise
3.5.2 Aufbau
3.5.3 Einschleusung
4 Fazit und Ausblick
5 Glossar
A Zusatzinformation
A.1 UML-Theorie
A.1.1 Sysrq-Kommandos
A.1.2 Terminal I/O
A.1.3 tmpfs-Performancetest
Literaturverzeichnis
Motivation
User-Mode-Linux, abgekurzt als UML1, wurde von Jeff Dike im Jahre 1999 entwickelt. Es handelt sich dabei um ein Produkt aus der Virtualisierung. Der Wunsch, Betriebssysteme unabhangig innerhalb anderer Betriebssys- teme zu betreiben, wurde mit UML auf einem bisher noch nicht existierenden Loasungsweg realisiert. Bisher musste, unabhaangig von der eingesetzten Technologie, eine Zwischenschicht die Trennung der Betriebssysteme vorneh- men. Die UML-Architektur ist so konstruiert, dass auf einen performance- lastigen Layer verzichtet werden kann. Damit dieses Konzept auch auf exis- tierende Betriebssysteme umgesetzt werden kann, ist hier schon eine erste Einschraankung zu sehen. UML unterstuatzt lediglich Linux-Betriebssysteme.
UML kann von zwei unterschiedlichen Standpunkten analysiert und be- urteilt werden. Die haufig vorkommende Feststellung „UML ist ein Be- triebssystem, das wie ein Programm auf einem Betriebssystem lauft“ liefert schon eine grundlegende Definition von dem, was UML darstellt. Aus dem Betrachtungswinkel eines Benutzers am Hostsystem ist UML ein Benutzer- prozess, auf den ersten Blick nicht vom Prozess einer anderen Anwendung zu unterscheiden. Aus anderem Betrachtungswinkel, dem des Benutzers in- nerhalb UML, ist UML ein vollwertiges Betriebssystem, das zunaachst nicht von einem Hostbetriebssystem unterscheidbar ist.
Der Ua bergang vom Betriebssystem zum Benutzerprogramm muss, da kein Virtualisierungslayer existiert, vom UML-Kernel ubernommen werden. Um einen Linuxkernel zu einem UML-Linuxkernel umzufunktionieren, muss bei dessen Ubersetzung lediglich die eigens dafur entwickelte User-Mode- Architektur anstelle z.B. der x86-Architektur verwendet werden. Zugriffe, die ein gewohnlicher Kernel an der Hardware durchfuhrt, werden bei einem UML-Kernel durch die UML-Arch-Schnittstelle simuliert. Diese Schicht lei- tet die Anfragen an den Hostkernel als gewohnlicher Usermode-Prozess wei- ter.
Gerade durch diese transparente Architektur bietet UML interessante Einsatzgebiete.
Kernel- und Prozessdebugging
Der UML-Kernel kann vom Host aus mit denselben Tools debugged werden, wie es bei einem Benutzerprogramm moglich ist. Ebenso konnen UML- Benutzerprozesse debugged werden.
Lehre
UML eignet sich als virtuelles Betriebssystem hervorragend im Rahmen des Unterrichts. Studenten konnen an UML nicht nur die Funktionsweise und Eigenschaften von Betriebssystemen beobachten, sondern auch diese mo- difizieren, ohne dass die Gefahr besteht, Schaden am Hostbetriebssystem zu verursachen. Durch UML koonnen auch andere Systemkomponenten, wie z.B. GroBe des Hauptspeichers oder die Anzahl der CPU-Kerne, unabhangig vom realen Vorhandensein ausgewahlt werden.
Sandbox
Eine Sandbox schottet Prozesse, die in dieser betrieben werden, vom Rest des Systems ab. Prozesse, die innerhalb von UML laufen, erlangen, so- weit es nicht gewollt ist, keinen Zugriff auf das Hostsystem. Anwendungen koonnen somit keinen Schaden am Hostsystem anrichten. UML stellt selbst eine Sandbox dar und kann auch als Usermode-Programm, als Prozess des Hostsystems ebenso wie ein gewohnlicher Benutzerprozess in einer weiteren Sandbox betrieben werden, etwa durch Einsatz des ,,chroot“-Systemcalls. Prozesse, die innerhalb einer Sandbox laufen, besitzen keine Moglichkeit, aus dieser Sandbox auszubrechen. Die Sandbox umfasst einen vom Benut- zer definierten Bereich in der Verzeichnishierachie und im Hauptspeicher, der fur die eingeschlossenen Programme als gesamt verfugbarer Ressourcen- bereich wirkt. Ausbruche in andere Verzeichnisse durch absolute Pfadnamen oder Befehle2 werden als gewohnliche Systemcalls an den Kernel, unter dem die Sandbox lauft, gerichtet, welcher diese lediglich in den Speicherbereichen der Sandbox verarbeitet und einen Ausbruch verhindert.
Virtuelles Netzwerk
Auf einem Hostsystem konnen durchaus mehrere Instanzen betrieben werden, die durch ein simuliertes Netzwerk miteinander verbunden werden. Dies lasst sich durch unterschiedliche Varianten realisieren. Ein dafur notwendi- ger Switch wird als eigenstandiges Hostprogramm von UML zur Verfugung gestellt. Instanzen kdnnen mit ,,tun“- oder ,,tap“-Schnittstellen3 verbunden werden und somit eine Kommunikation zwischen weiteren UML-Instanzen oder Systemen auBerhalb des Hostsystems aufnehmen. Elne weltere Moglich- kelt beschrankt slch ledlgllch auf UML-Instanzen, wobel kelne Schnlttstellen vom Host zur Verfugung gestellt werden und eventuelle Gefahrdungen ln- nerhalb des UML-Netzwerkes nlcht das reale Netzwerk beelntrachtlgen. Der Vortell von vlrtuellen Netzwerken llegt darln, dass dle Kommunlkatlon von mehreren Systemen uber das Netzwerk ohne Emschrankungen ln der Funktlo- nalltat entwlckelt und getestet werden kann, ohne zwel oder mehrere reale Systeme zu benaotlgen.
Kurzfassung
User-Mode-Linux ist eine Software, die sowohl in die Bereiche Benutzer- programme, als auch Betriebssysteme zugeordnet werden kann. UML ist der Kategorie der Systemvirtualisierung zuzuordnen, dessen Funktionalitat sich von weiteren Virtualiserungstechnologien stark unterscheidet. Eine UML- Instanz wird vom Benutzer in einem Hostsystem als Benutzerprogramm ge- startet und ohne Root-Privilegien am Hostsystem ausgefuhrt. UML verzich- tet auf eine Virtualisierungsschicht. Die Architekturschnittstelle des UML- Kernels ist die einzige Komponente, die sich von herkommlichen Linuxkernel unterscheidet. Diese Schicht kommuniziert nicht mit der Hardware, sondern fordert Ressourcen vom Hostbetriebssystem als Benutzerprozess an. Diese Vorgehensweise beschraankt den Einsatz von UML auf Hostsystemen, die unter Linux betrieben werden.
Das erste Kapitel betrachtet die wesentlichen Komponenten eines Be- triebssystems. Eingeleitet wird mit der Funktionsweise des Linuxkernels und die Differenzen der eingesetzten Architekturen. UML erzeugt fur eigene Zwecke Prozesse am Host, weshalb auch das Thema Prozessmanagement betrachtet wird. Ein weiterer Punkt ist das Speichermanagement, da UML als Betriebssystem Haupt- und Festplattenspeicher benoatigt, der vom Host zur Verfugung gestellt werden muss. Abgeschlossen wird dieses Kapitel mit ei- nem Exkurs in die Funktionsweise alternativer Virtualisierungstechnologien.
Der Hauptteil umfasst die Funktionsweise und Eingliederung von UML auf einem Hostsystem. Es existieren unterschiedliche Varianten, wie UML am Host betrieben werden kann, weshalb deren Funktionsweisen analyisiert werden. Behandelt wird auch die Virtualisierung von Ressourcen durch UML.
Im letzten Kapitel werden die Sicherheitsaspekte von UML untersucht. Moglichkeiten, die einem Benutzer den Ausbruch aus UML auf das Host- system ermoglichen, werden aus unterschiedlichen Blickwinkeln erklart, so- wie Moglichkeiten, um Ausbruche zu verhindern. AbschlieBend werden Einsatzgebiete erortert, deren ErschlieBung durch UML in Zukunft geplant ist.
Abstract
The software User-Mode-Linux can be treaten from two different points of view. On the one side it is a user program and on the other hand it is an operating system. UML is part of the domain of system virtualization, but with the addition that its functionality differs from existing technologies. This system is started up by the user on a host system, just like a user program without root privileges. UML is executed without a virtualization layer. The architecture layer is the only modified part of the UML kernel which differs from common linux kernels. The major difference of this layer is the destination of communication. Requests generated by UML processes are not sent to the hardware, they are sent to the host kernel like a host user process. This modus operandi uniques the usability on linux host systems.
The first chapter covers fundamental components of an operating system beginning with the mode of operation of the Linux kernel and discrepancies of appointed architectures. Processes will be created on the host for own purposes by UML and thus process management will be deconstructed. The memory management will be also analyzed because UML as an operating system needs main memory and disk storage provided by the host. This chapter will be completed with an excursus describing the functionality of alternative virtualization technolgies.
The major part of this thesis covers functionality and integration of UML into a host system. Executing UML on a host can be implemented in the form of different models. Each model will be specified and qualified. Another section is the description how resources will be virtualized by UML.
In the last chapter of this thesis, procedures how a UML user can break out of UML and gain access to the host system are analyzed. To prevent break outs, counter measures will be explicated to protect the host against these attacks.
Kapitel 1 Grundlagen
1.1 Linux-Kernel
Der Kernel ist das Zentrum eines jeden Betriebssystems. Situiert ist der Kernel als Schicht zwischen Hardwareressourcen und Anwendungsprogrammen. Die durch die Hardware des Computers zur Verfugung gestellten Ressour- cen befinden sich im alleinigen Zugriff durch den Kernel. Diese Tatsache stellt die Grundlage fur den gleichzeitigen Betrieb mehrerer Anwendungs- programme dar. Programme benotigen, um ausgefuhrt zu werden, zur Laufzeit Rechenzeit und Ressourcen aus der Hardwareschicht. Wie schon erwahnt, kann nur der Kernel auf die Hardware zugreifen. Deshalb mussen Programme, um Ressourcen zugewiesen zu werden, Anfragen, wie z.B. das Lesen einer bestimmten Datei von der Festplatte, an den Kernel stellen, welcher diesen Auftrag ausfuhrt und das Ergebnis zuruckliefert. Der Kernel stellt nicht nur Ressourcen zur Verfugung, sondern auch Rechenzeit, die ein Programm benotigt, um ausgefuhrt zu werden.
1.1.1 Einleitung
Am Markt existieren unterschiedliche Betriebssysteme, wie etwa ,,Micro- soft Windows“, ,,Unix“, ,,Linux“ oder ,,OS/2“, um nur einige zu nennen. Demnach besitzen unterschiedliche Betriebssysteme auch unterschiedliche Kernel, deren Architekturen sich untereinander differenzieren.
Exokernel
Bei dieser Architektur werden Kernelfunktionalit&ten, die in anderen Archi- tekturen vom Kernel wahrgenommen werden, von den Anwendungspro- grammen wahrgenommen, die diese als Bibliothek beinhalten. Der Kernel selbst uubernimmt nur die Ressourcenverwaltung. Der Vorteil dieser Archi- tektur liegt in der Erweiterung, da diese an den Anwendungsprogrammen selbst und individuell fur ihre Einsatzzwecke vorgenommen werden kdnnen.
Nachteilig ist jedoch, dass Programme Aufgaben, wie die Verwaltung von Plattenblocken durch eigene Dateisysteme oder z.B. Netzwerksockets, selbst- standig implementieren miissen. Diese Art der Implementierung weist keine Sicherheitsliicken auf, da die Anwendungsprogramme mit ihren Betriebs- systemfunktionen im Usermode4 betrieben werden 12, S.19.
Der Exokernel existiert in drei unterschiedlichen Implementationen5, die auf der Exokernelarchitektur basieren. Diese Implementationen unter- scheiden sich anhand der eingesetzten Hardware. „Aegis“ findet Einsatz unter „DECstations und MIPS-Prozessoren, „Glaze“ fur experimentelle „SPARC“-basierte Multiprozessormaschinen und „Xok“, die neueste Implementation, kann auf Systemen mit ,,x86“-Prozessoren eingesetzt werden 17, S.12.
Mikrokernel
Der Mikrokernel beherbergt ausschliefilich Funktionalitaten wie ,, Message Passing“, „Virtual Memory“, „Scheduling“ und „Geratetreiber“. Zusatzli- che Funktionen sind in Serverprozessen enthalten, die im Benutzermodus ausgefuhrt werden. Serverprozesse unterscheiden sich nicht von gewohn- lichen Benutzerprozessen. Diese befinden sich im Usermode und stellen Funktionen, die nicht im Kernel enthalten sind, zur Verfugung.
Der Grund fur die Ausfuhrung der zusatzlichen Funktionen liegt in der Gewahrleistung der Sicherheit zum Einem als Schutz vor Manipulationen und zum Anderen durch die Einschrankung der Auswirkungen von Feh- lern auf den verursachenden Serverprozess. Der Kern ist das einzige Medium, welches auf die Hardwareressourcen zugreifen darf. Anforderungen an Hardwareressourcen durch ein Anwendungsprogramm werden an den Kernel gerichtet, welcher diese an den zustandigen Serverprozess weiterleitet und die Antwort uber den Mikrokernel an die Applikation zuruckliefert. Der Vorteil in diesem Client/Server-Modell liegt bei dem Einsatz in verteilten Betriebssystemen, da Serverprozesse nicht nur lokal vorhanden sein mussen und somit diese Ressourcen nicht redundant zu Lasten der Performance aus- gelegt werden mussen.
Monolithischer Kernel
Der monolithische Kernel beinhaltet im Gegensatz zu anderen Architekturen alle fur die Ausfuhrung eines Betriebssystems erforderlichen Funktionen. Es mussen somit keine Funktionen durch Benutzerprogramme aus dem Usermode bereitgestellt werden. Der Kernel beinhaltet sumtliche Treiber, die fur den Betrieb erforderlich sind. Der Nachteil liegt zum Einen darin, dass fehlerhafte Treiber auch den restlichen Kernel kompromittieren konnen. Ein weiterer Nachteil besteht darin, dass ein spateres Hinzufugen oder Entfernen des Treibers eine Neukompilierung aus den Sourcen erfordert6.
Eine modifizierte Variante dieser Kernelarchitektur wird unter Linux eingesetzt. Die Modifikation besteht darin, dass Treiber zur Laufzeit in Form von Modulen an den Treiber gebunden und wieder entfernt werden konnen. Diese Module werden im Kernelmode betrieben. Fehlerhafte Module wirken sich durch dieses Modell negativ auf den gesamten Kern aus, da diese auf den gesamten Kerneladressraum uneingeschrankte Rechte be- sitzen. Diese Variante ermoglicht jedoch, dass eine Neukompilierung des Kernels umgangen werden kann. Der wesentlichste Vorteil in dieser Kernelarchitektur liegt in der zum Vergleich anderer Technologien hohen Performance, da saomtliche Funktionen im Kernelmode ausgefuohrt werden und de- ren Kommunikation, die vollstaondig im Kernelmode ausgefuohrt wird, keine zusatzliche Interprozesskommunikation aufwanden muss.
Makrokernel
Der Makrokernel7 stellt eine Kombination aus Mikro- und monolithischem Kernel dar8. Im Vergleich zum Mikrokernel besitzt dieser mehrere Funk- tionen, die sich somit im Kernelmode befinden, womit ein Geschwindigkeits- vorteil gegenuber dem Mikrokernel erzielt werden kann, da weniger Kontext- wechsel erforderlich sind 25. Dieser Kernel verfugt jedoch nicht uber den Funktionsumfang eines monolithischen Kernels.
Beim Makrokernel werden nicht alle Treiber im Kernelmode betrieben und somit das Risiko reduziert, dass bei einem fehlerhaften Usermodetreiber der gesamte Kernel absturzt. Eine Regel, die besagt, welche Funktionen im Kernel vorhanden sind und welche extern im Usermode betrieben werden, existiert nicht.
1.1.2 Aufbau und Funktionsweise des monolithischen Kernels
Die Abbildung 1.1 zeigt den Aufbau und das Zusammenwirken der in einem Kernel enthaltenen Bestandteile bei monolithischer Kernelarchitektur.
Prozessverwaltung
Dieser Teil des Kernels ermoglicht es, einen oder mehrere Prozesse9 auf einer CPU auszufuhren. Pro vorhandenen CPU-Kern kann immer nur ein Prozess
Abbildung in dieser Leseprobe nicht enthalten
Abbildung 1.1: Aufbau des Linux-Kernels 27.
gleichzeitig ausgefuhrt werden. Jedoch findet ein Prozesswechsel durch den Kernel in sehr kurzen Zeitabstanden statt, sodass dies dem Benutzer durch seine trageren Sinnesorgane als Parallelbetrieb erscheint. Verfugt ein System uber mehrere CPU-Kerne, so konnen der Zahl der Kerne entsprechend gleich viele Prozesse gleichzeitig abgearbeitet werden.
Der Aufgabenbereich des Kernels liegt in der Erstellung und der Been- digung von Prozessen, der Kommunikation zwischen Prozessen untereinander, durch Signale und Pipes sowie dem Scheduling10 von Prozessen. Der Aufbau und die Funktionsweise von Prozessen wird intensiver im Abschnitt 1.2 behandelt.
Die Prozessverwaltung beinhaltet auch die Prozesserzeugung durch das Betriebssystem, welche auf folgende Weise erzeugt werden kann.
1. Zuweisung einer eindeutigen Prozesskennung zum neuen Prozess. Der primaaren Prozesstabelle wird ein neuer Eintrag hinzugefuagt.
2. Zuteilung von Speicherplatz fur den Prozess. Beinhaltet alle Elemente des Prozessabbilds. Die von der Art des Prozesses abhangige GroBe kann als Standardwert durch den Benutzer zum Zeitpunkt der Job- erstellung oder durch den Elternprozess an den Kernel uabergeben wer- den, sofern dieser den Prozess erzeugt.
3. Initialisierung des Prozesskontrollblocks, welcher die ID des Prozesses, die ID des erzeugenden Prozesses und Prozessorstatusinformationen enthalt, wobei bis auf „ProgramCounter“ und Systemstapelzeiger die Eintrage mit Standardwerten und Attributen versehen werden. Der Prozesszustand wird auf „bereit“ gesetzt.
Eine weitere Aufgabe der Prozessverwaltung liegt im Wechsel von akti- ven Prozessen. Der Prozesswechsel kann zu einem beliebigen Zeitpunkt erfol- gen, der entweder durch einen „Interrupt“, „Trap“ oder „Supervisor“-Aufruf eingeleitet wird.
Die Terminierung von Prozessen erfolgt in der Regel durch den Prozess selbst, in dem ein „Interrupt“ an den Kernel gesendet wird. Die Terminierung eines Prozesses kann auch durch seinen Vaterprozess veranlasst werden oder durch das Betriebssystem selbst.
Ein weiteres Aufgabengebiet ist die Interprozesskommunikation, die der Kommunikation von Prozessen untereinander dient, da diese in unterschied- lichen Adressraumen liegen und somit keinen direkten Zugriff zueinander erlangen konnen.
Die Prozessverwaltung ubernimmt auch die Verwaltung der Prozess- kontrollblaocke. Ein Prozesskontrollblock enthaalt saamtliche Informationen uber einen Prozess, die vom Betriebssystem fur die Steuerung des Prozesses benotigt werden. Diese Steuerinformationen sind unter 31, S.160 abgebil- det.
Speicherverwaltung
Die Speicherverwaltung bezieht sich auf den Hauptspeicher eines Computer- systems, da dieser zwischen Betriebssystem und den Prozessen des Systems aufgeteilt werden muss. Es wird zwischen virtuellen und physikalischen Adressraaumen unterschieden. Der physikalische Adressraum lokalisiert den gesamten Hauptspeicher. Die einzelnen Speicherbereiche des Hauptspeichers sind verschiedenen Prozessen zugeordnet. Der virtuelle Adressraum existiert separat fur jeden Prozess. Dieser enthalt die Adressen des eigenen Prozesses sowie die des Kernels.
Die Adressen des virtuellen Adressraumes referenzieren dabei auf Adres- sen des physikalischen Adressraums, deren Adressen unabhaangig von denen des virtuellen Adressraums sind. Virtuelle Adressraaume ermoaglichen eine effizientere Ausnutzung des Hauptspeichers. Betriebssysteme, die die par- allele Ausfuhrung mehrerer Prozesse unterstutzen, konnen den gesamten Prozess, aber auch Teile unterschiedlicher Prozesse im Hauptspeicher hal- ten. Ein weiterer Vorteil ist, dass im Prozess keine Funktionen vorhanden sein mussen, die Codefragmente auf andere physikalische Datentrager wie etwa auf die Festplatte auslagern. Selbst wenn der Code an einer anderen Adresse im Hauptspeicher eingelagert wird, stellt dies kein Problem dar.
Der Kernel bietet Schutzfunktionen an, um zu vermeiden, dass Prozesse (un)gewollt auf Speicherbereiche im Hauptspeicher referenzieren, die zur Laufzeit von anderen Prozessen belegt sind. Eine weiterfuhrende Erlauter- ung findet sich im Abschnitt 1.3.1 wieder.
Dateisysteme
Uber die Hardware des Systems legt der Kernel ein strukturiertes Datei- system. Diese Datei-Abstraktion findet sich im gesamten Betriebssystem wieder. Linux unterstutzt unterschiedliche Dateisysteme. Fur blockorien- tierte Gerate, wie z.B. die Festplatte, werden Systeme wie ext3, reiserfs, oder auch fat verwendet. Informationen liber Kernelkonfigurationen so- wie die Systemzustande werden durch das in Linux vorhandene proc-Datei- system in Dateien dargestellt.
Geratesteuerung
Jedem Betriebssystem unterliegen Hardwarekomponenten, sei es in realer oder virtualisierter Form. Die Ausfuhrung des Betriebssystems und der Bedarf von Ressourcen durch Programme, wie z.B. das Lesen von Tastatur- eingaben, verlangen vom Betriebssystem eine Steuerung dieser Komponen- ten. Ein System besteht aus unterschiedlichen Hardwarekomponenten, die eigenstandige Aufgaben ubernehmen und daher unterschiedlich bedient werden mussen. Die Tatsache, dass eine Vielzahl an unterschiedlichen Hardwarekomponenten existieren, lasst darauf schlieBen, dass Geratetreiber groBteils vom Hersteller entwickelt werden. Die Funktionsweise von Treibern werden im Abschnitt 1.4.2 intensiver erlautert.
Netzwerkbetrieb
Neben Block- und Zeichengeratetreiber existieren auch Netzwerkgeratetrei- ber im Linuxkernel. Diese Treiber steuern die Netzwerkschnittstellen eines Computers. Neben den physischen Netzwerkkarten wird auch eine virtuelle Netzwerkkarte11 angesteuert, die vom Kernel simuliert wird. Der Grund far die Existenz einer solchen Softwareschnittstelle liegt darin, dass Pro- zesse auch die Netzwerkschicht zur Kommunikation untereinander verwen- den konnen.
Ein erster Unterschied zu Block- und Zeichengeraten liegt darin, dass Netzwerkschnittstellen nicht in Form einer Datei im Betriebssystem repraasen- tiert werden, wie das bei einer Festplatte mit beispielsweise ,,/dev/hda1“ der Fall ist. Ein zweiter Unterschied im Gegensatz zum Blocktreiber liegt darin, dass dessen Ausfahrung nicht ausschlieBlich vom Linuxkernel initiiert wird, sondern dieser bei einkommenden Netzwerkpaketen dies dem Kernel durch Interrupts signalisieren muss. Diese Pakete der Netzwerkschicht des Kernels sind unabhangig von den eingesetzten Netzwerkprotokollen12 der User- programme sowie der darunter liegenden Hardwareprotokolle13.
Programme, welche Netzwerkaktivitaten verfolgen, mussen, um Netz- werkpakete senden und empfangen zu konnen, eine Verbindung zum Netz- werkkartentreiber aufbauen. Diese Verbindung wird auch als Socket be- zeichnet. Eine Netzwerkschnittstelle kann eine Vielzahl von Sockets gleich- zeitig aufweisen. Eine Applikation baut vor dem Senden von Informationen oder der Bereitschaft des Empfanges von Paketen eine Socketverbindung auf. Ein Socket kann jedoch nicht vom Kernel zu einem Benutzerprozess aufgebaut werden. Dieses „Linux Netzwerk Subsystem'1 ist in vier Schichten untergliedert 22, S.41.
Ein Prozess, welcher Daten als Netzwerkpakete sendet, muss den ,,sys- sockcall“-Systemcall auslosen. Das Senden von Paketen durch Systemcalls ist der einzige Weg, damit Pakete uber eine Netzwerkschnittstelle in das Socket-Interface transportiert werden konnen. Je nach dem zugrunde- liegenden Ubertragungsprotokoll der Pakete wird die passende Socketimple- mentierung ausgefuhrt.
Das ,Netdevice Interface“ als nachfolgende Schicht organisiert die zu sen- denden Pakete durch Pufferung in einer Warteschlange, welche anschlieBend an den Treiber weitertransportiert werden. Diese Schicht bietet die Moglich- keit, Datenpakete nach bestimmten Kriterien, wie verwendetes Protokoll oder Sender- und Empfanger, zu filtern und diese in unterschiedliche Warte- schlangen aufzuteilen. Diese Warteschlangen werden unterschiedlich oft ab- gerufen, womit ,,Traffic Shaping' ermoglicht wird. Beim Empfang von Daten werden die Schichten in umgekehrter Reihenfolge ausgefuhrt, wobei fur diese Pakete ein eigener Puffer existiert.
Die letzte Schicht beinhaltet die Geratetreiber fur Netzwerkschnittstellen- karten. Dieser Treiber implementiert die Steuerung der Netzwerkkarten. Die von der ,,Netdevice“-Schicht empfangenen Pakete leitet der Treiber an die Schnittstellenkarte weiter, welche im finalen Schritt diese versen- det. Empfangene Pakete werden vom Treiber entgegengenommen und in die Warteschlange des ,,Netdevice-Interfaces“ weitergeleitet.
Scheduling
Wie im letzten Abschnitt erwahnt, kann immer nur ein Prozess pro CPU- Kern ausgefuhrt werden. Diese Gegebenheit verlangt vom Kernel einen Mechanismus, welcher die CPU-Rechenzeit zwischen allen Prozessen ver- teilt. Dieser Mechanismus wird vom Scheduler ubernommen. Unterschieden werden drei Arten des Schedulings, die in der Tabelle 1.1 aufgelistet sind.
Abbildung in dieser Leseprobe nicht enthalten
Tabelle 1.1: Arten des Schedulings 31, S.458.
Das kurzfristige Scheduling14 wird wahrend der Ausfuhrung des Betriebs- systems am haufigsten durchgefuhrt. Die Entscheidung, welcher Prozess als Nachstes Rechenzeit zugeteilt bekommt, ist ein wichtiges Kriterium fur die Performance eines Systems.
Unterschiedliche Betriebssysteme besitzen Scheduler, welche die Aus- wahl der Prozesse nach unterschiedlichen Kriterien handhaben. Scheduler in Betriebssystemen, die fur den Privatanwender gedacht sind, werden dazu optimiert, dass die Auswahl und die Dauer der Ausfuhrung auf interaktive Prozesse fokussiert wird, wahrend bei Serverbetriebssystemen eine effektive Nutzung der Rechenzeit im Vordergrund steht. Ein Prozess wird mit einer Prioritat versehen. Prozesse mit haherer Prioritat15 werden vom Scheduler mit einer graBeren Wahrscheinlichkeit ausgewahlt als jene mit niedriger Prioritaat. Ein Scheduler kann nicht erst alle Prozesse mit der hoachsten Prioritaat abarbeiten, da solange sich Prozesse mit dieser Prioritaat in der Warteschlange befinden, keine Prozesse mit niedriger Prioritat ausgefiihrt werden kannen und somit verhungern.
Scheduler benutzen unterschiedliche Algorithmen, welche die Auswahl des nachsten Prozesses bestimmen 31, S.467.
- FCFS (First Come First Served): Jener Prozess, der als Erstes in die Warteschlange kommt, wird ausgefiihrt. Der Scheduler ist einfach zu realisieren und ressourcenschonend, Prozesse werden jedoch nicht nach ihrer Dringlichkeit behandelt.
- Round Robin: Aus alien auszufuhrenden Prozessen wird per Zufall ein Prozess ausgwahlt. Das Problem ist, wie bei FCFS, dass theoretisch Prozesse nie zur Ausfuhrung ausgewahlt werden.
- SPN (Shortest Process Next): Prozesse, deren Ausfuhrung weniger Rechenzeit benotigt, werden bevorzugt. Existieren viele solche Prozesse, wird die Ausfuhrung von Prozessen mit langerer Rechenzeit stark benachteiligt.
- SRT (Shortest Remaining Time): Jener Prozess, der noch die kurzeste verbleibende Verarbeitungszeit aufweist, wird ausgewahlt. Kurze, aber wichtige Prozesse werden nicht bevorzugt, was aus Sicht des Benutzers einen extremen Performanceeinbruch bedeuten kann.
- HRRN (Highest Response Ratio Next): Jener Prozess wird ausgewahlt, welcher am laangsten zur Abarbeitung bereitsteht. Nachteile wie bei SRT.
1.2 Prozessmanagement
1.2.1 Prozesse vs. Threads
Bei Prozessen und Threads handelt es sich um keine Konkurrenzprodukte, welche das gleiche Ziel verfolgen. Ein Thread ist lediglich Bestandteil eines Prozesses, welcher die Ausfuhrung des Programmcodes vornimmt, wahrend der Prozess selbst die zur Ausfuhrung notwendigen Ressourcen bereitstellt.
Prozesse
Ein Programm, welches sich in Ausfuhrung befindet, wird als Prozess titu- liert. Jeder Prozess bekommt einen eigenen Adressraum zugewiesen, welcher bei ,,x86“-Architekturen 4 GB betr>. Davon erh< der Kernel 1 GB. Die Ausfuhrung eines Programmes fordert zahlreiche Ressourcen, wie unter Ab- bildung 1.2 dargestellt, die im Adressraum bereitgestellt sein mussen.
Jeder Prozess besitzt einen Prozessdeskriptor, in dem Informationen fur den Kernel zur Verwaltung des Prozesses abgelegt sind. Eine Erlauterung des Prozessdeskriptors findet sich im Abschnitt 1.2.2 wieder.
Zur Ausfuhrung des Programmes muss auch dessen Programmcode zur Verfugung stehen. Dieser kann in einer beliebigen (Hoch)sprache geschrie- ben werden und muss anschlieBend zu Maschinencode kompiliert werden. Variablen und Konstanten erhalten ebenfalls einen separaten fixen Speicher- bereich, da die Anzahl und GroBe dieser Objekte schon zum Programmstart- punkt bekannt sind und sich w&hrend der Laufzeit nicht ver&ndern.
Der n&chste Abschnitt ist der Heap. Dessen GroBe ist nicht statisch, sondern ver&ndert sich zur Laufzeit. Am Heap konnen Speicherbereiche
Abbildung in dieser Leseprobe nicht enthalten
Abbildung 1.2: Elemente eines Prozesses im virtuellen Adressraum bei 32- Bit-Architektur.
allokiert werden16. Dies wird vor allem dann benotigt, wenn der Prozess externe Dateien ladt oder dynamische Objekte17 anlegt, deren Anzahl und Grofie wahrend der Laufzeit durch externe Faktoren beeinflusst werden kann.
Der letzte Bereich ist der Stack, der ebenfalls uber eine variable Grofie verfugt. Im Gegensatz zum Heap liegt der Beginn des Stacks am Ende des Adressraums und wachst in des Heaps entgegengesetzte Richtung. Am Stack werden dynamische Speicherstrukturen, wie etwa Ubergabeparameter und Return-Werte von Funktionen abgelegt.
Threads
Der Thread ist die Einheit eines Prozesses, die fur die Ausfuhrung auf der CPU verwaltet werden 32, S.97. Aufgaben werden nicht durch den Prozess abgearbeitet, sondern durch seine Threads. Jeder Prozess besitzt nach seiner Generierung mindestens einen Thread, kann aber durchaus mehrere besitzen. Ein Thread befindet sich im Adressraum seines Prozesses und ver- wendet die davon zur Verfugung gestellten Ressourcen. Jeder Thread besitzt zusatzlich einen ,,ProgrammCounter“18, Register fur lokale Variabeln und einen eigenen Stack. Threads konnen untereinander auf ihre eigenen Ressourcen zugreifen.
Diese Tatsache stellt kein Sicherheitsrisiko dar, da jeder Prozess dem gleichen Programm entspringt und Eigentumer des gleichen Users ist. Der Vorteil in der gleichzeitigen Ausfuhrung mehrerer Threads liegt darin, dass in vielen Anwendungen samtliche Aktivitaten gleichzeitig zu erledigen sind. Es kann naturlich fur jede Aktivitat eine eigene Prozessinstanz mit nur ei- nem Thread vom Programm gestartet werden, jedoch benotigt das Erstellen eines Prozesses erheblich mehr Ressourcen als das Erstellen eines Threads, da der Prozess einen eigenen Adressraum braucht und samtliche Ressourcen angelegt werden mussen, was auch mit zusatzlichem Rechenaufwand verbunden ist.
Threads fuhren unterschiedliche Aktivitaten aus. Beispielsweise kann in einem Kalkulationsprogramm ein Thread eine Formel berechnen, wahrend ein weiterer, wenig rechenintensiver Thread die Tastatureingaben des Users verarbeitet. Befinden sich beide Threads in einem Prozess, kann die Anwen- dung beschleunigt werden, in dem sich beide Threads uberlappen. Stehen dem System mehrere CPU-Kerne zur Verfugung, kann die entsprechende Anzahl an Threads auch tatsauchlich parallel ausgefuuhrt werden.
1.2.2 Erstellen & Beenden von Prozessen
Erstellt wird ein neuer Prozess unter Linux unter anderem mit Hilfe von Systemcalls 28.
- fork() - Kindprozess unterscheidet sich lediglich in der PID und PPID vom Elternprozess.
- clone() - Kindprozess teilt sich den Adressbereich und Filetables des Elternprozesses.
- vfork() - Kind- und Elternprozess teilen sich einen gemeinsamen Adress- bereich. Der Elternprozess wird so lange suspendiert, bis der Kind- prozess beendet wurde, oder dieser wiederum einen Kindprozess er- zeugt hat.
Hierbei handelt es sich um ein Kopieren eines bereits existierenden Pro- zesses. Der neu erstellte Kindprozess teilt sich die Ressourcen mit seinem Vaterprozess. Durch die dabei entstehende Prozesshierachie hat jeder Prozess einen Vater und kann eines oder mehrere Kinder besitzen. Der Vater- prozess, welcher keinen Vorg&nger besitzt, ist der irnt-Prozess. Dieser wird im letzten Abschnitt des Bootvorganges gestartet.
Nach der erfolgten Ausfuhrung eines der oben angefuhrten Systemcalls handelt es sich beim Kindprozess um eine Kopie des Elternprozesses. Mit Hilfe des Systemcalls ,,exec()“ wird eine ausfuhrbare Datei in den Adressbereich des zuvor kopierten Prozesses geladen. Durch die Ausfuhrung des „exit“-Systemcalls wird der Prozess beendet und die von ihm belegten Res- sourcen werden freigegeben.
Die Tasklist ist eine doppelt verkettete Liste, die vom Kernel verwaltet wird. Jeder Knoten enthalt einen Prozessdeskriptor, welcher Informationen iiber seinen Prozess enthalt.
Prozessdeskriptor
Die Prozessinformationen, die in einem Prozessdeskriptor enthalten sind, konnen in 14 Bereiche unterteilt werden 29.
- State: Enthalt den aktuellen Zustand des Prozesses.
1. set_tast_state: Zustand eines bestimmten Prozesses.
2. set_current_state: Zustand des aktuellen Prozesses.
- Counter: Beinhaltet die Zeit in „Ticks“19 bis zum Scheduling und die dynamische Prioritat.
- Nice(priority): Enthalt statische Prioritat, die vom Scheduler verwen- det wird, um den Counter zu setzen.
- Need_resched: 1st dieses Bit gesetzt, muss ein Scheduling durchgefuhrt werden.
- Next_task: Verweist auf den nachsten Prozess in der Kette.
- Prev_task: Verweist auf den vorherigen Prozess in der Kette.
- Run_list: Liste der laufenden Prozesse.
- Verwandschaftsverhaaltnisse der Prozesse zueinander.
- TTY: Informationen zur Konsole.
- Thread: Informationen uber den Prozessstatus beim letzten Modus- wechsel sowie die Sicherung aller Prozessorregister.
- Fs: Enthalt dateisystemspezifische Informationen wie das aktuelle Ver- zeichnis zur Auflosung relativer Pfadnamen und das Wurzelverzeichnis zur Aufldsung absoluter Pfadnamen.
- File: Der Filedeskriptor zur Referenzierung einer gedffneten Datei.
- mm: Eigene Unterstruktur der Speicherverwaltung zwecks Ubersicht- lichkeit und Zeiger auf die virtuellen Speicherbereiche.
- Sig: Pointer auf die Signalbehandlungsroutinen des Prozesses.
Abbildung in dieser Leseprobe nicht enthalten
Abbildung 1.3: Prozesszustande und -ubergange unter Linux 16.
1.2.3 Prozesszustande
Der Linuxkernel unterscheidet zwischen funf Prozesszustanden, die in der „State“-Variable im Prozessdeskriptor des jeweiligen Prozesses abgelegt sind. Der Zustand ist fur den Scheduler ein wichtiges Kriterium, um festzustellen, ob ein Prozess zur Ausfuhrung bereit ist, bzw. gerade ausgefuhrt wird oder auf ein bestimmtes Ereignis wartet. Die Ubergange dieser Zustande sind in Abbildung 1.3 dargestellt. Die Erklarung der einzelnen Zustande im Detail befinden sich in Tabelle 1.2.
1.2.4 User- & Kernelmode
Fur die Ausfuhrung von Prozessen existieren unterschiedliche Privilegien- stufen, die durch die Hardwarearchitektur definiert werden. Die CPU in „x86“-Systemen bietet vier verschiedene Levels (Ringe), wobei Ring 0 samt- liche Rechte besitzt und Ring 3 im Vergleich zu den restlichen Ringen die wenigsten Rechte besitzt.
Von den meisten Betriebssystemen, wie auch unter Linux, wird nur die hochste Stufe far den Kernel-Mode (privilegierter Modus) und die niedrigste
Abbildung in dieser Leseprobe nicht enthalten
Tabelle 1.2: Prozesszustande unter Linux.
Stufe fur den User-Mode (unprivilegierter Modus) verwendet. Der Einsatz dieser Ringe ermoglicht es, den Zugriff auf Hardwareressourcen durch die Hardware zu regeln. AusschlieBlich Prozesse im Kernel-Mode konnen unein- geschrankt auf die Hardware des Systems zugreifen. Die Zugriffsrechte des Adressraums eines Prozesses werden unterteilt. Der Bereich 0-3 GB ist dem Prozess zugeordnet und dieser kann auf diesem Bereich im Usermode (Ring 3), unter dem ein Prozess standardmaBig betrieben wird, uneingeschrankt zugreifen. Im Bereich von 3 GB - 4GB konnen Zugriffe ausschlieBlich im Kernelmode erfolgen.
Benotigen Benutzerprozesse Zugriff auf Ressourcen, so kann dies nur erfolgen, wenn sich der Benutzerprozess im Kernelmode befindet. Dazu sendet dieser einen Systemcall an den Kernel. Dieser Systemcall enthaolt die Art des Zugriffes sowie eventuell benotigte Parameter. Wird die Durch- fuhrung des Systemcalls durch den Kernel erlaubt, wechselt der Benutzer- prozess vom Usermode in den Kernelmode. Im Kernelmode wird die auf- gerufene Funktion ausgefuhrt und anschlieBend wechselt der Prozess wieder in den eingeschrankten Usermode zuruck.
1.2.5 Interrupts
Interrupts stellen einen Mechanismus dar, mit dem Komponenten eines Computersystems die aktuelle Taskausfuhrung unterbrechen konnen. Es gibt unterschiedliche Komponenten, welche Interrupts auslosen 31, S.33. standardisierten Sprache zur Modellierung von Systemen.
[...]
[1] Nicht zu verwechseln mit der Abkurzung fur ,,Unified Modeling Language11, einer
[2] z.B. ,,../“
[3] Diese Schnittstellen sind simulierte Netzwerkschnittstellen, die durch einen VPN- Tunnel mit einer verbunden sind.
[4] Wird im Abschnitt 1.2.4 erlautert.
[5] Das Betriebssystem ,,ExOS“, welches auf ,,UNIX“ basiert, setzt die Kernel ,,Aegis“ und ,,Xok“ ein.
[6] Es nicht moglich, Treiber direkt in die Binardatei des Kernels zu kopieren.
[7] Wird auch als Hybridkernel bezeichnet.
[8] Diese Kerneltechnologie wurde unter Windows NT 4.0 eingesetzt.
[9] Der Linuxkernel in der aktuellen Version 2.6 unterstutzt den Betrieb von mehreren Prozessen gleichzeitig.
[10] Algorithmus zur Auswahl eines Prozesses, welcher als nachster lauft [32, S.148]. Wird genauer unter Abschnitt 1.1.2 behandelt.
[11] Diese Device umfasst einen IP-Adressbereich von 127.0.0.1 bis 127.255.255.254 und kann alternativ uber ,,localhost“ kontaktiert werden.
[12] z.B. IP, IPX.
[13] z.B. Ethernet, Token-Ring, Fiber Distributed Data Interface (FDDI).
[14] Dieser Scheduler wird auch als ,,Dispatcher bezeichnet [31, S.461].
[15] z.B. Musikplayer.
[16] C stellt dazu die Funktion ,,malloc()“ bereit.
[17] Unter Java werden solche Objekte mit dem ,,New“-Operator angelegt.
[18] Gibt an, welcher Schritt als Nachstes ausgefuhrt wird.
[19] 1 ,,Tick“ sind 10 ms.
-
Laden Sie Ihre eigenen Arbeiten hoch! Geld verdienen und iPhone X gewinnen. -
Laden Sie Ihre eigenen Arbeiten hoch! Geld verdienen und iPhone X gewinnen. -
Laden Sie Ihre eigenen Arbeiten hoch! Geld verdienen und iPhone X gewinnen. -
Laden Sie Ihre eigenen Arbeiten hoch! Geld verdienen und iPhone X gewinnen. -
Laden Sie Ihre eigenen Arbeiten hoch! Geld verdienen und iPhone X gewinnen. -
Laden Sie Ihre eigenen Arbeiten hoch! Geld verdienen und iPhone X gewinnen. -
Laden Sie Ihre eigenen Arbeiten hoch! Geld verdienen und iPhone X gewinnen. -
Laden Sie Ihre eigenen Arbeiten hoch! Geld verdienen und iPhone X gewinnen. -
Laden Sie Ihre eigenen Arbeiten hoch! Geld verdienen und iPhone X gewinnen. -
Laden Sie Ihre eigenen Arbeiten hoch! Geld verdienen und iPhone X gewinnen. -
Laden Sie Ihre eigenen Arbeiten hoch! Geld verdienen und iPhone X gewinnen. -
Laden Sie Ihre eigenen Arbeiten hoch! Geld verdienen und iPhone X gewinnen. -
Laden Sie Ihre eigenen Arbeiten hoch! Geld verdienen und iPhone X gewinnen. -
Laden Sie Ihre eigenen Arbeiten hoch! Geld verdienen und iPhone X gewinnen. -
Laden Sie Ihre eigenen Arbeiten hoch! Geld verdienen und iPhone X gewinnen. -
Laden Sie Ihre eigenen Arbeiten hoch! Geld verdienen und iPhone X gewinnen. -
Laden Sie Ihre eigenen Arbeiten hoch! Geld verdienen und iPhone X gewinnen. -
Laden Sie Ihre eigenen Arbeiten hoch! Geld verdienen und iPhone X gewinnen. -
Laden Sie Ihre eigenen Arbeiten hoch! Geld verdienen und iPhone X gewinnen.