Unternehmen sollten nicht zu viel in Windows investieren, denn bei Microsoft zählt es zu den Auslaufmodellen. ZDNet zeigt, dass die Migration zu Midori einen Bruch bedeutet, mit dem Microsoft und seine Anwender zu kämpfen haben werden.
Anfang des Monats gab Jonathan S. Shapiro[1] überraschend bekannt, dass er seine Arbeit am Betriebssystem Coyotos[2] und der Sprache BitC[3] komplett einstellen wird, denn er hat bei Microsoft angeheuert[4], um am Midori-Projekt[5] mitzuarbeiten. Wenn Microsoft einen so hochkarätigen Entwickler anheuert, zweifelt niemand ernsthaft mehr daran, dass Midori vom Forschungsprojekt Singularity[6] zum neuen kommerziellen Betriebssystem von Microsoft aufgestiegen ist.
Windows ist somit zum Auslaufmodell geworden. Das bedeutet nicht, dass der Name Windows verschwindet. So hat beispielsweise Mac OS X mit seinem "Vorgänger" Mac OS 9 technisch nichts zu tun. Trotzdem wurde der Name Mac OS beibehalten.
Auch wenn Midori frühestens in etwa fünf Jahren Marktreife erreichen wird, ist es an der Zeit, sich schon einmal damit vertraut zu machen, dass die Tage von Windows gezählt sind. Das neue Betriebssystem wird bisherige Windows-Programme nicht mehr ausführen können. Eine Rückwärtskompatibilität soll nur über Virtualisierung erreicht werden.
Damit Midori überhaupt erfolgreich werden kann, muss Microsoft auch einiges an Anwendungsprogrammen, etwa Office und den Internet Explorer, auf Midori portieren. Gleiches gilt für Serverdienste, zum Beispiel Exchange und SQL-Server. Dass diese Portierungen einen extremen Aufwand bedeuten, der selbst Microsoft an die Grenzen seiner Leistungsfähigkeit bringt, ist unmittelbar klar.
Es stellt sich die Frage, warum Microsoft Windows aufgeben und mit einem ganz neuen Betriebssystem seine Marktführerschaft verteidigen will. Denn dabei besteht die konkrete Gefahr, die Marktführerschaft einzubüßen, wenn Midori keine breite Akzeptanz findet.Realistisch betrachtet hat Windows gleich eine Reihe von Problemen, die die Weiterentwicklung schwierig machen. Das zeigt sich zum Beispiel daran, dass Windows XP erst mit Windows 7 einen "würdigen" Nachfolger bekommt. Windows Vista wird von vielen Anwendern als Beta-Version angesehen, die mit Windows 7 endlich RTM-Qualität erlangt. Die heutigen, auf Windows NT basierenden Windows-Versionen kranken vor allem an drei Dingen:
- Modularität: Schon 1993 beim Erscheinen von Windows NT staunte die Fachwelt, als es hieß, das neue Windows wäre nur mit dem gesamten grafischen Subsystem hochzufahren. Da Windows NT für damalige Verhältnisse mit 16 MByte recht große Ansprüche an den Hauptspeicher stellte, war es insbesondere als Serverbetriebssystem vorgesehen. Auf Servern ist es üblich, nur eine Textkonsole zu starten. Das grafische Subsystem kann man eventuell später hochfahren.
Windows NT krankte von Anfang an daran, dass die einzelnen Komponenten viel zu direkt miteinander interagierten. War eine Funktion nicht schnell genug, so ging der Entwickler kurz zum Kollegen ins Büro, und die beiden vereinbarten eine Methode, wie man das Problem lösen kann. Meist endete das darin, dass sich zwei Komponenten gegenseitig direkt aufrufen, die nach dem "Speed-Tuning" nur gemeinsam oder gar nicht lauffähig sind. So wurde aus Dave Cutlers[7] Microkernel-Konzept[8] der Monolith[9] Windows NT, später wurde dafür der Marketingbegriff Hybrid-Kernel[10] geboren.
Das hat sich bis heute nicht geändert. Windows XP verfügt zwar über eine Recovery Console, die tatsächlich ohne Grafik läuft. Allerdings kann man das Netzwerk nicht starten. Windows Server 2008 kommt mit einer Textmodus-Mogelpackung, die sich Server Core nennt. Aber auch in dieser Version muss das komplette Grafiksubsystem gestartet werden. Einfache Win32-Anwendungen wie Notepad laufen ohne Probleme. Außerdem können viele Serverdienste nicht oder nur eingeschränkt genutzt werden, da sie eine Administration über ein GUI-Frontend auf der lokalen Maschine benötigen. - Erblasten: Anders als Unix ist Windows mit den Jahren immer größer geworden. Dieser Ballast hat sich dadurch angesammelt, dass Microsoft immer wieder neue Techniken implementiert hat, die sich hinterher als nutzlos oder obsolet herausstellten. Dazu gehören beispielsweise MTS[11] oder MSMQ[12]. Diese Technologien müssen jedoch von Version zu Version mitgeschleppt werden, um die Rückwärtskompatibilität zu wahren. Heute nutzt man sie kaum noch. Das gleiche Schicksal wird COM ereilen, da Microsoft nun empfiehlt, .NET-Code statt COM-Komponenten zu entwickeln.
Unter Erblasten müssen auch strategische Fehlentscheidungen bei der Entwicklung von Windows bezeichnet werden. Dazu die zählt die Registry, die für einen Großteil der Windows-Performanceschwäche verantwortlich ist. Config-Files können das gleiche leisten und bremsen das System nicht aus. - Security: Erblasten und mangelnde Modularität sind sicherlich ein spezifisches Problem von Windows. Security hingegen ist ein Problem, das alle modernen Betriebssysteme haben. Pufferüberläufe und Andockpunkte für Rootkits gibt es bei Unix-Betriebssystemen genauso wie bei Windows. Mit Midori will Microsoft das jetzt grundsätzlich ändern.
Managed Code löst zwei Hauptprobleme für Angriffe auf heutige Betriebssysteme. Eins davon ist der Pufferüberlauf. Historisch gesehen wurden Pufferüberläufe absichtlich eingebaut, denn eine Überprüfung der Pufferlänge kostete noch in den 80er Jahren spürbar Rechenzeit. Wenn ein API einen String von maximal 80 Zeichen akzeptierte, dann wurde das in der Dokumentation so festgehalten. Der Nutzer eines API hatte sich an die 80 Zeichen zu halten und die Länge gegebenenfalls zu überprüfen.
Diese Überprüfung musste beispielsweise stattfinden, wenn der betreffende String aus einer Benutzereingabe stammte. Weglassen konnte man sie hingegen, wenn der String aus einer Konstante kleiner 80 Zeichen bestand. So konnten Programmierer schnellen Code entwickeln. Eine Überprüfung fand nur statt, wenn sie notwendig war.
Da auch die besten Programmierer nicht perfekt sind, wurden Puffergrößen nicht immer überprüft, obwohl ein Sicherheitsrisiko bestand. Malwareprogrammierer fanden schnell Möglichkeiten, Puffer so geschickt überlaufen zu lassen, dass die Rücksprungadresse auf dem Stack mit einem von der Malware gewählten Wert überschrieben wurde. Interessant dabei ist, dass dafür das Unterschieben von manipulierten Datendateien wie Bilder, Audio und Video ausreicht. So lässt sich Malware durch das Betrachten einer Webseite ganz ohne Skripts und sonstigem Programmcode einschleusen.Schon seit Mitte der 90er Jahre sind die Betriebssystemhersteller dabei, bei allen APIs Puffer vor einem Überlauf zu sichern. Wie man jedoch immer wieder in Security-Bulletins nachlesen kann, werden auch heute noch regelmäßig Sicherheitslücken gefunden, die einen Pufferüberlauf ausnutzen. Die Häufigkeit von Pufferüberläufen in Sicherheitswarnungen nimmt zwar ab, dennoch kann man nicht von einer Entwarnung reden.
Managed Code lässt keine Pufferüberläufe zu. Zu jedem Objekt gehört seine Länge in Bytes. Beim Arbeiten mit Objekten wird jedes Mal überprüft, ob die Längenbeschränkung eingehalten wird, selbst wenn das nicht nötig wäre. Das führt dazu, dass Managed Code zum Teil deutlich langsamer ist als Unmanaged Code. So ist zum Beispiel der folgende C-Code als sicher einzustufen:
const char* const yesno[2] = {"No", "Yes"];
char answer[4];
int condition;
if ( ... ) condition = 1; else condition = 0;
strcpy(answer, yesno[condition]);
Die grundsätzlich unsichere Funktion strcpy kann in diesem Fall verwendet werden, weil sichergestellt ist, das answer nur Yes oder No annehmen kann. Dafür ist answer mit vier Bytes, nämlich drei Zeichen und dem Nullterminator, ausreichend dimensioniert. In einer Managed-Code-Umgebung bekommt der obige Code jedoch in etwa folgendes Äquivalent in C:
const char* const yesno[2] = {"No", "Yes"];
const int maxlen = 4;
char answer[maxlen];
int condition;
if ( ... ) condition = 1; else condition = 0;
if (strlen(yesno[condition]) >= maxlen )
errorHandler();
else
strcpy(answer, yesno[condition]);
Diesen zusätzlichen Code kann ein Optimizer meist nicht ganz ausmerzen. Das gilt insbesondere dann, wenn die Definition des String-Arrays yesno in einem anderen Modul steht als der Rest des Beispielcodes.
Anders als oft angenommen ist Managed Code nicht deswegen langsamer, weil der Sourcecode zunächst in einen Bytecode und erst später auf dem Zielsystem in Native Code übersetzt wird. Im Gegenteil, ein Just-In-Time-Compiler kann spezifische Befehlssatzerweiterungen, zum Beispiel SSE2, SSE4.2 oder 3DNow, ausnutzen. Die geringere Ausführungsgeschwindigkeit kommt fast ausschließlich von den redundanten Überprüfungen.
Der zweite Sicherheitsvorteil resultiert daher, dass Managed Code grundsätzlich keine Pointer, sprich direkte Referenzen auf Hauptspeicher zulässt. Fehler im Umgang mit Pointern bedeuten bei Usermode-Code, dass das jeweilige Programm abstürzt. Im Kernel-Mode bedeuten sie meist den Absturz des gesamten Systems. Es können sich aber auch wesentlich hinterhältigere Probleme einschleichen, etwa Inkonsistenzen im Filesystem oder in Datenbanken. Auch dieser Sicherheitsgewinn wird mit einem Performancenachteil bezahlt.
Wenn Anwender nur Managed Code ohne Pointer starten können, dessen Puffergrenzen immer überprüft werden, dann ist es allerdings überflüssig, dass der Prozessor überhaupt noch Usermode-Code ausführt. Bei x86-Prozessoren bedeutet das, das Managed Code sicher genug ist, um im Ring 0 ausgeführt zu werden. Unmanaged Usermode-Code läuft im wesentlich langsameren Ring 3.
Dadurch dass der Bytecode in einen nativen Code überführt und Hauptspeicher immer korrekt über APIs anfordert wird, kann man auf die Möglichkeiten der Hardware-MMU (Memory Management Unit[13]) eines Prozessors verzichten. Die Umwandlung von logischen in physische Speicheradressen mittels Page Tables[14], Page Walk Caches und TLBs (Translation Lookaside Buffer[15]) kann vollständig entfallen. Da der Just-In-Time-Compiler nur unpriviligierte Befehle erzeugt, braucht die CPU den ausgeführten Code nicht auf Exceptions aufgrund von Befehlen wie CLI, IN oder OUT zu checken. Auf diese Weise können Anwenderprogramme mit der Geschwindigkeit von Kernelmode-Code ausgeführt werden. So kann man den Performanceverlust von Managed Code zu einem großen Teil wieder wettmachen.
Heutiger Managed Code des .NET-Frameworks von Windows läuft im Usermode ab. Mit dem Wechsel zu Midori will Microsoft das ändern. Das ist jedoch nicht ungefährlich. Wenn es gelingt, auf irgendeine Weise nativen Prozessorcode einzuschleusen, dann läuft dieser auf jeden Fall mit allen Rechten. Einer nativen Malware sind keinerlei Grenzen gesetzt.Um sicher zu gehen, dass keine native Malware eingeschleust wird, muss Midori nativen Code von außen ganz und gar verbieten. Das wird zumindest bei Treibern für PCI-Geräte nicht funktionieren. Bei Geräten, die über USB, Bluetooth, SCSI oder SATA angeschlossen sind, kann man Treiber komplett in Managed Code entwickeln. Bei PCI-Geräte müssen zumindest Interrupthandler[16] und Hardware-I/O mit nativem Code realisiert werden. Die Handler für Deferred Procedure Calls[17] lassen sich auch in Managed Code entwickeln.
Wenn Treiber für USB-Geräte komplett in Managed Code entwickelt werden, hat das natürlich Stabilitätsvorteile. Schlecht programmierte Treiber für Noname-DVB-T-Sticks können nicht mehr den ganzen Computer zum Absturz bringen, so wie das heute oft der Fall ist. Bei PCI-Geräten wird der Anteil von Native Code immerhin stark reduziert, so dass Hoffnung besteht, dass sich Entwickler genug Mühe geben, um den nativen Teil des Codes absturzsicher zu programmieren.
Ungeklärt ist bis jetzt allerdings, ob Microsoft für Anwendungsprogramme weiterhin Native Code erlaubt. Obwohl Managed Code für viele komplexe Anwendungen die richtige Lösung ist, gibt es durchaus performancekritische Routinen, die sich schneller und effektiver mit C oder Assembler lösen lassen. Webanwendungen, die sich häufig ändern und zudem naturgemäß dem Internet ausgesetzt sind, lassen sich in C gar nicht so schnell entwickeln, wie sie sich wieder ändern. Flüchtigkeitsfehler mit möglicherweise fatalen Folgen für die Sicherheit sind vorprogrammiert. Managed Code, beispielsweise in C#, ist in diesem Fall die richtige Lösung.
Im technisch-wissenschaftlichen Umfeld gibt es hingegen sehr rechenintensive Anwendungen, die sich durch immer weitere Optimierungen beschleunigen lassen. Nicht selten arbeiten Programmierer mehrere Jahrzehnte an der Optimierung von mathematischen Algorithmen. Das geschieht meist in C oder in Assembler. Diese hochoptimierten Algorithmen lassen sich nicht in die Beschränkungen von Managed Code zwängen. Für Anwendungen wie Kinofilmeffekte, Windkanalsimulation oder Molekülmodellierung ist Managed Code wenig geeignet. Je näher man direkt am Prozessor programmiert, beispielsweise durch direkten Zugriff auf SSE2-Befehle mittels Compiler Intrinsics[18], desto schneller wird der Code. An solche Techniken ist bei Managed Code nicht zu denken.
Man sollte nicht der falschen Vorstellung verfallen, dass Managed Code den größten Teil aller Sicherheitsprobleme löst. Managed Code, so wie er in Midori vermutlich zwingend vorgeschrieben ist, geht nur ein Teilaspekt von fehlerhaftem Code an, der immer dann entsteht, wenn Code von Menschen geschrieben wird. Trotz aller Sorgfalt gibt es keine bugfreien Programme.Auch wenn die Begriffe Microsoft und Windows untrennbar scheinen: Von Windows in der heutigen Form wird sich Microsoft in einem Zeitraum von etwa fünf bis sieben Jahren verabschieden. Der Produktname Windows bleibt möglicherweise erhalten, technisch gesehen entwickeln hochkarätige Experten ein neues Betriebssystem unter dem Codenamen Midori, das mit Windows nicht verwandt ist.
Midori wird bewusst nicht auf Windows basieren. Denn Windows hat im Laufe der Jahre einen immensen Ballast angesammelt, der zur Wahrung der Rückwärtskompatibilität immer wieder mitgeschleppt werden muss. Eine Weiterentwicklung ist anders als bei den meisten Unix-Betriebssystemen immer schwieriger. Neue Versionen reagieren zunehmend träger.
Ebenso legt Microsoft bei Midori Wert auf Modularität. Funktionalität soll in einem fest definierten Modul implementiert sein. Ein Fiasko wie bei Windows, so dass sich später herausstellt, dass das Netzwerk nur gestartet werden kann, wenn das grafische Subsystem mit seinem gesamten Speicherverbrauch hochgefahren ist, will man nicht wieder erleben.
Dadurch dass fast das gesamte Betriebssystem in Managed Code entwickelt wurde, will Microsoft die Sicherheit und die Stabilität erhöhen. Das mag vor allem für die Stabilität gelten, weil beispielsweise der Treiber eines Noname-DVB-T-Sticks den Kernel nicht mehr zum Absturz bringen kann. Die Sicherheit wird jedoch nur in einigen Teilaspekten erhöht. Zudem darf man den Einfallsreichtum von Cyberkriminellen nicht unterschätzen, die sicherlich auch in Midori Angriffspunkte finden.
In fünf bis sieben Jahren ein erblastfreies neues Betriebssystem auf die Beine zu stellen, bei dem sich Anwender wieder auf gutes Antwortzeitverhalten verlassen können, ist keine leichte Aufgabe. Noch weitaus schwieriger ist es, heutige Anwendungsprogramme in Managed Code zu überführen. Dazu muss nahezu jede Codezeile geändert werden. Zwar wird es möglich sein, Windows-Programme mit Virtualisierungstechniken auszuführen, das bedingt jedoch, dass neben Midori auch Windows mit seinem ganzen Ballast gestartet wird. Man darf auf jeden Fall auf das Ergebnis gespannt sein, wenn in etwa drei Jahren erste Entwicklerversionen in Umlauf kommen.
URLs in diesem Artikel:
[1] = http:/
[2] = http:/
[3] = http:/
[4] = http:/
[5] = http:/
[6] = http:/
[7] = http:/
[8] = http:/
[9] = http:/
[10] = http:/
[11] = http:/
[12] = http:/
[13] = http:/
[14] = http:/
[15] = http:/
[16] = http:/
[17] = http:/
[18] = http:/