Dreißig Jahre lang lebte die Systemprogrammierung mit einem Trade-off, der grundlegend wirkte: entweder manuelle Speicherverwaltung samt ihrer Fehler, oder ein Garbage Collector samt seiner Latenz. Rust verweigerte die Wahl. Sein Ownership-Modell liefert die Sicherheit einer verwalteten Sprache und die Layout-Kontrolle von C — vollständig zur Compile-Zeit bezahlt. Der Mechanismus besteht aus wenigen Regeln und einem Compiler, der sturköpfig genug ist, sie durchzusetzen.
Der Preis, der die Idee nötig machte
Speicherfehler sind kein ästhetischer Einwand. Sie sind die dominante Quelle ferngesteuert ausnutzbarer Sicherheitslücken in C- und C++-Code. Microsofts Security Response Center hat es beziffert:
„Rund 70 % der von Microsoft jährlich vergebenen CVEs sind weiterhin Speicherfehler.” — Matt Miller, Trends, Challenges, and Shifts in Software Vulnerability Mitigation, BlueHat IL, Februar 2019.
Googles Chromium-Team berichtet unabhängig dieselbe Quote:
„Etwa 70 % unserer schwerwiegenden Sicherheitsfehler sind Speicherprobleme.” — The Chromium Projects, Memory safety, fortlaufend.
Im Februar 2024 ging das Office of the National Cyber Director im Weißen Haus über die bloße Beschreibung hinaus:
„Speichersicherheitslücken sind eine Klasse von Schwachstellen, die betrifft, wie Speicher gelesen, geschrieben, alloziert oder freigegeben wird. Vor allem aber sind sie vermeidbar. Der wirksamste Weg, diese gesamte Klasse zu eliminieren, ist, dass Softwarehersteller speichersichere Programmiersprachen einsetzen.” — ONCD, Back to the Building Blocks: A Path Toward Secure and Measurable Software, Februar 2024.
Die empirische Bestätigung kam von Android. Indem Google neuen Plattformcode konsequent in Rust schrieb und den alten C/C++-Code unangetastet ließ, sank der Anteil speichersicherheitsrelevanter CVEs von 76 % aller jährlichen Android-Schwachstellen 2019 auf 24 % 2024:
„Der Anteil speichersicherheitsrelevanter Schwachstellen in Android sank von 76 % im Jahr 2019 auf 24 % 2024 — deutlich unter den 70 % der Branche.” — Jeff Vander Stoep, Eliminating Memory Safety Vulnerabilities at the Source, Google Security Blog, September 2024.
Alter Code altert weiter; neuer Code produziert schlicht keine neuen Fehler dieser Klasse.
Vor diesem Hintergrund existiert Ownership. Es ist kein Sprachfeature. Es ist ein Sicherheitsargument.
Die drei Regeln
Jeder Wert in Rust gehorcht drei Regeln:
- Jeder Wert hat genau einen Eigentümer (eine Bindung).
- Verlässt der Eigentümer den Geltungsbereich, wird der Wert freigegeben — sein Destruktor läuft, sein Speicher wird freigegeben.
- Referenzen auf einen Wert unterliegen der Regel Aliasing XOR Mutabilität: zu jedem Zeitpunkt gibt es entweder eine veränderliche Referenz oder beliebig viele unveränderliche, niemals beides.
Die ersten beiden Regeln liefern deterministische Zerstörung (RAII, geerbt von C++). Die dritte Regel — Exklusivität des schreibenden Zugriffs — ist der eigene Beitrag und der Grund, weshalb Data Races und die meisten Iterator-Invalidierungen statisch unmöglich werden.
Formal gilt für zwei lebende Referenzen auf denselben Wert:
Der Compiler beweist diese Eigenschaft für jede Referenz im Programm. Eine Laufzeitprüfung gibt es nicht.
Den vollständigen Beweis, dass die Regeln solide sind — dass sicheres Rust wirklich kein undefiniertes Verhalten erzeugen kann —, lieferte das Projekt RustBelt, das eine substantielle Teilmenge der Sprache und ihrer Standardbibliothek im Beweisassistenten Coq formalisierte.
„RustBelt ist die erste formale Verifikation der Sprache Rust und prüft nicht nur das Typsystem, sondern auch eine repräsentative Sammlung von Bibliotheken aus Rusts Standardbibliothek.” — Jung, Jourdan, Krebbers, Dreyer, RustBelt: Securing the Foundations of the Rust Programming Language, POPL 2018.
Move-Semantik und RAII
fn main() {
let s1 = String::from("hallo");
let s2 = s1; // s1 wird in s2 BEWEGT
// println!("{}", s1); // error[E0382]: Verwendung nach Move
println!("{}", s2); // s2 ist Eigentümer; beim Verlassen genau einmal verworfen
}Die Zuweisung let s2 = s1 kopiert nicht den Heap-Puffer, sondern überträgt das Eigentum. Der Compiler verfolgt anschließend, dass s1 uninitialisiert ist. Verlässt s2 den Geltungsbereich, läuft Drop::drop einmal. Es gibt keine Reference Counts, keinen Tracing Collector, kein manuelles free.
Es ist dasselbe RAII-Muster, das C++ seit 1985 kennt — nur durchgesetzt. In C++ verursachen ein nachlässiger Kopierkonstruktor oder ein vergessenes std::move Doppelfreigaben oder Leaks. In Rust verweigert der Borrow-Checker schon die Übersetzung.
Borrowing: Aliasing XOR Mutabilität
Eine Referenz in Rust hat zwei Formen:
| Form | Schreibweise | Fähigkeit |
|---|---|---|
| Gemeinsam (unveränderlich) | &T | Beliebig viele gleichzeitig; nur lesend |
| Exklusiv (veränderlich) | &mut T | Maximal eine zeitgleich; lesend und schreibend |
Der Borrow-Checker erzwingt diese Eigenschaften als statischen Typzustand jeder Bindung. Der Gewinn ist nicht nur Speichersicherheit: Der Optimierer darf annehmen, dass &T-Referenzen frei von Aliasing mit jeder &mut T auf denselben Speicher sind. Das ist die noalias-Annotation, die LLVM in C nie zuverlässig erhält. Rust liefert sie qua Konstruktion.
Der Preis ist die berüchtigte Lernkurve. Muster, die in Java oder Go trivial kompilieren — eine doppelt verkettete Liste, ein Graph mit Eltern-Zeigern, eine Closure, die eine veränderliche Referenz über den Geltungsbereich hinaus einfängt — lassen sich ohne unsafe, Rc<RefCell<T>> oder einen Umentwurf nicht ausdrücken. Der Community-Konsens lautet: das ist ein Feature, kein Bug — diese Muster waren meistens selbst der Fehler.
Lifetimes
Eine Referenz darf nicht länger leben als ihre Daten. Rust drückt das mit Lifetime-Parametern aus, die über Geltungsbereiche generisch sind:
fn longest<'a>(x: &'a str, y: &'a str) -> &'a str {
if x.len() > y.len() { x } else { y }
}Die Signatur erklärt, dass die zurückgegebene Referenz aus derselben Region 'a stammt wie die Eingaben. Die Beziehung zwischen Lifetimes nutzt Subtyping: 'a: 'b bedeutet, dass 'a 'b überlebt. Die meisten Lifetime-Annotationen leitet der Compiler aus den Elisionsregeln ab; explizit erscheinen sie nur, wenn das Verhältnis zwischen Ein- und Ausgang wirklich mehrdeutig ist.
Lifetimes werden zur Compile-Zeit gelöscht. Sie erzeugen keinen Code und kosten zur Laufzeit kein Byte. Sie existieren nur als Beweispflicht für den Typ-Checker.
Send, Sync und furchtlose Nebenläufigkeit
Die Marker-Traits Send und Sync erweitern Ownership-Reasoning auf Threads:
T: Send— Werte vom TypTdürfen Thread-Grenzen überschreiten.T: Sync—&Tdarf zwischen Threads geteilt werden (äquivalent:&T: Send).
Diese Traits werden anhand der strukturellen Komposition eines Typs automatisch abgeleitet. Rc<T> (nicht-atomarer Referenzzähler) ist !Send, weil zwei Threads, die den Zähler gleichzeitig dekrementieren, eine Race bildeten. Arc<T> ist Send + Sync, weil der Zähler atomar ist. Der Compiler weigert sich zur Compile-Zeit, einen Thread mit einem nicht-Send-Wert zu starten.
Zusammen mit Aliasing-XOR-Mutabilität ergibt das, was die Community fearless concurrency nennt: derselbe Borrow-Checker, der einfädige Iterator-Invalidierungen verhindert, verhindert auch mehrfädige Data Races — und aus demselben Grund.
Was das kostet
Das Ownership-Modell hat Kosten, die jede ehrliche Darstellung nennen muss.
- Async-Lifetimes. Borrows über
await-Punkte laufen in dasPin/ self-referential-Generator-Problem, das die Sprache noch nicht abschließend gelöst hat. Async-Funktionen in Traits, Ende 2023 stabilisiert, weisen weiterhin Ergonomielücken auf, die fortgeschrittene Muster mit Crates wieasync-traitumgehen. - Verkettete Datenstrukturen. Klassische Graphen oder Bäume ohne
unsafeverlangen Arena-Allocator oder Index- statt Zeigerdarstellungen. Korrekt, aber nicht das, was ein C-Programmierer erwartet. - Compile-Zeit. Monomorphisierung plus Borrow-Analyse machen Rust langsam zu übersetzen. Saubere Builds eines mittleren Workspaces dauern Minuten, nicht Sekunden.
- Lernkurve. Programmierer, die eine andere Systemsprache fließend beherrschen, brauchen üblicherweise mehrere Monate, bis sie aufhören, gegen den Borrow-Checker zu kämpfen.
unsafe. Eine Korpusstudie von 2020 fand, dass rund 29 % der Crates auf crates.io mindestens einenunsafe-Block enthalten, und die Standardbibliothek ist intern starkunsafe. Ownership ist eine Garantie über sicheres Rust;unsafeist die Falltür, an der die Garantie nicht greift und an der menschliche Prüfung übernehmen muss.
Keine dieser Kosten ist tödlich. Alle sind real.
Wo Rust heute steht
| Bereich | Status |
|---|---|
| Linux-Kernel | Rust-Unterstützung in 6.1 gemerged, Oktober 2022; Treiber und rust-for-linux-Subsysteme wachsen |
| Windows | Rust-Module in DWriteCore, Win32 GDI / GDI+ Region-Engine und Teilen von win32k (2023–24) |
| Android-Plattform | Neuer nativer Code in Rust; Anteil speichersicherheitsrelevanter CVEs von 76 % (2019) auf 24 % (2024) gesunken |
| Chromium | Rust seit Januar 2023 für Drittbibliotheken zugelassen; First-Party-Einsatz wächst |
| AWS Firecracker, Bottlerocket | Produktion-VMM und -OS für AWS Lambda und Fargate, in Rust geschrieben |
| Kryptografie & TLS | rustls, ring, dalek-cryptography, RustCrypto; auditiert und im Produktivbetrieb |
| Eingebettet | embedded-hal-Ökosystem stabil; Tock OS im Einsatz, Hubris in der Oxide-Cloud-Computer-Hardware |
Die meistzitierte Branchenstimme kam vom CTO von Microsoft Azure:
„Was Sprachen angeht, ist es Zeit, keine neuen Projekte mehr in C/C++ zu beginnen und Rust dort einzusetzen, wo eine Nicht-GC-Sprache erforderlich ist. Aus Sicherheits- und Zuverlässigkeitsgründen sollte die Branche diese Sprachen als veraltet erklären.” — Mark Russinovich, September 2022.
CISA, NSA und ONCD in den USA haben Leitlinien veröffentlicht, die für neuen Code in kritischen Systemen speichersichere Sprachen empfehlen. Rust ist die einzige systemtaugliche Sprache dieser Kategorie mit produktionsreifen Einsatznachweisen.
Der stille Teil
Das Ownership-Modell wird oft als cleverer Trick beschrieben. Das ist es nicht. Es ist die operative Konsequenz einer weit älteren Idee: lineare Typen, aus Girards linearer Logik (1987) und Wadlers „Linear Types Can Change the World!” (1990) — Typsysteme, die Ressourcennutzung verfolgen, sodass Werte nicht stillschweigend dupliziert oder verworfen werden können. Was Rust geleistet hat, war nicht die Theorie zu erfinden. Es war, die Theorie ergonomisch genug zu machen, dass Systemprogrammierer sie akzeptieren.
Genau das hat zwanzig Jahre gedauert. Der Borrow-Checker ist die leichte Hälfte; die Syntax, die Fehlermeldungen, die Editorintegration, die Standardbibliothek und das kulturelle Beharren darauf, dass kompilierender Code der Boden und nicht die Decke ist — das machte die Adoption möglich. Jeder andere Versuch linearer Typen in einer Mainstream-Sprache scheiterte nicht am Typsystem, sondern an der Unzumutbarkeit der Benutzung.
„Kryptografie wird selten gebrochen; sie wird umgangen.” — Adi Shamir
Dasselbe gilt für Sicherheit in Systemcode. C und C++ sind nicht unsicher, weil ihre Typsysteme schwach sind. Sie sind unsicher, weil der sichere Pfad eine Wachsamkeit verlangt, die kein Mensch über eine Million Zeilen aufrechterhält. Ownership beseitigt diese Forderung.
Quellen
- Miller, M. Trends, Challenges, and Shifts in Software Vulnerability Mitigation. BlueHat IL, Microsoft Security Response Center, Februar 2019. github.com/Microsoft/MSRC-Security-Research
- The Chromium Projects. Memory safety. www.chromium.org/Home/chromium-security/memory-safety
- Office of the National Cyber Director. Back to the Building Blocks: A Path Toward Secure and Measurable Software. Weißes Haus, Februar 2024. bidenwhitehouse.archives.gov/…/Final-ONCD-Technical-Report.pdf
- Vander Stoep, J. Eliminating Memory Safety Vulnerabilities at the Source. Google Security Blog, September 2024. security.googleblog.com
- NSA. Software Memory Safety Cybersecurity Information Sheet. November 2022. media.defense.gov
- Jung, R.; Jourdan, J.-H.; Krebbers, R.; Dreyer, D. RustBelt: Securing the Foundations of the Rust Programming Language. POPL 2018. plv.mpi-sws.org/rustbelt
- Astrauskas, V.; Matheja, C.; Poli, F.; Müller, P.; Summers, A. How Do Programmers Use Unsafe Rust? OOPSLA 2020. doi.org/10.1145/3428204
- Girard, J.-Y. Linear Logic. Theoretical Computer Science 50(1), 1987.
- Wadler, P. Linear Types Can Change the World! In Programming Concepts and Methods, North-Holland, 1990.
- Klabnik, S.; Nichols, C. The Rust Programming Language. No Starch Press / rust-lang.org. doc.rust-lang.org/book
- Torvalds, L. Merge des initialen Rust-Supports, Linux 6.1, Oktober 2022. git.kernel.org
- Russinovich, M. Öffentliche Stellungnahme zur Rust-Adoption, 19. September 2022. twitter.com/markrussinovich/status/1571995117233504257