 Tim Talk, Taming the Chaos und der nächste Sprecher Peter Sewell von der University von Cambridge. Bitte einen Applaus. Und hier ist die deutsche Übersetzung. Wir sind Ploy und Pink Dispatcher. Vielen Dank. Und jetzt geht es los. Ein Programm. Ja, viele tolle, aufregende Sachen gibt es hier. Und wenn wir allein die Security-Vorträge angucken, dann gibt es ganz viele interessante Namen. Wir haben hier zum Beispiel, ja, was haben wir denn? Wir gucken uns mal einige der Titel an Exploiting Kernel Memory Corruptions und einen Angriff auf E-Mail Encryption, E-Mail Verschlüsselung. Was haben wir noch? Moderne Windows User Space Exploits. Und wir hacken Online Accounts. Also viele von diesen, viele erklären das Computer gar nicht, das tun, was wir wollen. Und das ist nur die ganz kleine Spitze eines Eisbergs. Und wir haben hunderttausende bekannte Vulnerability Bees. Aber wie viele Unbekannte gibt es davon? Und wir machen mal hier Zuschauer Beteiligungen. Wie viele haben im letzten Jahr etwas geschrieben, mindestens 100 Codezeilen geschrieben im letzten Jahr? Und von allen diesen Leuten halten mal die Hände oben, wenn ihr ganz sicher seid, dass dieser Code genau das Richtige macht. Hm, ich würde gerne mal mit dir später sprechen, der da noch die Hände oben hatte. Und die Leute, die selbst fahren Autos machen, da würde ich auch gerne mal mit sprechen. Also wie viele unbekannte Vulnerabilities haben wir jetzt noch? Ne, man kann, wir nehmen mal diese Zahl und multiplizieren die mit, hm, das funktioniert gerade hier nicht so richtig. Nein, funktioniert immer noch nicht. Nein, nein, nein. Computer machen einfach das Falsche. Und ja, das funktioniert so nicht. Wir können das multiplizieren. Wir haben etwa vielleicht 100 Milliarden neuer Code, der jedes Jahr geschrieben wird. Und wenn man alle diese Vorträge und diese Zahlen anguckt, das macht uns nicht glücklich und zufrieden. Das sollte uns traurig, sehr traurig machen. Und wir sollten wirklich erschrocken sein. Was passiert in dieser Welt? Also was können wir machen? Wir können Option 1, wir können einfach aufhören Computer überhaupt zu benutzen. Und den meisten Publikum wäre das schwierig, aber ihr seid alle glücklich damit, die einfach auszuschalten. Oder wir können auch unsere einfach nur zusammenbrechen und uns in einer kleinen Grobe irgendwie zusammenbrechen und in einer Grobe der Verzweiflung vielleicht, vielleicht aber auch nicht. Und heute will ich euch ein ganz kleines Stückchen zeigen, ein ganz kleines Stückchen Hoffnung, dass es vielleicht möglich ist, was Besseres zu tun. Wenn wir was Besseres machen wollen, da müssen wir erst mal uns überlegen, warum die Sachen im Moment so schlecht sind. Und wenn wir in der Luftfahrt gucken, die machen Flugzeuge, die extrem selten abstürzen. Warum funktioniert das das? Warum können die das? Ja und warum sind wir so scheiße Computer zu machen? Und ja, weil ich benutze noch mal ein und die beste Beschreibung, die wir je gesehen haben von der Hardware und Software, die wir benutzen, das ist das beste Bild dafür, was ich gesehen habe. Und das meiste ist einfach toll und wir sehen alle diese Flaschen hier und das ist der C-Compiler und wir sehen viele andere Sachen, die hier umlegen und es ist eine feindliche Umgebung hier, eine unfreundliche Umgebung. Und wenn wir dies angucken und überlegen, was die Grundursachen sind, dass es schief geht, dann sehen wir einiges. Das Erste ist, ja wir haben ganz viele alte Komplexität, mit der wir einfach die wir haben und wenn wir einige von den Sachen in der Mitte rausnehmen und Sachen, die genau dieselbe Form haben, dann, wenn wir etwas etwas ersetzen, wenn das anders ist, dann bricht es alles zusammen, also müssen wir langsam schrittweise das verbessern. Und das Wichtigste ist, warum dies nicht wie Flugzeuge sind, dies sind diskrete Systeme und nicht kontinuierliche Systeme und wenn man einfach ein Stück Stahlträger, ein Stahlträger nimmt, dann und wenn es sich, wenn man es belastet bewegt es sich ein bisschen und es bewegt sich proportional und wenn es 1% zu stark oder zu schwach ist, das macht nicht viel aus. Und bei diesen Sachen hier, wenn nur eine Code Zeile falsch ist, dann gibt es die Möglichkeit für einen katastrophalen Angriff und wir haben hier ganz viele Millionen davon. Das Nächste, das funktioniert wieder nicht und die Sachen sind sehr kompliziert und das Erschreckende ist nicht nur die Statische Komplexität von diesen, die Anzahl Anzahl der Code Zeilen, obwohl das auch schon Angst machen kann, aber das wirklich Erschreckende ist die exponentielle Anzahl der Zustände und Pfade durch die Ausführung und das Testen, was wir benutzen, wir können im Moment diese Systeme nur testen und testen kann niemals, kann uns niemals retten vor diesen, diesen ausnutzbaren Fehlern, die wir haben und das bedeutet am Ende brauchen wir eigentlich Beweise. Wir brauchen richtige Maschinenüberprüfte, mathematische Beweise und wir brauchen auch mehrere Systeme, die aus ganz einfachen Grund sicher sein müssen und die basieren darauf, dass diese 100 Milliarden Code Zeilen korrekt sind. Und wir haben alle diese Interfaces, die ganzen Schnittstellen noch, das C-Interface, Socket Interfaces, TCP IP Interfaces, alle diese verschiedene Teile des Systems basieren darauf, dass die richtig funktionieren, aber die sind alle wirklich schlecht beschrieben und schlecht definiert und was man sieht, ist alle von diesen typischerweise hat man ein Buch voller Posa, so dick ungefähr, voll von Text und wir verlassen uns immer noch auf das Testen, obwohl es sehr beschränkt ist, aber man kann niemals alles vollständig gegenüber diesen Büchern testen, so was wir stattdessen brauchen. Wir brauchen Schnittstellen, Beschreibungen, Spezifikationen und Definitionen, die mathematisch rigorös sind und die dann auch ausführbar sind, nicht wie in der Implementation, sondern als ein Testorakel ausführbar sind, dass man tatsächlich rausfinden, ob Verhalten erlaubt ist oder nicht und wir brauchen Schnittstellenbeschreibungen, die diesen Beweis unterstützen. Und dann alles dieses ist in den 1970er Jahren gemacht worden oder in den 60ern und in den 60er und 70er, da war die Welt noch ein glücklicher Ort und Leute hatten Blumen in den Haaren und es nie irgendwas Schlechtes passiert und das ist einfach nicht mehr so, das heißt, wir brauchen Verteidigungen im Design und wir brauchen Verteidigungen, die kompatibel sind oder vielleicht kompatibel genug mit diesem alten System, die wir haben und dann, ich kann dazu nicht viel sagen, aber wir haben sehr wenig Motivation, die komplizierter sind als das, was wir verstehen können und wir fügen immer noch Features dazu und wir bauen Sachen, die man so gerade ausliefern kann, dann liefern wir es aus und dann machen wir das nächste. Das heißt, was wir brauchen ist, wir brauchen ökonomische und juristische Motivation für Einfachheit und Sicherheit und die haben wir noch nicht, aber wir müssen erst mal uns darüber enthalten, dass wir die technischen Voraussetzungen haben, um diese Motivation zu machen und ich spreche von zwei von diesen Interface, nämlich das C-Interface und viel von dem hat zu tun mit Speicher. Das heißt, wer immer das war, der den Untertitel für dieses Meeting, Refreshing Memories, sich ausgedacht hat, vielen Dank, das ist ganz toll, ich liebe es und frische Eure Erinnerungen auf, Euren Speicher. Das heißt, wenn ihr noch ganz jung wart, 1987, als viel cooles Hacking passiert ist, 1837 hat Charles Babbage diese Analytical Engine, diese analytische Maschine gebaut und der hat eine, diese mechanische, urwerkartige Sache gebaut, die die sogenannte Mill, in der alle alles ausgeführt wurde und dann einen Speicher auch und die sind hier Stapel von Zahlen, die mehrere Stapel von, von Zahnrädern und vielleicht an 50-stelligen Nummern speichern und dieses, dieses Array, dieses Feld geht irgendwie weit nach rechts rüber noch und das sind alles, alles Zahlen und dann hat man einen Speicher und das ist ein wirklich ein großes Feld von Zahlen und ich glaube diese waren nicht, ich weiß nicht ob man Berechnungen mit Adressen machen konnten, ich glaube Adressen waren immer konstant, aber, aber immerhin, das war ein Feld von, von Zahlen und na, was haben wir jetzt? Jetzt gucken wir mal uns das an. Wie viele von denen die 100 Zeilen geschrieben haben, haben C programmiert? Oh, einige und vielleicht ist euch auch einfach nur peinlich. Alle die sich jetzt nicht gemeldet haben bei der ersten Frage, ihr solltet euch, ihr solltet stolz sein und dass ihr, dass ihr so unschuldig seid, solange es, solange ihr eure unschuld noch habt, ihr seid noch keine Komplizen in diesem, in diesem großen Unfall. Hier ist ein bisschen C Code und ich erkläre, erkläre das mal gerade in verschiedenen Arten. Wir fangen an mit, es erzeugt zwei Positionen, zwei Location. Oh, nicht, was ist das? Das ist so blöd. So, es erzeugt zwei, es erzeugt x und speichert da eins und ein Secret Key und da ist deine Pin gespeichert. Und dann einige Berechnungen, die sollten nur x beeinflussen, aber vielleicht ein bisschen buggy oder korrompiert von irgendwas kaputt gemacht und dann versuchen wir einen Point auf x zu machen und in dieser Ausführung ist x zufällig 14 als hex 14 und dann addieren wir eins zu dem Zeiger. Das ist C, das heißt, was macht das in C? Das heißt, addiert vier Bytes von der Größe, von dem auf das es zeigt. Das heißt, wir addieren vier zu vierzehn, dann haben wir 18 und dann versuchen wir das Ding zu lesen, worauf der Zeiger jetzt zeigt und was passiert. Ich kompliere das mal gerade und ganz konventionell, kompliere das ganz und versuche das dann auszuführen und es druckt den Schlüssel aus, den geheimen Schlüssel und das ist charakteristisch nicht für alle Security Probleme, aber eine verstörende große Menge davon, die im Wesentlichen genau dieses machen. Und also kann man das in C wirklich machen? Ja und nein. Und wenn man sich den C Standard anguckt, eins von diesen schönen Büchern, das da steht drin. Man muss das ziemlich sorgfällig lesen. Dieses Programm hat undefiniertes Verhalten und das bedeutet, was den Standard angeht, für Programme wie diese. Es gibt keine Beschränkungen für das Verhalten der Implementation und wie man das vielleicht nützlich ausdrücken könnte, der Standard lässt Implementation annehmen, dass Programme Code einfach diese Sachen nicht machen, die undefinierten und es liegt in der Verantwortung des Programmierers, diese Sachen zu vermeiden. In 1975, vielleicht 1980 war das gut und der Programmierer hatte sehr viel Flexibilität, sehr viel Freiheit, effiziente Implementierung zu machen und das gilt jetzt nicht mehr wirklich so. Aber wie funktioniert das in der Definition? Der Standard muss irgendwie diesen Standard angucken und identifizieren, dass es ein undefiniertes Verhalten hat und tatsächlich, naja, wenn wir einfach nur über die Zahlen im Speicher nachdenken, dann ist dieses, dieser Zeige auf dem P zeigt auf eine legale Speicheradresse und wenn wir da eins addieren, dann ist das auch erlaubt und das einzige vorher wir wissen können, dass es undefiniert ist, ist nachzuverfolgen, wo der Zeige Ursprünglichen gezeigt hat, als er ursprünglich alluziert wurde und dann gucken wir wo das ist und dann haben wir in diesem Zeiger, obwohl wir vier dazu gezählt haben, haben wir immer noch die, können wir immer noch feststellen, wann er alluziert wurde und wenn wir das lesen, überlegen wir, ob das in dem Fußabdruck von der ursprünglichen Alluzierung war und es ist dann nicht mehr, sondern es ist irgendwo an, das ist nicht mehr an der richtigen Stelle und da kann man feststellen, dass das dann undefiniertes Verhalten hat. Also, damit ihr jetzt hier nicht verwehrt seid, man hat diese Definition von undefinierten Verhalten und das ist, wenn das irgendwo vorkommt im Programm, dann stört es ab. Also, aber das ist sehr, sehr spannend, weil für diesen ziemlich wichten Teil vom Standard verlassen wir uns drauf und das ist aber in einer üblichen Implementation nicht vorhanden zur Laufzeit. Wenn ich dieses Programm kompiliere und auf ArmAssembly runter kompiliere, dann hat es hier diese Sequenz von Store, Load und Add und wenn ich anschaue, was die Armarchitektur Spezifikation sagt, über diese Blauntransition hier ist, man kann sehr wohl Dinge in einer anderen Reihenfolge ausführen. Man kann entweder diesen Load machen oder diesen Store. Also, aber für jetzt lassen wir das mal bei dieser sequenziellen Abarbeitung. Also, dieses Laden hier lädt eine 64-Bit Zahl an diese Adresse, hat 4 und dann lädt man von dieser Adresse den Secret Key. Also, hier sieht man diese Allokationsabschnitte, sieht man hier in dem Sinne nicht mehr. Also, mach mir mal einen Schritt zurück. Ich habe euch jetzt Screenshots gezeigt von Verhalten von C und insbesondere auf der Armarchitektur und diese zeigen euch eigentlich alle erlaubten Verhaltensmuster, also die, die eigentlich der Standard erlauben sollte. Und was ich euch eigentlich jetzt gezeigt habe, aber ist, diese sind an mathematische Modelle geknüpft, die wir in einem Forschungsprojekt gemacht haben. Also, wirklich saure Ingenieurarbeit hier in diesen Projekten. In diesen Projekten haben wir eine Semantik gebaut, ein mathematisches Modell, das alles erlaubte Verhalten in C festlegt und die Architekturen von üblichen Prozessoren wie Arm, Risk Five, IBM Power und auch diese, die Instruktion Set Architektur, die sagt, wie diese Instruktion ausgeführt werden. Und diese Spezifikationen sind ausführbar als Testoragel. Also, man kann algorithmisch vergleichen ein beobachtetes Verhalten, kann man dann rausfinden, ob das jetzt eigentlich erlaubt wäre oder nicht. Also, es ist eigentlich eine idiotisch einfach Idee, aber der Industrie hat sich das noch nicht durchgesetzen lassen, fünfte Karten, obwohl es eigentlich nicht so schwer ist. Also, die ganzen mathematischen Modelle, auf die komme ich später nochmal zurück. In all diesen Beispielen, wenn man ganz genau hinschaut, findet man raus, dass man muss eigentlich nicht eine saure mathematische Strukturbahn von etwas, was das gut verstanden ist, sondern man merkt, es gibt da wirklich noch offene Fragen, zum Beispiel im C Standardisierungskomitee oder auch bei ARM, dass man sich da nicht mal ganz einig sind, was diese Dinge eigentlich sind. Und das ist ja eigentlich die Basis für alle unsere IT-Infrastruktur. Hier habe ich noch ein paar andere Projekte, das gibt es auch auf der Ebene von JavaScript oder CC++ Concurrency. Also, da sage ich jetzt mal nichts mehr dazu, aber Hannes Mennert sagt noch etwas über TCP im speziellen, an einem anderen Talk hier. Also, das ist jetzt ein bisschen besser, etwas rigoroseres Ausarbeiten von Spezifikationen, aber nur für eine nicht bereits existierende Infrastruktur, also eben die Programme, Sprache C, die Architektur ARM und was, wenn wir jetzt noch besser bauen wollen, bessere Sicherheitsarchitektur. Also, die Architekturen, die wir heute haben, sind eigentlich so aus den 60er und 70ern mit dieser Idee von Virtual Memory. Also, da gibt es einem eigentlich nur sehr, sehr grob einen Schutz. Man hat separate Prozesse, die isoliert sind voneinander und an einem guten Talk hat man vielleicht separate Browser Tabs im Browser, die isoliert sind voneinander, aber das skaliert nicht wirklich. Es ist einfach zu teuer, zu aufwendig. Also, das auf dieser Ebene von Granulatität zu machen. Wir können einfach bessere Sprachen entwickeln als C, aber der ganze bereits existierende Code ist nur mal in C. Also, eine andere Frage ist vielleicht, können wir bessere Sicherheit in die Hardware einbauen, das nicht riesige Veränderungen erfordert in der Software, die wir bereits haben. Und ein anderes riesiges Projekt, das Cherry-Projekt, hat sich diese Frage gestellt. Das läuft jetzt etwa schon acht Jahre, kommt von Cambridge, ist Unterstützt von Data Appsers, Google und so weiter. Die Leute, die mal involviert sind, sind Watson, Moore und Neumann. Also, wie macht man das jetzt? Also, das ist die Frage nochmal etwas genauer. Können wir Hardware-Unterstützung bauen, die effizient ist und deploybar, welches fein aufgelösten Speicherschutz uns gibt, um solche Leaks, wie im Beispiel vorhin, zu verhindern und skalierbare Compartmentalisierung uns erlaubt, dass dieses unerlaubte Verhalten nicht mehr möglich ist. Die Frage, also die Idee ist eigentlich auch aus den 70ern. Also, man muss in die Hardware-Unterstützung für Capabilities einbauen. Das zeige ich euch gleich an ein paar Momente. Also, die Idee ist, dass man dieses Least Privilege-Prinzip zur Anwendung bringt, dass ein Programm nur das machen darf, was es nötig hat und nicht mehr. Und jedes Mal, wenn ein Programm eine dieser Capabilities verwendet, dann muss man es explizit verwenden. Also, die Intention im Code muss sichtbar sein. So, das funktioniert jetzt folgendermaßen. Also, diese Capabilities ersetzen gewisse oder oder vielleicht eventuell alle Pointer im Code. Also, hier in ISOC hatten wir eine Adresse, also im Standard so. Gut, also der Standard ist es nicht sehr klar in diesem Punkt, aber also man hat hier eine Allocation ID, heißt das. Und in Cherisee kann man den selben Code laufen lassen. Man hat als Pointer nicht nur diese eine Zahl, sondern man hat diese eine Zahl und dazu noch die Basis der ursprünglichen Allokation und die Länge und Information über die Zugriffsrechte. Und das gehört alles zur Information vom Pointer und das kann dann in Hardware zum Zeitpunkt des Zugriffs überprüft werden, ob das jetzt in einen gültigen Speicherbereich ist dieser Zugriff. Und wenn es nicht so ist, dann kann man eine Trap auslösen. Also, man braucht ein bisschen mehr Maschinerie, dass das hier funktioniert. Also wäre schön, wenn das alles hier 64-Bit große Wörter werden, aber dann braucht man halt viel mehr Speicherplatz. Also, wir wollen das in weniger Platz unterbringen. So, und man muss natürlich das Instruktionsset der CPU vorsichtig so designen, um sicher zu stellen, dass man diese Capabilities nicht fälschen kann mit einer normalen Instruktion, dass man nicht einfach etwas aus der Luft greifen kann und das Hinzau mit ein paar Dits, Bits, die halt im Speicher rumliegen. Also das ganze Manipulieren von Capabilities da kann man nur, muss so sein, dass es man aus bereits gültigen Capability-Objekten ein anderes daraus konzieren kann, dass aber weiter eingeschränkt ist durch Berechtigungen. Also wenn die Hardware läuft, zur Initialisierungszeit der Hardware, muss man der Software einen Capability für alles geben. Und wenn das Betriebssystem funktioniert und der Linker und der Allocator aus der C-Sprache, dann werden diese Capabilities weiter unterteilt in kleinere Stücke, die weiter reichen werden. Und ein weiteres Ding brauchen wir noch. Also das ist jetzt die, im Prinzip das C-Ökosystem, also Maschinencode-Ökosystem. Also man kann halt jetzt immer noch Bits einfach schreiben. Und diese Capabilities hier müssen wir irgendwie geschützt werden davon, dass man absichtlich oder aus Versehen einfach drüber schreibt. Also die Integrität muss sichergestellt werden im Speicher. Und für jedes von diesen 128 Bits-Stücken fügen wir einfach ein zusätzliches Bit hierzu und das ist das Tag. Und da drin steht, ob in diesem Speicherbereich eine gültige Capability drinsteht oder nicht. Also diese Capability-Manipulationsinfrastruktur, wenn man den Capability eine Gültige gibt mit einem Tagset, dann, wenn man jetzt einfach zum Beispiel hier dieses Bit überschreiben würde, dass die Basis verändert, dann würde die Hardware dieses Tag löschen. Also sie sind eigentlich nicht direkt adressierbar, diese Tags. Also das ist wirklich Teil vom Speichersystem der Hardware. Also diese kann man nicht verändern aus der Software. Also das ist jetzt ziemlich lässig. Wir haben jetzt in ISO dieses nicht definierte Verhalten im Standard und in der Praxis in unserem Beispiel war das ein Leak und hier in Cherry haben wir das jetzt umgewandelt. Haben wir eine Garantie, dass das Programm abgebrochen wird und diese Information nicht gelegt wird. Noch ein paar weitere Dinge, die ich euch sagen will übers Design. Also ich habe die meisten davon schon erwähnt. Hier ging darum das möglichst flexibel zu machen, dass es leicht ist auf Cherry umzusteigen. Man kann das für alle Pointer machen oder einfach nur an ausgewählten Stellen. Und zum Beispiel zwischen Kernel und User Space. Es funktioniert ja gut zusammen, es existieren im C und C++. Also man muss kaum den Source Code umbauen, um das verändern zu können. Es geht auch sehr gut zusammen mit dem Virtual Memory Architektur, die wir haben. Also man kann die nur Virtual Memory brauchen oder auch Capabilities dazunehmen. Dann habe ich noch einige Mechanismen, die ich jetzt nicht eingehen will, um es sicherer zu machen. Also hat so ja das mehr ins Detail runter. Also es geht hier um Spatial Memory Safety. Aber es schützt nicht von einer Wiederverwendung von der alten Capability. Also wir haben hier keine zeitliche Memory Safety, Temporal Memory Safety. So wie können wir also die High Level Idee und so. Und wie kann man es hinkriegen, dass es wirklich funktioniert? Naja und eine Möglichkeit ist es wirklich herzustellen zu bauen und zu gucken was passiert. Und das ist wirklich ein sehr interessanter Prozess und meistens wenn man Sachen baut zum Beispiel in der akademischen Welt oder in der Industrie, dann muss man die meisten Teile einfach fest machen. Und man kann sich ständig Prozesse und Betriebssystem ändern. Das ist einfach zu unvorstellbar. Aber wir haben das hier gemacht, wir haben einen 3-Teilings Code, 3-Teilings Code Design gemacht, wir haben Hardware gebaut und eine adaptierte Software, die da drauf basiert und ein mathematisch formales Modell davon. Das haben wir gleichzeitig gemacht. Und erstens macht es einfach Spaß und es bringt Leute zusammen, die solche Sachen machen können. Und außerdem ist es aber auch sehr effektiv. Also was wir hergestellt haben, was wir gemacht haben, ist eine Architekturspezifikation und eine Erweiterung von MIPS, weil es einfach, da es keine Intellectual Property Geschichten gab. Und die Spezifikation ist eine von diesen mathematisch rigorosen Dingen, die in einer domain-spezifischen Sprache gemacht ist, ganz speziell, um Befehlsätze zu spezifizieren. Und wir haben zwei davon tatsächlich implementiert und es gibt Hardware-Prozesse-Implementierungen, die in FPGAs implementiert sind und viel der Hardware-Forschung ist, dass es einfach schnell geht, obwohl es zusätzlich aufwand ist. Und dann gibt es einen großen, adaptierten, angepassten Software Stack, der darauf läuft. Da gehört Clang dazu, ein FreeBSD-Colonel, FreeBSD-Userspace, WebKit und viele andere Teile. Und das ist ein wirklich großer Auswertungsaufwand. Und das ist warum man diese vielen Leute braucht, ungefähr 40 Leute, weil man diese Kombination braucht. Das ist basiert auf MIPS, aber die Ideen sind nicht MIPS spezifisch und es gibt weitere Forschung, dass das auch angepasst werden kann an ARM, an die ARM-Architektur, an Microcontroller-Architektur, ARM-Microcontroller und RISC-5. Und wir werden sehen, wie das funktioniert. Also mit allen diesen Teilen können wir mal gucken, ob das wirklich funktioniert. Und das ist immer noch ein Prozess, der man noch stattfindet. Aber es ist recht ermutigend, was wir bisher gesehen haben. Also hier sehen wir, zuerst sehen wir die Leistung, die Performance. Und vielleicht gibt es ein oder zwei Prozent Overhead zur Laufzeit. Und es gibt ja Sachen, die wir machen müssen, die Aufwand sind. Und manche sind sehr viel Zeigermannipulationen. Und bei vielen großen Zeigern ist das etwas lästig. Aber es geht erstaunlich gut. Und dann ist es etwas, wofür keine riesige Anpassung brauchen von existierendem Code. Und in diesem FreeBSD Userpace und alle diese Programme, die da laufen, vielleicht etwa 20.000 Files und nur 200 von diesen 20.000 mussten angepasst werden. Und ein oder zwei Leute haben das in gar nicht so langer Zeit gemacht. Einige von dem anderen Code ist mehr oder weniger, das sind tiefe Einschnitte im Betriebssystem. Aber es ging trotzdem. Und ist es denn jetzt wirklich auch sicherer, wie kann man das messen? Wir mögen es, Sachen zu messen. Wir machen Wissenschaft hier, wenn wir können. Und können wir das messen? Nein, nicht wirklich. Aber das ganze Setup schützt vor einer großen Familie von bekannten Angriffen. Wenn man zum Beispiel HardBleed sich anguckt, dann hätte es einen Trap gegeben. Und Signal 34 gibt es dann. Und das ist schon mal ganz gut. Und wenn man darüber nachdenkt, über Angriffe nachdenkt, viele von denen haben eine Kette von ganz vielen Fehlern, die zusammenkommen von einem genialen Kopf in der Community. Und oft ist einer von diesen eine Art von Speicherzugriffproblemen auf die ein oder andere Art. Und das ist schön. Aber ich habe jetzt viel darüber gesprochen über rigoroses Engineering. Und wir haben hier formal definiert, formale Definition der Architektur. Und das ist sehr nützlich, um zum Zug testen, damit man weiß, wogegen man testen kann und Teste generieren kann und Spezifikationscoverage überprüfen kann. Aber wir sollten eigentlich mehr tun können. Und diese formale Definition der Architektur und also für alle Befehle, für jeden Befehl von dieser Cherry ASA haben wir eine Definition. Und diese Definition sieht ein bisschen wie Code aus, wie normaler Code. Und hier ist die Definition des Befehlens für die Capability Increment Cursor. Und das benutzt ein Capability Register und eine Immediate Variable. Und was man hier sehen kann in diesem Code, es sieht aus wie Code. Und das definiert ganz genau, was passieren soll und passiert ganz genau, was passiert, wenn etwas schief geht. Und hier gibt es eine Exception, eine Ausnahmebehandlung. Und es steht, was dann passiert dann. Und es gibt hier eine Prozessor Exception. Es sieht aus wie Code, aber aus diesen können wir Emulatoren, können wir herausbauen, die relativ schnell laufen für C und O-Cameral. Und es gibt auch mathematische Modelle für den Theory Improver. Und es gibt die besten, die wir kennen, sind Isabel und Hohl und Cock, die Theory Improver. Und wir definieren, wir erzeugen Definitionen für alle von diesen. Also haben wir eine mathematische Definition der Architektur. Und dann können wir einige Eigenschaften festlegen. Und das hatten wir von Anfang an eigentlich vor. Aber wir können einen von diesen definierten Ziel nehmen und können daraus ein ganz präzises Ding machen und beschreiben. Und das ist eine sichere Encapsulation, eine nicht unbedingt für die Speicher-Lex, aber die wir vorangeguckt haben. Aber stellt euch mal vor, wir haben in einem Cherry-Compartment. Ich weiß nicht genau, was es ist, aber belegt euch, was es ist. Innerhalb von diesem Compartment läuft ein Stück Software. Und das könnte zum Beispiel vielleicht ein Videocodec sein oder ein Webbrowser oder vielleicht auch eine Implementation einer Datenstruktur oder eine C++ Klasse und alle Objekte, die dazugehören. Stellt euch vor, dieses Compartment läuft. Und stellt euch vor, die ursprüngliche Capability ist zum Beispiel über Register und über den Speicher. Und die Register, auf die es Zugriff hat und den Speicher auf die es Zugriff hat. Und stelle euch alle diese Capability vor. Und der Satz sagt jetzt, egal wie dieser Code ausgeführt wird, was auch immer da tut, wie immer kompromittiert oder fehlerhaft der ist, in dieser Ausführung bis eine Exception stattfindet in der Ausführung oder wenn ein Aufruf kommt zu einem anderen Compartment, solange kann das keine Ausführung machen, keinen Zugriff machen, die von der ursprünglichen Capability nicht erlaubt wird. Man muss Exceptions ausnehmen und Intercompartment Calls zu anderen Compartments aufrufen. Sie muss man ausnehmen, die funktionieren anders, aber bis dahin haben wir garantiert, dass nur, und das haben wir bewiesen. Ninos hat das bewiesen mit einem maschinenüberprüften mathematischen Beweis in Isabell. Und das ist ein Fakt, der bekannt ist und von dem wir wissen, wenn ein mathematischer Prover einen ganz detaillierten mathematischen Proof, einen mathematischen Beweis bewiesen hat, dann ist das echtes Wissen, was wir haben. Und dieser Proofchecker basiert nur auf einem ganz kleinen Turckkernel. Und ja, vielleicht haben kosmische Strahlen gerade in einen Transistor getroffen, aber das ist etwas, was wir wirklich definitiv wissen. Und es gibt dieses eine Sicherheitseigenschaft und wir haben nicht bewiesen, dass Jerry sicher ist. Es gibt noch ganz viele andere Arten von Angriffen, aber die von diesem Fakt gar nicht betroffen sind. Aber diese eine Eigenschaft, die wissen wir definitiv. Und das ist schon einigermaßen beruhigend und nichts, was konventionelle Informatik machen konnte insgesamt. Und also haben wir jetzt das Chaos schon bezwungen, aber noch nicht, nein tut mir leid, aber ich habe euch zwei Sachen gezeigt. Und das erste war zu zeigen, wie wir etwas rigorosere Ingenieurleistungen vollbringen können. Und zwar, dies war machbar und ich glaube, es war machbar, solche Spezifikationen zu machen, die wir dann als Testorakl benutzen können. Und das können wir schon seit Jahrzehnten. Wir brauchen keine ganz tolle neue Technologie dafür. Wir mussten uns nur fokussieren auf diese eine Idee und dann für existierende Infrastruktur. Und Jerry ist eine ziemlich kleine Änderung nur und die mit der man die Sicherheit verbessern kann. Und ich glaube, wir haben gezeigt, dass es prinzipiell zumindest einsetzbar ist, ist das in der Praxis wirklich einsetzbar in allen unseren Telefonen in fünf Jahren oder so, die alle Jerry enabled sind. Das kann ich nicht sagen. Ich denke, es ist plausibel, dass das passieren könnte. Und wir gucken auch, wie wir das vielleicht vorantreiben könnten. Aber wir werden sehen, ob das funktioniert. Also, damit habe ich euch gezeigt, vielleicht ein bisschen Hoffnung gegeben, nicht ganz viel, aber vielleicht ein ganz klein bisschen Hoffnung, dass die Welt besser gemacht werden kann. Und ich ermutere euch, darüber weiter nachzudenken. Und vielleicht könnt ihr wenigstens ein paar Momente lang träumen, dass wir in einer besseren Welt leben können. Und damit vielen Dank für die Aufmerksamkeit. So, vielen Dank. Damit gehen wir mal noch zu Fragen über. Also, Mikrofon Nummer eins, bitte. Ja, vielen Dank für den sehr ermutigenden Vortrag. Ich habe eine Frage, wie sich hat man den Vater runterab? Vorher wissen wir, dass die Beschreibung zu der Hardware-Parte, dass die Hardware tatsächlich genau beschrieben wird. Und gibt es Möglichkeiten, zu überprüfen, dass die Hardware tatsächlich genau so funktioniert, wie speziell gesagt, dass da keine Möcher drin sind, dass nicht bestimmte Kombinationen anders funktionieren oder Kombinationen, die gar nicht im Modell vorkommen. Und es ist möglich, Hardware-Designs anzugucken und gegen die Hardware zu testen oder mit Intel, würden die ihre Modelle reprüfen gegen die Spezifikationen? Die Frage ist im Prinzip, können wir beweisbar korrekte Hardware machen unter dieser Abstraktions-Ebene? Also, es ist eine gute Frage. Leute arbeiten dran und man kann es machen. Also, mindestens auf so eine akademischen Größenordnung. Um das in der ganzen Größe, industriell hergestellt, der Superscalarprozessor herzustellen, das geht noch nicht wirklich. Wir vielleicht in einem Jahrzehnt sind wir etwa da, ja. Also, ja, eine Dekade ist ziemlich schnell. Ja, vielen Dank. Mikrofon 4 jetzt. Also, eine Frage aus dem Internet. Keiner Mikrofon. Wo ist das Internet? Hier ist das Internet. Und überall, also Ruminate würde gern wissen, ist die Kosten und der Aufwand, Security in Hardware einzubauen, wie du beschrieben hast, ist das größer oder weniger als der Aufwand, Software zu portieren und sichere Programmiersprachen? Also, es hat bei Bauen etwa groß gleich Kosten, wie Software auf sichere Sprache neu zu schreiben. Ich würde sagen, ja, es ist, die Kosten sind tiefer. Das schwer bei Software zu portieren ist, ich meine, alle, die hier sind, ja, wart alle am Code schreiben für 50 Jahre. Also, ich will jetzt nicht sagen effektiv, aber vielleicht humorvoll. Und es ist wirklich eine erschreckende Menge an Code, die da draußen ist. Okay, Mikrofon 2. Also, da die meisten Programme und die meisten Software heute in der Software- und Hardware-Level kann man einfach die nur den halben Weg gehen und das System nur als Orator benutzen, zum Beispiel während der Entwicklung der Codebase und sichere Hardware und dann im Wesentlichen dieselbe Software auf unsichere Hardware ausliefern und hat man dann dieselben Vorteile davor von diesem Beweis. Also, ich parafassiere das mal. Können wir diese Hardware-Implementation brauchen als ein Sanitizer eigentlich? Ich denke, ja, doch, das wäre sinnvoll. Man kann sich hervorstellen, dass man nicht mal echte Hardware sagt, sondern zum Beispiel diese Quemo-Implementation, also ein Simulator. Und es könnte jetzt schon sehr nützlich sein, um Backstool zu finden, ja. Also, ja, das wäre es wert. Aber genauso halt wie Testing untersucht das nur eine sehr kleine Menge von Pfaden in der Software. So, nochmal das Internet. Okay, wie funktioniert deine Technik mit Intel MPX im Vergleich? Und Fits, ist das besser oder schneller oder kannst du etwas darüber sagen? Also, für diese Frage, für eine echte Antwort, müsstest du mit einem von Hardware-Nahm Kollegen sprechen. Also, ich weiß nicht genau, was dieses MPX ist. Okay, Mikrofon 1. Also, was für die Gesamtkonstruktion die Idee ist, dass man unendlich enderbare Bits hat, die die Eigenschaften des Pointers beschreiben. Ist dir etwas, was nur in Software gemacht werden kann oder extra Speicher oder so? Also, man kann es nicht nur in Software machen, weil man muss das ja detektieren können, wenn da was verändert wird. In der Hardware-Implementation von meinen Kollegen ist es ziemlich effizient gemacht. Also, es gecached und wird schlau verwaltet, dass es nicht allzu teuer ist, das zum tun. Man braucht ein bisschen breitere Datenpfade, größere Caches, solche Dinge, um das zu verwalten. Okay, Mikrofon 7. Wie gut funktioniert das System, um den Control-Flow Integrität zu sichern, verlichten mit anderen Hardware-Systemen, die Data-Flow-Isolation machen oder Co-Pointer-Integrität in Arm. Es ist ein bisschen schwer zu beantworten. Es kommt halt drauf an, wie man die Capabilities verwendet. Also, man kann es sich so einrichten, dass jede C-Allocation geschützt ist oder man könnte es auch so machen, dass jedes Subobjekt auch unabhängig geschützt wird. Und dieser Schutz schützt gegen Stack-Smashing. Also, weil die auf jeweils nur ein Objekt der Umfang von so Schutz ist. Okay, noch mal eine Frage aus dem Internet. Twitter würde gerne wissen, ist es möglich, Cherisee ohne Custom-Hardware zu verwenden? Also, kann man Cherisee ohne spezielle Hardware laufen lassen? Ja, man kann es emuliert laufen lassen. In Kuemu haben wir eine Implementation. Das funktioniert ziemlich schnell, also schnell genug, dass man es auf die Bank kann. Das hatten wir in der vergangenen Frage schon. Man kann sich natürlich vorstellen, dass es da noch ein bisschen schnellerer Emulation gäbe. Ich weiß auch nicht, ob das wirklich ergiebig ist, das anzuschauen. Also, ein großer Gewinn ist natürlich, wenn man das immer anhat. Okay, Mikrofon 1. Du Beispiel von den Art der Code-Veränderungen, die nötig sind zu Betriebssystemen und Userland. Also, was für Veränderungen haben wir gemacht, um Code auf Cherry anzupassen, zu portieren? Wenn man sich C-Code anschaut, also gibt es den C-Standard, da sind ganz viele Dinge, werden sind undefined behavior. Und wenn man tatsächlich ein C-Code anschaut, dann sieht man, dass sehr, sehr viel davon von Idiomen abhängt, die im C-Standard eigentlich gar nicht vorhanden sind. Also, zum Beispiel gibt es sehr viele Vorkommnisse von einem Pointer gemacht wird, bei welchen man mehr als plus ein Offset macht und dann wieder zurück in den alloziierten Speicherbereich kommt. In Cherry-C sind viele von diesen Fällen erlaubt, aber nicht alle. Dann gibt es exotischere Fälle, also wirklich wahnsinniges Zwischenobjektzeug. Also, im C-Standard ist das eigentlich nicht spezifiziert, aber in der Praxis kommt das halt vor. Und dann gibt es Code, die Bits von Pointer manipuliert, um Daten zu speichern, das ist sehr verbreitet. Also, das kann man in Cherry-C machen, man muss den Code auch ein bisschen anpassen. Es gibt noch Grundregeln und Beispiele. Also, beim Swapping Out oder Swapping In, dann muss das Betriebsstem irgendwie Capabilities wieder neu herstellen, aus einem größeren, dass das Betriebsstem behalten hat. Da braucht es ein bisschen mehr Arbeit. Das ist eine Kombination, eigentlich. Gewisse Dinge sind eigentlich sowieso Veränderungen, die man haben will im Code und andere sind halt mehr radikal. So, nochmal aus dem Internet. Das Internet ist ganz still, großartig. So, doch noch eine. Gibt es Pläne für Impact-Testing auf Linux oder nur für die BSD? Also, wenn jemand ein paar Minuten übrig hat, viele Minuten, wäre das lässig, mal zu versuchen, zu schauen, was der Einfluss in Linux sein könnte. Also, Free BSD Codebass ist halt einfacher, etwas mehr aufräumt. Und meine Systems-Kollegen sind halt damit schon Vertrauter. Und bei, das ist einfach schon, wäre schon ein Riesenaufwand für ein akademisches Projekt. Also, wäre sehr schön, wenn wir das bei Linux machen können oder bei Android, aber wir haben einfach nicht die Ressourcen dazu. Dann bitte noch mal ein Mikrofon ein. Mikrofon 1 funktioniert nicht. Ja, wie wahrscheinlich oder gefährlich ist es, dass ein Programmierer mit den Capabilities durcheinander kommt, die er spezifiziert? Also, wie oft wird der Programmierer Fehler machen bei Minutzen von Capabilities? Also, normalerweise macht man einfach einen Zugriff mit einem C-Pointer oder C++-Objekt auf eine normale Art. Also, man baut nicht die Capability selbst. Also, das sollte im Normalfall einfach funktionieren. Wenn man selber eine spezielle Encapsulation baut, da muss man dann halt aufpassen. Aber das ist eigentlich ein eher kleines Risiko im Vergleich zu, na ja, halt dem Zustand von Software im Allgemeinen, den wir heute haben. Mikrofon 8 existieren und der Speicherschutz-Technologie sind sehr, die Patchwork, die Canaries und Random Layout und so. Randomization, ja. Und dieses System soll das diese alten Techniken ersetzen oder zusätzlich benutzt werden? Ich denke, es kommt ein bisschen auf an, wie man Capabilities verwendet. Wenn man die einfach absolut überall hat, dann braucht es eigentlich address-based Layout Randomization gar nicht mehr oder Canaries auch nicht mehr, die halt gegen explizites Information-Leaks schützen. Ich denke, na ja, vielleicht Randomization will man trotzdem noch haben, um vor Sidechannel Flows zu schützen, aber Canaries bringen's dann wohl nicht mehr. Mikrofon 4, bitte. Vielen Dank für den sehr interessanten Vortrag. Du hast mit Terri zusammen ein System gezeigt, wie man existierende C-Software verifizieren kann, nachdem sie geschrieben ist und dann mit Security mit einem Laufzeitsystem Improving, ja, verbessern, nicht beweisen. Also, was hältst du da vorne, dieses einen Static-Analysis und Static-Verifikation für das, was es nicht möglich ist, um zu benutzen? Ist es möglich, da Software damit zu analysieren, die Show und die unsafe Languages geschrieben ist, in diesen unsicheren Programmiersprachen und zu zeigen, dass es bestimmte Security-Eigenschaften hat, ohne diese Beweise in Hall oder Isabel manuell zu schreiben? Also, wenn man existierende Software analysieren will, also diese Analyse ist dann natürlich schon sinnvoll, um Box zu finden, wenn man sich aber sicher sein will, dass das wirklich fehlerfrei ist, das ist ziemlich hart. Also, man muss natürlich manuell Beweise schreiben in der existierenden C-Semantik, also man braucht da Infrastruktur, wenn man sich anschaut, das Hypervisors oder Compiler verifiziert worden oder Betriebssysteme, also das ist jetzt möglich auf einer beachtlichen Skala schon. Aber die brauchen halt Schichten von Beweisenabtragsionsinfrastruktur, also sie schreiben nicht für jedes letzte Detail ein Beweis von Han. Gewisse von diesen Verifikationsmethoden, also kann man sich vorstellen, so ähnlich wie statische Analyse. Also, man braucht statische Analyse, um eigentlich relativ einfache Fakten herzuleiten über Code und diese steckt man dann zu einem größeren Aufbau zusammen. Also, wenn man sowas eher komplettes haben will, ist das sehr schwer, dass das umsetzbar sein könnte. Also, ich glaube, da Assurance rauszukommen wird eher schwer. Mikrofon 1. Du hast gesagt, du veränderst die MIPS-Architektur mit zusätzlicher Logik für Calvabilities und was sind die Kosten dafür? Was ist das? Was sind die Kosten für diese Modifikation, für die Komputation und für die Konsum? Ah, was sind die Energiekosten? Also, über Performancekosten hatten wir ja schon gesprochen. Also, ich habe euch bewusst diese Energiekosten ausgelassen, das irgendwie wissenschaftliche Heroes zu machen, weil ja, ohne halt eine tatsächliche massenproduzierte CPU, dann kann man das nicht messen. Wenn du irgendwie 10 oder 20 Millon Pfund hast, dann kann ich dir das gerne auch noch messen. Wie ist das im Vergleich mit den Problemen, die zum Beispiel durch Rust schon ausgeschlossen werden? Also, wenn ich die bei den Problembereiche vergleiche, wenn du natürlich all dein Code in Rust schreibst und nie das Wort Unsafe brauchst, dann vielleicht gäbe es keinen Sinn, Cherry zu verwenden. Aber wirst du das jetzt tun? Ich denke, da hinten schüttelt jemand den Kopf, ja. Mikrofon 1. Was hältst du von der vorigen Aussage? Wir bauen ein ganzes System von Genen mit künstlicher Intelligenz und so was ähnlichem, das überallt uns in technischen Levels und die zusätzliches Chaos baut und erzeugt und das lässt sich hiermit nicht beheben. Das ist ziemlich schlimm, nicht wahr? Also, ich bin ein gewisser von meinen Kollegen, beschäftige ich mich mit dieser Frage. Also, man will vielleicht irgendwie sich Grenzen machen zu was die AI Zugriff hat oder anfangen kann und diese Art von Technologie könnte man durchbrauchen. Aber diese Machine Learning Systeme intrinsisch bauen die Halt Dinge, die wir nicht verstehen und meine Arbeit hier geht nicht auf das ein. So, hat das Internet noch eine Frage? Nein, gut. Ich sehe sonst auch niemanden mehr und dann können wir das hier abschließen. Herzlichen Dank.