Privilegienstufe (CPU)
Privilegienstufe (CPU) - Privilegierungs-Sicherheitsstufe des gerade laufenden Programmcodes
Beschreibung
Die Privilegienstufe (CPU (privilege level) bezeichnet (im Umfeld der Betriebssystem-Programmierung und des Multitaskings) eine Privilegierungs- bzw. Sicherheitsstufe des gerade laufenden Programmcodes
- Es handelt sich um eine Funktion der Hardware, durch die der auf der CPU nutzbare Befehlssatz und der verwendbare Speicherbereich dynamisch eingeschränkt werden kann
- Die Nutzung von Privilegierungsebenen ist sinnvoll, um die Hardware zu abstrahieren und um Prozesse voneinander und vom Betriebssystem und Treibern abzuschotten
Je nach Prozessorarchitektur wird die Privilegienstufe auch Ring, Schutzring oder Domain genannt
- Architekturen (Privilegienmodelle)
Während manche Architekturen wie x86 sehr viele Privilegienstufen besitzen, existiert bei anderen Architekturen nur eine Zweiteilung
- Benutzermodus (user mode)
- Systemmodus bzw. Kernelmodus (kernel mode)
x86

Intel-80286-kompatible Prozessoren unterscheiden vier Privilegierungsstufen: Ring 0, 1, 2 und 3
- Dabei stellt Ring 0, genannt "supervisor mode", die höchste Privilegierungsstufe dar, die bis zur Stufe 3 (Ring 3) immer weiter eingeschränkt wird
- Beispiele für Maschinenbefehle, die im Ring 0, jedoch nicht im Ring 3 ausgeführt werden dürfen, sind z. B. "cli" und "sti"
- Mit diesen Anweisungen wird die Behandlung von (maskierbaren) Hardwareinterrupts ab- bzw. eingeschaltet
- Ursprünglich waren die Ringe für den Kernel (Ring 0), Treiber (Ring 1), Systemdienste (Ring 2) und Anwendungsprogramme (Ring 3) vorgesehen
Um Prozesse in einem geschützten Bereich (Ring > 0) ablaufen zu lassen, wird der physikalische Arbeitsspeicher in virtuelle Speicherseiten aufgeteilt
- Zu jeder Speicherseite existiert eine Tabelle, in der unter anderem gespeichert ist, in welchem Level (Ring) der Programmcode, der innerhalb dieser Speicherseite gespeichert ist, ausgeführt wird
- Diese Auswertung nimmt die MMU meist extern vor
Wechsel zwischen den Ringen
Für einen Wechsel des Rings stehen drei Gate-Typen zur Verfügung, die bei ihrer Verwendung unterschiedlich viel Rechenzeit in Anspruch nehmen, da jeder Wechsel von einem Ring zum anderen auch einen Kontextwechsel zumindest einiger Zustände in der CPU darstellt:
- Call-Gates für den direkten Aufruf von Programmcode aus höheren Privilegierungsebenen
- Das Call-Gate bestimmt dabei, an welcher Stelle und mit welchen Privilegien der aufgerufene Programmcode laufen wird
- Aus Sicherheitsgründen wird hierbei dem Programmcode aus der höheren Privilegierungsebene ein eigener Stapel zugewiesen, die Aufrufparameter vom Stapel des aufrufenden Codes werden in den neuen Stapel kopiert
- Im Übrigen läuft der privilegierte Code im Kontext des aufrufenden Codes
- Interrupt-Gates werden zum einen beim Auslösen eines so genannten Software-Interrupts verwendet, aber auch Hardware-Interrupts erfordern ein Interrupt-Gate
- Zusätzlich zu allen Schritten, die beim Benutzen eines Call-Gates durchgeführt werden, wird zusätzlich das Flags-Register auf dem Stapel gespeichert und weitere Interrupts bis zur Rückkehr der Interrupt-Routine gesperrt
- Task-Gates erlauben die Kontrolle an einen anderen Prozess abzugeben
- Dies stellt die aufwändigste Form eines Kontextwechsels dar, da hier der vollständige Prozessorzustand des aufrufenden Prozesses gespeichert und des aufgerufenen Prozesses geladen werden muss
Betriebssysteme auf x86
Die verbreiteten Betriebssysteme für x86 Linux und Windows (sowie macOS für x64 und DOS mit EMM386.EXE-Speichermanager) nutzen lediglich zwei der vier möglichen CPU-Ringe
- Im Ring 0 werden der Kernel und alle Hardwaretreiber ausgeführt, während die Anwendungssoftware im unprivilegierten Ring 3 arbeitet
- Damit bleibt die Portabilität des Betriebssystems auch auf Prozessorarchitekturen gewährleistet, die nur zwei Privilegierungsstufen unterscheiden können. OS/2 benutzt allerdings Ring 2 für Grafiktreiber. Eine speziell angepasste Version des Speichermanagers EMM386 aus dem Entwicklungskit für DOS Protected Mode Services (für Novell DOS 7, OpenDOS 7.01 und DR-DOS 7.02 und höher) lässt DPMS auf Ring 1 statt auf Ring 0 laufen und erleichtert so die Fehlersuche bei Software, die DPMS nutzt
Manche Virtualisierungslösungen verwenden auch Ring 1
- Hierbei wird der Betriebssystemkern aus Ring 0 in Ring 1 verschoben, der Hypervisor residiert dann als darüberliegende Schicht in Ring 0 und verwaltet einen oder mehrere in Ring 1 laufende Betriebssystemkerne
- Dies kann allerdings auch durch Rootkits ausgenutzt werden, um Schadcode unbemerkt vom Anwender auf dem Ring 0 ausführen zu lassen (siehe auch Virtual Machine Based Rootkit)
Ring 0 (Kernel-Mode)
Im innersten Ring (höchste Berechtigungsstufe; privilegierte Ebene; System-Ebene; Kern-Ebene) läuft meist das Betriebssystem, evtl. sogar nur dessen Kernel und damit dessen Bestandteile wie Prozessverwaltung, Speicherverwaltung, Geräteverwaltung, Dateisysteme und Schnittstellen zur Hardware
- Das Betriebssystem "darf alles", insbesondere direkte Hardwarezugriffe und das Eingreifen in die RAM-Bereiche anderer Prozesse
- Je nach Aufbau des Kernels werden Treiber auch in Ring 0 ausgeführt, was bei den meisten Betriebssystemen der Fall ist
Code auf dieser Ebene darf..
- alle CPU Anweisungen ausführen
- auf jeden Speicherbereich zugreifen
- auf E-/A-Geräte zugreifen (über Treiber)
Ring 1 und 2
Diese Ringe sind zwischen Kernel- und Benutzermodus
- Programme, die in dieser Stufe laufen, dürfen daher zwar weniger als der Kernel, aber mehr als Programme im Benutzermodus
- Da diese Ringe jedoch in vielen anderen Prozessorarchitekturen nicht vorhanden sind, werden sie bei den meisten Betriebssystemen nicht genutzt - so verwenden z. B
- diverse Unix-Systeme, Windows NT und Linux dasselbe Kernel-Design auf einer Vielzahl unterschiedlicher Befehlssatzarchitekturen, von denen die meisten nur einen privilegierten Modus (Kernelmodus, bei x86 Ring 0) und einen unprivilegierten Modus (Benutzermodus, bei x86 Ring 3) bieten
Ein Beispiel für ein Betriebssystem, das Gerätetreiber im Ring 2 ausführt, ist OS/2 auf der 32-Bit-x86-Architektur IA-32.
Ring 3 (User-Mode)
Anwendungsprogramme sind üblicherweise auf den äußersten Ring beschränkt (niedrigste Berechtigungsstufe)
- Für Operationen, welche einen Hardwarezugriff erfordern, müssen Anwendungsprogramme Betriebssystem-Dienste beauftragen
Ring 1 (Hypervisor-Modus)
Um die Verwendung von Hypervisoren zu vereinfachen, führen neuere CPUs von Intel und AMD einen neuen "Ring -1" ein, so dass der Betriebssystemkern in Ring 0 verbleibt, während der Hypervisor als darüberliegende Schicht in Ring -1 residiert
- Dabei verwaltet er einen oder mehrere Betriebssystemkerne in Ring 0
Ring 2 (Systemverwaltungsmodus)
Da moderne Systeme immer komplexer wurden, begannen CPUs ab dem Intel 386SL einen Systemverwaltungsmodus zu implementieren, der, firmwareähnlich, grundlegende "interne" Hardwarefunktionalität implementierte
- Dieser wird unter anderem für Systemereignisse, Temperatur- und Energieverwaltung, SMBIOS, ACPI und Sicherheitsfunktionen verwendet
Ring 3 (Intel Management Engine / AMD Platform Security Processor)
Seit 2008 besitzen moderne Computer zudem ein unsichtbares, vollständig unabhängiges System mit nicht genau bekannter Funktionalität, mit noch höheren Privilegien, das selbst im "ausgeschalteten" Zustand weiterläuft
- Auf Intel-Systemen ist dies die Intel Management Engine, und auf AMD-Systemen der Platform Security Processor
Umsetzung
Der Befehlssatz wird für unprivilegierte Prozesse (userspace oder userland) derart eingeschränkt, dass sie nicht direkt auf die Hardware zugreifen können und sich auch nicht aus ihrer Privilegierungsebene befreien können
- Der Zugriff auf den Speicherbereich anderer Prozesse wird meist durch Speichervirtualisierung verhindert
- Somit wird gewährleistet, dass Programmcode in niedrigeren Privilegienstufen nicht eigenmächtig auf Programmcode oder Daten des Kernels und anderer Systemdienste in höheren Privilegienstufen zugreifen kann
- Die gleiche Speichervirtualisierung wird üblicherweise auch eingesetzt, um unterschiedliche Prozesse voneinander zu isolieren
- Da die unprivilegierten Prozesse auf Hardware nicht direkt zugreifen können, existieren sogenannte "Gates", mit denen Programmcode aus höheren Stufen Programmcode aus niedrigeren Stufen aufrufen kann, insbesondere ist so die Programmierschnittstelle des Kernels erreichbar, um die notwendigen Aktionen anzufordern
In der CPU und ggf. MMU müssen Schaltungen bestehen, die bei jedem Befehl bzw. Speicherzugriff prüfen, ob dieser in der aktuellen Privilegienstufe erlaubt ist
- Falls ein Prozess etwas nicht Erlaubtes durchführen möchte, wird er unterbrochen und eine Betriebssystem-Routine aufgerufen, deren Aufgabe es ist, entsprechend zu reagieren
Die meisten Prozessor-Architekturen bieten mindestens zwei Privilegienstufen: Programmcode in der höchstprivilegiertesten Stufe befindet sich im Kernelmodus (engl. "kernel mode"), Kernelraum (engl. "kernel space") oder ist Superuser-Code (engl. "super user code") - alle anderen im Benutzermodus (engl. "user mode") oder Benutzerraum (engl. "user space")
Ablauf eines Betriebssystemaufrufs
Ein (mit niedriger Berechtigung laufender) Prozess wählt durch geeignetes Setzen von CPU-Registern und Speicherbereichen die auszuführende Funktion des Betriebssystems und setzt die benötigten Parameter
- Anschließend löst er per CPU-Befehl einen Softwareinterrupt aus
- Der Prozess wird dadurch unterbrochen, die CPU wechselt in eine höhere Privilegienstufe ("Kernel mode") und setzt die Ausführung mit einer speziellen Betriebssystem-Routine fort
- Diese sichert zunächst weitere (CPU-)Zustände, die nicht von der CPU selbst im Rahmen des Softwareinterrupts bereits gesichert wurden, um beispielsweise freie Register für das eigene Ablaufen zu haben
- Anschließend agiert sie gemäß dem angeforderten Auftrag: Sie übergibt ihn an den zuständigen Treiber, reiht ihn in eine Warteschlange zur Abarbeitung durch einen Kernel-Thread ein oder kann evtl
- den Auftrag selbst ausführen
- In den ersten beiden Fällen wird anschließend meist ein vollständiger Kontextwechsel zu einem anderen Prozess durchgeführt, da der aufrufende Prozess erst weiter laufen kann, wenn das Betriebssystem den Auftrag vollständig abgearbeitet hat
- Sobald der Auftrag vollständig abgearbeitet wurde, legt die Betriebssystem-Routine die Rückgabewerte in die Speicherbereiche des Prozesses ab und vermerkt ggf. weitere Rückgabewerte für bestimmte CPU-Register in dessen Prozesskontext
- Der anfordernde Prozess wird als "bereit" markiert und später im Rahmen des regulären Schedulings wieder (mittels Kontextwechsel) fortgesetzt: Eine spezielle CPU-Instruktion schließt den Kontextwechsel ab, die CPU "kehrt aus dem Softwareinterrupt zurück", wodurch die CPU wieder in den User-Mode (niedrigste Privilegienstufe) zurück wechselt und die Ausführung des niedrig-berechtigten Prozesses direkt nach der Unterbrechungsstelle fortsetzt