Stolperfalle Copy & Paste: Kopierte Fehler im Software-Code aufspüren

Autor / Redakteur: Mark Hermeling * / Sebastian Gerstl

Auch wenn es als schlechter Stil gilt, ist Copy&Paste dennoch unter Entwicklern ein gängiges Verfahren zur Code-Wiederverwertung. Doch können dabei auch vorhandene Sicherheitslücken kopiert werden – und neue Fehler entstehen. Die statische Code-Analyse kann helfen, Bugs in kopiertem Code zu vermeiden.

Anbieter zum Thema

Einmal verwendete Codeschnipsel kann man mit Copy&Paste schnell wieder nutzen - oder? Wenn etwa Anpassungen in Variablen vergessen werden, schießt sich ein Entwickler schnell neue Bugs und Sicherheitslücken in die Software. Statische Analyse kann helfen, nachlässig kopierte Code-Stellen aufzuspüren.
Einmal verwendete Codeschnipsel kann man mit Copy&Paste schnell wieder nutzen - oder? Wenn etwa Anpassungen in Variablen vergessen werden, schießt sich ein Entwickler schnell neue Bugs und Sicherheitslücken in die Software. Statische Analyse kann helfen, nachlässig kopierte Code-Stellen aufzuspüren.
(Bild: Clipdealer)

Vorhandenen Code weiter zu verwenden, ist sparsam genutzt ein sinnvoller Ansatz. Der Code hat in der Regel seine Funktionalität bewiesen, wenn es um die Lösung eines speziellen Problems geht. Und letztlich sind viele Anforderungen in der Software-Entwicklung nicht komplett neu, sondern Variationen bereits gelöster Aufgaben. Was liegt also näher, als bereits fertigen Code zu nehmen und anzupassen? Es spart – vordergründig – Zeit und Geld und bringt schnelle Erfolge, wenn die Performance der Entwickler in Code-Zeilen gemessen wird.

Um Code mehrfach zu verwenden, ist eigentlich einiges an Aufwand notwendig. Der Code sollte in eine generische Form überführt, gut dokumentiert und zudem hinreichend getestet sein. In der Praxis ist jedoch kaum Zeit für diese Schritte. So machen viele Entwickler das, was eigentlich als schlechter Programmierstil gilt: Sie kopieren vorhandene Code-Teile und fügen sie an anderer Stelle wieder ein. Ein paar Anpassungen, etwa bei den Variablen, und fertig ist ein Stück der Arbeit. Die Schattenseite: Auch im Code vorhandene Fehler werden kopiert. Und durch manuelle, inkonsistente Anpassungen schleichen sich neue, unter Umständen gravierende Bugs ein. Bei kleineren Code-Schnipseln ist das relativ harmlos, diese können ohne übermäßigen Aufwand vom Entwickler untersucht werden. Bei größeren Bausteinen, eventuell sogar ohne ausführliche Dokumentation, ist das Verfahren jedoch riskant. Erst recht bei sicherheitskritischen Systemen.

Bildergalerie
Bildergalerie mit 5 Bildern

Das größte Risiko bei kopiertem Code sind Inkonsistenzen

Das größte Risiko bei kopiertem Code stellen die manuellen Anpassungen dar, die fast immer notwendig sind, wenn Code-Teile mehrfach genutzt werden sollen. Hier treten oft Inkonsistenzen auf, vor allem beim Ersetzen der Variablen. Ein recht typisches Beispiel dafür wurde etwa im freien Video-Transcoder FFmpeg gefunden: Der Code wurde nach dem Kopieren nicht vollständig geändert, an einer Stelle blieb das ursprüngliche Feld dts anstelle des korrekten pts stehen (siehe Bild 2).

Diese Probleme zu erkennen ist manuell fast nicht möglich. Und auch für automatische Tools ist es eine erhebliche Herausforderung. Denn das Tool muss erst einmal erkennen, ob kopierte Code-Teile in der Software vorhanden sind. CodeSonar, das Tool zur statischen Analyse von GrammaTech, ist dazu in der Lage. Dazu muss das Tool zunächst Muster finden, die auf wiederverwerteten Code schließen lassen. Dabei sind unvollständig ersetzte Variablen ein wichtiger Indikator.

Ein vereinfachtes Beispiel: Ein Template der Form s(p0, p1, p2, p3, p4, p5) wird als s(A, B, C, D, E, F) instanziiert, das Ergebnis könnte sein: A B C C A D E B F C. Ein korrekte Kopie mit s(A, B, X, D, E, F)wäre dann A B X X A D E B F X. Das Muster ist eindeutig als Kopie erkennbar. Eine Inkonsistenz, zum Beispiel beim dritten Parameter p2, könnte dann so aussehen: A B X C A D E B F X. Das Erkennen der Kopie ist schwieriger. Zudem ist vorhandene die Inkonsistenz nur ein Hinweis von vielen. Um mit hinreichender Sicherheit auf einen Fehler zu schließen, reicht dieses Indiz nicht – es besteht schließlich eine gewisse Wahrscheinlichkeit, dass der Entwickler dieses mit Absicht gemacht hat.

Um ein Übermaß an False Positives auszuschließen, kommen weitere Analysen zum Einsatz. Einer der stärksten Indikatoren dabei ist die so genannte Pluralität: In welchem Maß übertreffen die korrekten Ersetzungen die Fehler? Unterschiedliche Fehler werden dabei auch unterschiedlich gewichtet, da sie als Indiz verschiedene Relevanz haben. Dabei gilt zunächst die Annahme, dass der Code-Teil mit den vermeintlich konsistenten Ersetzungen korrekt ist. Ob diese Annahme richtig ist, zeigt sich unter anderem daran, ob die vom Analyse-Tool vorgeschlagenen Änderungen zu einem lauf- und kompilierfähigen Code führen. Über heuristische Annäherungen ist es möglich, mit hoher Zuverlässigkeit zwischen versehentlichen und beabsichtigten Inkonsistenzen zu unterscheiden. Als weitere Instanz nutzt CodeSonar zudem möglicherweise vorhandene Änderungen am Code, die mit dem kopierten Code-Teil zusammenhängen: Häufig tritt eine semantische Änderung in mehreren, unterschiedlichen lexikalischen Formen auf. Diese können Hinweise darauf geben, ob eine Änderung konsistent vorgesehen war oder nicht.

Copy&Paste-Fehler häufiger, als man denkt

Copy&Paste-Fehler treten häufig auf, auch in bekannten Anwendungen. Kein Entwicklungsteam ist davor gefeit. Bei internen Tests konnte GrammaTech über 20 bestätigte und fünf noch zu überprüfende Bugs in sieben verschiedenen Open-Source-Paketen finden. Dazu zählen der Linux-Kernel, MySQL, Wine, Postgres und Python. Manche dieser Fehler halten sich hartnäckig. So wird vermutet, dass ein bestimmter Code zur Implementierung einer Linked-List-Class ohne den Einsatz von Templates oder Makros bereits unzählige Male kopiert wurde. Der Schönheitsfehler dabei ist, dass der ursprüngliche Entwickler einen Punkt übersehen hatte: Der Code gibt den Speicher nicht frei, wenn ein Item gelöscht wurde, sondern ordnet nur die Pointer neu. Manchmal wird dieser Fehler entdeckt und behoben, manchmal nicht.

Grundsätzlich sollten Entwickler bei Copy&Paste also größte Vorsicht walten lassen. Denn der mögliche Gewinn an Zeit und Ressourcen ist überschaubar: Das reine Schreiben des Codes ist der kleinste Teil des Entwicklungsaufwands. Mit jeder kopierten Instanz hingegen steigt der Wartungsaufwand. Ein einmal entdeckter Fehler muss in allen Kopien des betroffenen Codes bereinigt werden, was ab einem gewissen Punkt kaum mehr zu leisten ist. Wenn kopierter Code jedoch in einem Projekt benötigt wird, kann die statische Analyse dabei helfen, vorhandene Fehler und inkonsistente Anpassungen frühzeitig zu finden. Und je früher Fehler erkannt und beseitigt werden, desto geringer ist der dafür notwendige Aufwand – sowohl aus Zeit- als auch aus Kostensicht.

* Mark Hermeling ist Senior Director Product Marketing bei GrammaTech, Inc.

(ID:45480095)