Suche
Codesicherheit

Die 10 Programmier-Gebote der NASA

Redaktion JAXenter

© Shutterstock.com/Alexanderphoto7

Um die Qualität und Sicherheit ihrer Anwendungen zu gewährleisten, hat die NASA eigene Programmierstandards eingeführt. Diese Standards wurden auf Grundlage ihrer eigenen Richtlinien entwickelt und können auch von der Softwareentwicklungsindustrie angewendet werden.

Die NASA kümmerte sich zuletzt gleichermaßen sowohl um ihr ziviles Raumfahrtprogramm als auch um den Fortschritt ihrer Luft- und Raumfahrtforschung. Wenig überraschend also, dass sich ihre eigenen Erfahrungen im Bereich Softwareentwicklung nun in der Veröffentlichung eigener Programmierstandards niedergeschlagen hat. Deren Ausarbeitung wurde dabei vom Laboratory for Reliable Software des Jet Propulsion Laboratory (JPL) in Angriff genommen.

10 Regeln für die Codesicherheit

Dem leitenden Wissenschaftler bei JPL,  Gerard J. Holzmann, zufolge sorgt eine große Anzahl von willkürlichen Regeln und inkonsistenten Richtlinien dafür, dass die Codequalität selbst kritischster Anwendungen leidet. Aus diesem Grund veröffentlichte das Labor 10 „Programmier-Gebote“, die auf sämtliche NASA-Software angewendet werden sollen. Das Team um Holzmann formulierte die Regeln für die Softwareentwicklung dabei mit dem Gedanken an Codesicherheit im Hinterkopf.

Da sie von der NASA schon seit langer Zeit für sicherheitskritischen Code eingesetzt wird und aus diesem Grunde auch über eine entsprechend umfangreiche Werkzeugunterstützung verfügt, wurde C dabei im Besonderen berücksichtigt. Allerdings kann der Richtlinienkatalog auch auf die meisten anderen Programmiersprachen angewendet werden:

1. Beschränke deinen Code auf sehr einfache Kontrollflusskonstrukte. Vermeide also beispielsweise goto-Statements, setjmp-Konstruktionen und direkte oder indirekte Rekursion.

2. Alle Schleifen müssen eine feste Obergrenze haben. Es muss für ein Prüfinstrument auf einfache Art und Weise statistisch beweisbar sein, dass eine festgelegte Obergrenze für die Anzahl von Iterationen einer Schleife nicht überschritten werden kann. Wenn die Schleifengrenze statistisch nicht bewiesen werden kann, gilt die Regel als verletzt.

3. Verwende nach der Initialisierung keine dynamische Speicherzuordnung.

4. Keine Funktion sollte länger sein, als in einem Standard-Referenzformat mit einem Statement pro Zeile und einer Zeile pro Deklaration ausgedruckt auf einem Blatt Papier Platz hat. Normalerweise bedeutet das, dass auf jede Funktion nicht mehr als circa 60 Codezeilen entfallen.

5. Die Assertion-Dichte des Codes sollte durchschnittlich mindestens zwei Assertions pro Funktion umfassen. Assertions werden genutzt, um nach anormalen Bedingungen zu suchen, die in Ausführungen nie vorkommen sollten. Assertions sollen immer frei von Nebeneffekten sein und als Boolesche Tests definiert werden. Wenn eine Assertion fehlschlägt, müssen explizite Recovery-Maßnahmen ergriffen werden. Jede Assertion, der ein statistisches Prüfinstrument nachgewiesen hat, dass sie niemals fehlschlagen oder halten kann, verletzt diese Regel.

6. Datenobjekte müssen mit dem kleinstmöglichen Gültigkeitsbereich deklariert werden.

7. Der Rückgabewert einer non-void-Funktion muss von jeder Aufruffunktion geprüft werden; die Gültigkeit der Parameter muss in jeder Funktion überprüft werden.

8. Die Verwendung des Präprozessors muss sich auf die Einbindung von Header-Dateien und einfache Makro-Definitionen beschränken. Das Einfügen von Tokens, variable Argument-Listen (Ellipsen) und rekursive Makroaufrufe sind nicht erlaubt. Alle Makros müssen zu kompletten syntaktischen Einheiten erweitert werden. Auch wenn sie sich nicht immer vermeiden lassen, gilt die Verwendung von bedingten Kompilierungsdirektiven als zumindest bedenklich. Das heißt, dass selbst in großen Sofwareprojekten nicht mehr als zwei bedingte Kompilierungsdirektiven gerechtfertigt sind. Jede Nutzung sollte durch einen werkzeugbasierten Checker markiert und durch den Code gerechtfertigt werden.

9. Die Verwendung von Zeigern sollte beschränkt werden. Genauer gesagt ist nicht mehr als eine Ebene der Dereferenzierung erlaubt. Zeiger-Dereferenzierungsoperationen dürfen nicht in Makro-Definitionen oder innerhalb von typedef-Deklarationen versteckt werden. Funktionszeiger sind nicht erlaubt.

10. Der gesamte Code muss vom ersten Tag der Entwicklung an kompiliert werden. Dabei müssen alle Compiler-Warnungen in den pedantischsten Compiler-Einstellungen aktiviert sein. Aller Code muss mit diesen Einstellungen ohne Warnungen kompilieren. Der gesamte Code muss jeden Tag mit mindestens einem, bevorzugt jedoch zwei, topmodernen statischen Quellcodeanalysatoren überprüft werden; die Analysen dürfen keine Warnungen produzieren.

Auf den ersten Blick wirkt das Regelwerk als Ganzes sehr strikt, doch wie Holzmann erklärt:

If the rules seem Draconian at first, bear in mind that they are meant to make it possible to check code where very literally your life may depend on its correctness: code that is used to control the airplane that you fly on, the nuclear power plant a few miles from where you live, or the spacecraft that carries astronauts into orbit.

Die Regeln könnten genau der „digitale Sicherheitsgurt“ sein, den die Industrie benötigt. Immerhin wäre es in unserer aller Interesse, weitere IT-Desaster zu vermeiden.

Die Originalmeldung erschien auf Jaxenter.com

Aufmacherbild: KENNEDY SPACE CENTER, CAPE CANAVERAL, FLORIDA, USA – May 3, 2013 – NASA sign at the entrance of the Kennedy Space Center in Cape Canaveral, Florida von Shutterstock.com / Urheberrecht: Alexanderphoto7

Geschrieben von
Kommentare

Hinterlasse einen Kommentar

Hinterlasse den ersten Kommentar!

avatar
400
  Subscribe  
Benachrichtige mich zu: