Funktionale Sicherheit über den Entwicklungs-Lebenszyklus hinaus sicherstellen

Autor / Redakteur: Mark Pitchford * / Sebastian Gerstl

Im Zeitalter konstant mit dem Internet verbundener Systeme kann Softwareentwicklung nie als endgültig abgeschlossen betrachtet werden – sobald eine neue Sicherheitslücke auftaucht, muss diese auch sofort geschlossen werden. Wie bekommt man diesen Kreislauf in den Griff?

Anbieter zum Thema

Bild 1: V-Modell der Softwareentwicklung mit Bezugnahmen auf ISO 26262 und Standard-Entwicklungstools
Bild 1: V-Modell der Softwareentwicklung mit Bezugnahmen auf ISO 26262 und Standard-Entwicklungstools
(Bilder: LDRA)

Wenn Sie Software entwickeln, die funktional sicher sein muss, ist die bidirektionale Rückverfolgbarkeit der Anforderungen enorm wichtig. Mit dieser wird sichergestellt, dass das Design die Anforderungen widerspiegelt, die Softwareimplementierung dem Design entspricht und die Prüfprozesse die korrekte Implementierung bestätigen. Ebenso muss klar sein, welche Folgewirkungen von geänderten Anforderungen ausgehen, denn Sie müssen herausfinden, welcher Code sich ändert und welche Tests zu wiederholen sind. Dieser Zyklus endete mit der Abgabe des Produkts; von etwaigen kleinen Nachbesserungen abgesehen war die Entwicklung abgeschlossen.

Bei den heute verfügbaren vernetzten Systemen ändern sich allerdings die Anforderungen immer weiter, wann immer eine neue Schwachstelle aufgedeckt wird oder ein Hacker einen neuen Angriff entwickelt. Dies kann jederzeit passieren, solange das System im Einsatz ist. Sobald Änderungen erforderlich werden, muss der überarbeitete Code statisch analysiert werden, und auch alle betroffenen Modul- und Integrationstests müssen erneut durchgeführt (regressionsgetestet) werden. Jede neu entdeckte Schwachstelle bringt eine geänderte oder neue Anforderung hervor, auf die natürlich umgehend reagiert werden muss, auch wenn das System selbst von den Entwicklungsingenieuren schon lange nicht mehr in die Hand genommen wurde.

Bildergalerie

Dies verändert das Wesen der Produktinstandhaltung und verleiht den Tools und Techniken für die automatische Rückverfolgung der Anforderungen (Requirements Traceability) einen neuen Stellenwert. Durch die Verknüpfung der Anforderungen, des Codes, der Ergebnisse der statischen und dynamischen Analyse sowie der Tests auf Modul- und System-Ebene wird der gesamte Softwareentwicklungszyklus rückverfolgbar. Für die Teams wird es so einfach, Probleme zu identifizieren und Lösungen schneller und kosteneffektiver zu implementieren – auch nach der Markteinführung des Produkts.

Prozesszielsetzungen und Prozessphasen

Wir ziehen im Folgenden die Funktionssicherheits-Norm ISO 26262 aus dem Automobilbereich als Beispiel heran, jedoch lassen sich die gleichen Grundsätze auch auf andere safety-kritischen Branchen und Normen wie DO-178C, IEC 61508 oder IEC 62304 anwenden. Allen gemeinsam ist die Praxis, die an die Hard- und Software gestellten Funktionssicherheits-Anforderungen zu spezifizieren und sicherzustellen, dass diese vom Design, der Implementierung und den Tests abgedeckt werden. Bild 1 illustriert die Beziehungen zwischen der Norm ISO 26262 und ihren softwarespezifischen Subphasen.

In der Systemdesigns-Phase geht es um die genauere Ausarbeitung der Anforderungen in Sachen Funktion, Security und funktionale Sicherheit sowie die Abbildung dieser Anforderungen auf die Hard- und Software. Bei den daraus resultierenden Artefakten handelt es sich um CAD-Zeichnungen, Spreadsheets und Textdokumente in einer derartigen Vielfalt an Formaten, dass das Wahren der Rückverfolgbarkeit zwischen den Anforderungen und den sich anschließenden Phasen dem Projektmanagement echte Kopfschmerzen bereitet.

Das Spektrum der idealen Werkzeuge für das Anforderungsmanagement reicht von einfachen Spreadsheets oder Microsoft-Word-Dokumenten bis zu speziell entwickelten Requirements Management Tools wie IBM Rational DOORS Next Generation oder Siemens Polarion REQUIREMENTS. Auf jeden Fall ist die Entscheidung für die richtigen Tools hilfreich für das Sicherstellen der bidirektionalen Rückverfolgbarkeit zwischen den verschiedenen Entwicklungsphasen.

Anforderungen an die Sicherheit der Software

Diese Teilphase konzentriert sich auf das Spezifizieren der Anforderungen an die funktionale Sicherheit der Software, um die nachfolgenden Designphasen zu unterstützen. Sie bildet die Schnittstelle zwischen dem für das gesamte Produkt geltenden Systemdesign-Standard und den softwarespezifischen Anforderungen, wobei auf die zuvor verwendeten Requirements Management Tools zurückgegriffen werden dürfte.

Design der Software- Architektur

Die Implementierung von Softwarearchitektur-Artefakten beispielsweise aus MathWorks Simulink, IBM Rational Rhapsody und ANSYS SCADE kann in einer späteren Entwicklungsphase mithilfe der Kontroll- und Datenfluss-Analyse verifiziert werden, um zum Vergleich mit dem Design grafische Darstellungen der Beziehung zwischen den Codekomponenten zu erstellen.

Bild 2 ist kennzeichnend für die Tabellen in der Norm ISO 26262-6:2011. Gezeigt werden die Codier- und Modellierrichtlinien, die bei der Implementierung durchzusetzen sind – hier ergänzt durch eine Angabe, an welchen Stellen automatisierte Tools helfen können.

Implementierung der Software-Module

Die Befolgung dieser Richtlinien sorgt dafür, dass der Code nicht nur zuverlässiger und weniger fehleranfällig, sondern auch einfacher zu prüfen und zu pflegen ist. Zwar kommt den Peer Reviews weiterhin eine große Bedeutung zu. Aber das Automatisieren dieser mühsamen Checks ist weit effizienter, reproduzierbarer, besser nachweisbar und weniger fehleranfällig. Sprach-Teilmengen können intern oder durch Industriestandards wie MISRA oder CERT C vorgegeben werden – möglicherweise mit zusätzlichen projektspezifischen Anpassungen.

Jetzt Newsletter abonnieren

Verpassen Sie nicht unsere besten Inhalte

Mit Klick auf „Newsletter abonnieren“ erkläre ich mich mit der Verarbeitung und Nutzung meiner Daten gemäß Einwilligungserklärung (bitte aufklappen für Details) einverstanden und akzeptiere die Nutzungsbedingungen. Weitere Informationen finde ich in unserer Datenschutzerklärung.

Aufklappen für Details zu Ihrer Einwilligung

Neben der definitiven Markierung etwaiger Verletzungen von Codierregeln oder Designprinzipien liefern statische Analysetools Komplexitäts-, Kohäsions- und Kopplungs-Kennzahlen (Bild 3), die genauer Auskunft über die Qualität des Codes geben können. In der Praxis entwickelt sich die Rolle eines solchen Tools mit der Zeit von einer Lernhilfe zu einem Mittel zur Bestätigung eines hohen Qualitätsniveaus.

Software-Modultests und Test sowie Integration der Software

Dynamische Analysetechniken (Modul-, Integrations- und Systemtests) sehen die Ausführung des Codes vor, während es bei statischen Analysetechniken um eine automatisierte „Inspektion“ des Codes geht. Modultests sind gezielt auf bestimmte isolierte Softwareprozeduren oder Funktionen fokussiert. Die Integrationstests stellen sicher, dass die Anforderungen eingehalten werden, wenn alle Module zusammenarbeiten.

Die Norm ISO 26262-6:2011 listet Techniken und Kennzahlen für die Durchführung von Modul- und Integrationstests an der Ziel-Hardware auf. Fehlereinstreuung und Ressourcentests weisen zusätzlich die Robustheit und Resilienz nach und sorgen gegebenenfalls für die Back-to-Back-Prüfung von Modell und Code, um die korrekte Interpretation des Designs nachzuweisen. Die mit diesen Techniken zusammenhängenden Artefakte dienen als Referenz für ihr Management und als Nachweis für ihre Fertigstellung. Es handelt sich bei diesen Artefakten um die Softwaremodul-Designspezifikation, die Testprozeduren, den Verifikationsplan und die Verifikations-Spezifikation. Mit dem Abschluss einer jeden Testprozedur werden Pass/Fail-Resultate gemeldet, und die Einhaltung der Anforderungen wird entsprechend verifiziert.

Bildergalerie

Vom Software-Modultest zum Integrationstest

Das Beispiel in Bild 4 macht deutlich, wie ein Test-Tool hier helfen kann. Das Softwareinterface wird auf der Funktionsebene exponiert, sodass der Anwender Eingaben und erwartete Ausgaben als Basis für ein Test Harness eingeben kann. Der Test Harness wird anschließend kompiliert und auf der Ziel-Hardware ausgeführt, woraufhin die erwarteten und tatsächlichen Ausgaben verglichen werden können.

Modultests werden zu Integrationstests, wenn ein Aufrufbaum ausgeführt und nicht mit Stubs umgesetzt wird. Folglich kann man in beiden Fällen die gleichen Testdaten zur Validierung verwenden. Diese anforderungsbasierten Tests generieren Structural-Coverage-Kennzahlen um zu zeigen, welcher Anteil des Codes ausgeführt wurde, und um nachzuweisen, dass keine nicht gewünschten Funktionalitäten vorhanden sind.

Die gebotenen Kennzahlen können sich auf Funktionen, Aufrufe, Anweisungen, Verzweigungen und die MC/DC Coverage beziehen. Modul- und Systemtest-Einrichtungen können gemeinsam operieren, sodass die Coverage-Daten für den Großteil des Quellcodes durch einen dynamischen Systemtest generiert und anschließend durch Modultests ergänzt werden können. Dies spricht beispielsweise jegliche defensiven Konstrukte an, die während des regulären Systembetriebs nicht zugänglich sind. Sollten Änderungen notwendig werden – sei es infolge eines fehlgeschlagenen Tests oder als Reaktion auf eine modifizierte Anforderung –, können sämtliche betroffenen Modul- und Integrationstests einfach wiederholt (regressionsgeprüft) werden. Die Modultests lassen sich zum Nachweis der Robustheit ausweiten, indem man die Eingangsdaten automatisch generiert und mit Grenzwerten und Äquivalenz-Grenzwerten zusammenhängenden Testfälle ausführt.

Die Bedeutung bidirektionaler Rückverfolgbarkeit

Die bidirektionale Rückverfolgbarkeit setzt voraus, dass jede Entwicklungsphase exakt die jeweils vorangehende Phase widerspiegelt. Wenn die exakte Abfolge des V-Modells eingehalten wird, werden sich die Anforderungen theoretisch niemals ändern, sodass die Tests niemals ein Problem aufdecken. Die Realität ist freilich anders.

Was passiert im Fall einer Codeänderung als Reaktion auf einen fehlgeschlagenen Integrationstest – möglicherweise deshalb, weil die Anforderungen nicht stimmig sind oder weil ein Codierfehler vorliegt? Es ist zu fragen, welche anderen Softwaremodule von dem geänderten Code abhängig waren. Aus solchen Szenarien können schnell Situationen entstehen, in denen die Rückverfolgbarkeit zwischen den Produkten der Softwareentwicklung verlorengeht.

Softwaredesigns müssen bidirektional rückverfolgbar sein – also sowohl auf die Software-Anforderungen als auch auf die Softwarearchitektur. Die Softwaremodule werden dann spezifikationsgemäß und zum Design rückverfolgbar implementiert. Automatisierte „Requirements Traceability Tools“ stellen Beziehungen zwischen Anforderungen und Testfällen her, was ein Ermitteln der Testabdeckung gestattet (Bild 5). Die Auswirkungen von fehlgeschlagenen Testfällen, geänderten Anforderungen und einer unzureichenden Anforderungs-Abdeckung lassen sich erfassen und adressieren. Zudem können Artefakte wie zum Beispiel Rückverfolgbarkeits-Matrizen automatisch erzeugt werden, um Nachweise für die Einhaltung der jeweiligen Norm zu erbringen.

Die anfängliche strukturelle Abdeckung entsteht in der Regel im Rahmen dieses Prozesses, aus der Ausführung des Funktionstests auf instrumentiertem Code. Dabei werden nicht ausgeführte Abschnitte des Codes, die einer weiteren Analyse bedürfen, aufgedeckt. Dies führt zur Hinzufügung oder Modifikation von Testfällen, zu Änderungen an den Anforderungen und zur Entfernung von totem Code. In der Regel stellt eine iterative Abfolge aus Prüfung, Korrektur und Analyse sicher, dass die Designspezifikationen eingehalten werden.

Automatisierung der funktionalen Sicherheit während des Entwicklungs-Lebenszyklus und darüber hinaus

Obwohl Prozess-Standards in erheblichem Umfang zur Safety und Security beitragen, bringen sie zweifellos auch Aufwand mit sich. Der Einsatz automatisierter Tools während des gesamten Entwicklungs-Lebenszyklus kann entscheidend zur Verringerung eben dieses Aufwands beitragen und gleichzeitig einen großen Teil des Risikos für menschliche Fehler beseitigen. Dies ist heute von nie dagewesener Bedeutung.

MArk Pitchford, LDRA
MArk Pitchford, LDRA
(Bild: LDRA)

Mit dem Einzug der Vernetzung endet der Entwicklungsprozess nicht mehr mit der Einführung eines Produkts. Sobald im Feld eine neue Sicherheitslücke entdeckt wird, wird eine Änderung der Anforderungen notwendig. Die erforderliche Reaktion verstärkt die Forderung nach Automatisierung nicht nur während des Entwicklungs-Lebenszyklus, sondern auch danach.

Der Autor

* Mark Pitchford erwarb seinen Abschluss als Bachelor of Science an der Trent University, Nottingham, und ist seit mehr als 20 Jahren Diplomingenieur. Von 2007 bis 2014 arbeitete er als FAE bei LDRA. Im Anschluss wechselte er als Technical Manager für den Bereich EMEA zu Lynx Software Techno¬logies, bevor er im Februar 2017 zu LDRA zurückkehrte. Dort ist er als Tech¬nical Specialist tätig.

(ID:45583548)