Die Programmiersprachen C und C++ sind seit Jahrzehnten unverzichtbare Werkzeuge in der Softwareentwicklung. Sie ermöglichen direkte Hardwarekontrolle, bieten hohe Performance und erlauben fine-grained Speicherzugriffe. Gleichzeitig sind sie aber dafür berüchtigt, Speicherfehler zuzulassen, die in kritischen Sicherheitslücken münden können. Die mangelnde Speichersicherheit führt häufig zu Buffer Overflows, Use-After-Free-Fehlern oder anderen Schwachstellen, die Angreifer ausnutzen, um Schadcode auszuführen oder Systeme zu kompromittieren. Aus diesem Grund wurden neuere Sprachen wie Rust, Java oder Haskell so entworfen, dass solche Probleme prinzipiell ausgeschlossen sind.
Doch sie verzichten dabei auf die Nähe zur Hardware und die Flexibilität von C und C++. Genau an dieser Stelle setzt das Fil-C Manifesto an und präsentiert einen bemerkenswerten neuen Ansatz, um die Speichersicherheit in C und C++ durchzusetzen, ohne ihre geliebte Programmiermodelle zu ersetzen. Fil-C ist ein persönliches Projekt eines Entwicklers, der die Schönheit und Stärke von C und C++ bewahrt, dabei aber deren Sicherheitsherausforderungen mit einem innovativen System namens InvisiCap und einem hochmodernen Garbage Collector namens FUGC begegnet. Die Kernidee von Fil-C ist, dass jeder Pointer eine sogenannte Capability trägt. Diese Capability — unsichtbar für den Standard-Code — speichert die Grenzen des zugrunde liegenden Speicherbereichs sowie den Typ der referenzierten Daten.
Um dies zu erreichen, verfolgt Fil-C einen neuartigen Pointer-Encoding-Mechanismus namens InvisiCap, bei dem zu jedem 64-Bit-Pointer eine entsprechende Capability an einem unsichtbaren Ort im Adressraum hinterlegt wird. Beim Laden eines Pointers kann Fil-C so die Capability blitzschnell abrufen und bei der Speicherung effizient ersetzen. Während der Programmausführung werden Pointer in Registern zusammen mit ihren Capabilities behandelt, was neben Bound-Checks auch Typprüfungen ermöglicht. Damit kann Fil-C sehr feingranulare Speicheranalysen in Laufzeit erzwingen, die verhindern, dass Pointer außerhalb ihres gültigen Bereichs verwendet werden oder auf bereits freigegebene Speicherbereiche zugreifen. Dadurch werden klassische Fehlerquellen wie Buffer Overflows, Use-After-Free oder sogar falsche Pointerarithmetik aufspürbar und unterbunden — noch bevor sie zur Sicherheitslücke werden.
Sollte eine solche Verletzung auftreten, wird das Programm gesetzeskonform „gestoppt“ und eine ausführliche Fehlermeldung angezeigt. Ein weiterer Kernbestandteil von Fil-C ist FUGC (Fil’s Unbelievable Garbage Collector) – ein hochperformanter, genauer und nebenläufiger Garbage Collector, der alle Speicherzuweisungen verwaltet. FUGC arbeitet ohne Unterbrechung der mutierenden Threads, führt parallel Mark-and-Sweep-Phasen durch und verzichtet auf Stop-the-World-Pausen, wie sie viele andere Collector benötigen. Dies garantiert, dass Fil-C-basierte Programme reaktionsfähig bleiben, auch wenn die Garbage Collection im Hintergrund auf Hochtouren läuft. Interessanterweise ist es bei Fil-C nicht erforderlich, bestehende Speicherverwaltungsmechanismen wie malloc und free zu verändern oder speziell anzupassen.
Fil-C ist vollständig kompatibel zu bestehenden C/C++-Semantiken und erlaubt sogar die Nutzung von int-ptr unions ohne Probleme. Die Kombination aus InvisiCap und FUGC sorgt dafür, dass das Speichermanagement sicherer wird, ohne dass dafür drastische Änderungen im Quellcode notwendig sind. Für Entwickler bedeutet dies, dass ein großer Teil bestehender C- und C++-Projekte praktisch unverändert mit Fil-C kompiliert und ausgeführt werden kann. Sogar komplexe, vielschichtige Anwendungen wie der OpenSSH-Server, Curl, Python, SQLite oder diverse Standardbibliotheken können bereits fehlerfrei ausgeführt werden. Dies ist ein beeindruckender Beweis für die Kompatibilität und Stabilität des Systems.
Die Verwendung von Fil-C ist dabei denkbar unkompliziert gehalten. Entwickler können den Fil-C Compiler ähnlich benutzen wie einen herkömmlichen C-Compiler. Für Linux-Systeme mit x86_64 Architektur stehen vorgefertigte Binaries bereit, die einfach genutzt werden können. Auch der Quellcode steht offen, so dass interessierte Entwickler das System selber bauen und in ihre Projekte integrieren können. Trotz der umfassenden Sicherheitsvorkehrungen und detaillierten Prüfmechanismen sorgt Fil-C für eine vergleichsweise moderate Performance-Einbuße.
Laut Angaben des Entwicklers liegt die Ausführungszeit typischer Programme im besten Fall nur etwa 1,5-mal, im schlechtesten Fall rund 4-mal über der von herkömmlichem C-Code. Angesichts der erreichten Speichersicherheit ist dies ein bemerkenswert guter Kompromiss, der sich durch fortlaufende Optimierungen und Weiterentwicklung noch verbessern lässt. Besondere technische Herausforderungen wie Mehrthreading mit pthreads, Signalverarbeitung, Exceptions oder auch atomare Operationen sind in Fil-C vollständig adressiert. Statt „Schlupflöcher“ oder unsichere Konstrukte einzubauen, behandelt Fil-C diese Features konsequent innerhalb seines Sicherheitsmodells. So können auch hochgehandelte Parallelprogramme zuverlässig und sicher mit Fil-C umgesetzt werden.
Die Architektur von InvisiCaps erlaubt es sogar, Integer und Pointer innerhalb von Unions zu tauschen, ohne die Speichersicherheit zu kompromittieren. Tatsächlich erlaubt sie, Pointer-Integer-Konversionen zu erlauben, ohne dass dabei Capabilities verloren gehen oder verfälscht werden, was eine Fähigkeit darstellt, die viele andere Systemsicherheitsansätze nicht unterstützen. FUGC selbst ist ein innovativer Garbage Collector, der auf Konzepte zurückgreift, die in der GC-Forschung schon länger bekannt, aber selten so elegant in realen Projekten umgesetzt wurden. Er kombiniert paralleles Markieren und Aufräumen, nebenläufige Ausführung ohne die Notwendigkeit von Stop-the-World-Pausen, das sogenannte „grey stack“-Verfahren, Dijkstra-Store-Barriers für den sicheren Umgang mit neu erzeugten Referenzen während der Mark-Phase und eine bitvektorgestützte Sweeping-Technik, die das Aufräumen außerordentlich schnell und effizient macht. Die konsequente Integration der Safepoint-Konzeptualisierung gestattet es Fil-C, Threads flexibel zu koordinieren, ohne dass sie unnötig blockiert werden.
Threads können in geschützten Zonen pollchecks ausführen, die vom Garbage Collector genutzt werden, ohne die Programmausführung sichtbar zu beeinträchtigen. Dieses Modell unterstützt auch fortgeschrittene Features wie sichere Signalbehandlung oder Fork-Operationen. Fil-C bietet damit ein umfassendes Sicherheitsmodell, das als „Garbage In, Memory Safety Out“ (GIMSO) bezeichnet wird. Dieses Prinzip garantiert: Selbst wenn der Quellcode unsaubere Zugriffe oder typische C-Fehler enthält, wird zur Laufzeit jeder Verstoß gegen Speicherrechten erkannt und verhindert. Die Laufzeit wird niemals die Grenzen der Speichersicherheit überschreiten lassen, was bisherige Exploits unmöglich macht.
Auch wenn Fil-C derzeit noch nicht in großem Umfang in der Industrie zum Einsatz kommt, stellt es für die Zukunft der Systemsprache C/C++ einen bedeutsamen Fortschritt dar. Es schließt die Sicherheitslücke zwischen den hochperformanten, aber gefährlichen Quellen von Speicherfehlern und der Forderung moderner Softwareentwickler nach robusten und sicheren Programmen. Die Entwicklung von Fil-C zeigt, dass Speichersicherheit in C nicht nur wünschenswert, sondern technologisch realisierbar ist. Zusammenfassend lässt sich sagen, dass Fil-C mit seinen innovativen Konzepten wie InvisiCap und FUGC eine Brücke schlägt zwischen der rohen Performance der Systemsprache C und der erstklassigen Speichersicherheit moderner Programmiersprachen. Für Entwickler, die die Vorteile von C behalten möchten, dabei aber Sicherheitsrisiken radikal minimieren wollen, ist Fil-C ein vielversprechendes Projekt, das es wert ist, entdeckt und unterstützt zu werden.
Die Zukunft von C und C++ könnte dank Fil-C sicherer und gleichzeitig leistungsfähig bleiben – ein Ideal, das durch technische Innovation endlich greifbar wird.