Microsofts Checked C soll Sicherheitslücken durch Zeigerfehler verhindern

Microsoft arbeitet an einer Erweiterung der Programmiersprache C, die kritische Fehler wie Pufferüberläufe verhindern soll. Die Spezifikation soll in einem offenen Prozess wachsen und steht auf GitHub.

In Pocket speichern vorlesen Druckansicht 211 Kommentare lesen
Microsofts Checked C
Lesezeit: 3 Min.

Software enthält Fehler, und kritische Bugs öffnen Angreifern Hintertüren. Häufig führen falsch verwaltete Zeiger dazu, dass Schadcode Zugriff auf geschützte Speicherbereiche erhält oder Rücksprungadressen verändern kann. Solche Bugs will ein Forschungsprojekt, das Microsoft zusammen mit Michael Hicks und Andrew Ruef von der Universität von Maryland ins Leben gerufen hat und das Checked C heißt, verhindern helfen.

Wer Sprachen wir Java oder C# benutzt, muss sich über die konkrete Speicherverwaltung keine Gedanken machen, da das System die benötigten Variablen einrichtet und aufräumt. Systemsoftware und Dienste benötigen jedoch eine größere Kontrolle und sind daher weitgehend in C oder C++ geschrieben. Entwickler sind dabei selbst für das Bereitstellen und die Nutzung des passenden Speichers verantwortlich. Wenn beispielsweise der angeforderte Speicherbereich kleiner ist als die geschriebenen Daten, kommt es zu Pufferüberläufen und damit zu einer der häufigsten Sicherheitslücken.

Checked C ist eine Erweiterung für C, die neue Zeiger- und Arraytypen einführt, die kompatibel mit den vorhandenen, aber "bounds-checked" sind, also ihre Grenzbereiche überprüfen. Die Zeigertypen können statt dem *-Operator zum Einsatz kommen. Letzterer ist weiterhin erlaubt, bietet aber ungeprüften Zugriff. So greift ptr<T> auf einen Wert vom Typ T zu, array_ptr<T> zeigt auf ein Array aus Werten vom Typ T und span<T> verwaltet den Grenzbereich des Arrays dynamisch. Die neuen Zeiger dürfen wie herkömmliche Pointer bei Bedarf als const oder volatile deklariert werden oder auf solche Typen zeigen. Der folgende Code definiert einen konstanten Zeiger einmal herkömmlich und einmal als neuen Typ:

int n = 3;
int *const p = &n;
const ptr<int> pp = &n;

In dem Beispiel sind die Zeiger p und pp jeweils unveränderlich, während die Variable n, auf die sie verweisen, geändert werden darf. Angenehmer Nebeneffekt der neuen Typen ist die besser Lesbarkeit, bei der const wie bei anderen Variablen am Anfang der Zeile und nicht nach dem *-Operator steht. Überprüfte Arrays definieren Entwickler mit dem Schlüsselwort checked:

int a checked[10];

Die Verwendung von Checked C ist rückwärtskompatibel, sodass vorhandene Programme ohne Änderung funktionieren, aber auf die Sicherheitsprüfung verzichten. Weitere Informationen finden sich auf der Projektseite. Auf GitHub steht die Spezifikation zum Herunterladen bereit. Das Team arbeitet zudem an einer modifizierten clang-Variante zur Implementierung von Checked C in LLVM\clang. Die Initiatoren haben Checked C als offenes, gemeinschaftliches Forschungsprojekt gestartet, sodass jeder eingeladen ist, an der Spezifikation mitzuarbeiten.

Checked C ist ein interessanter Ansatz, das Übel Sicherheitslücken an der Wurzel zu packen, statt die Fehler im Debugger oder mit Codeanalyse aufzuspüren. Es erfordert auf den ersten Blick nur wenige Codeänderungen, vor allem im Verhältnis zur damit zusätzlich erlangten Sicherheit. Je nach den verwendeten Methoden – beispielsweise in der Pointer-Arithmetik – müssen Entwickler jedoch durchaus mehr Hand an vorhandenen Code anlegen als lediglich Variablen neu zu deklarieren.

Anfang Juni 2016 hatte Intel mit der Control-flow Enforcement Technology (CET) ein Konzept zur Bekämpfung ähnlicher Bugs auf Hardwareebene vorgestellt. Es soll Exploits wie ROP (Return Oriented Programming) an der Ausführung hindern, indem das System den Programmverlauf kontrolliert. Die konkrete Umsetzung in Chips wird jedoch noch auf sich warten lassen. (rme)