Forum: PC-Programmierung CaVer: Neue Technik findet Schwachstellen in C++-Code


von Kaj G. (Firma: RUB) (bloody)


Lesenswert?

http://www.heise.de/newsticker/meldung/CaVer-Neue-Technik-findet-Schwachstellen-in-C-Code-2778993.html

Finde ich sehr interessant, Besonders die Aussage:
1
Statt static_cast, das die Cast-Operation zur Übersetzungszeit prüft,
2
könnten Entwickler dynamic_cast verwenden: Es kontrolliert die
3
Vererbungshierarchie zur Laufzeit und verweigert fehlerhafte Downcasts.
4
Die Prüfung ist jedoch zeitaufwendig, weshalb zum Beispiel Mozilla
5
dynamic_cast in Firefox-Code verbietet.
6
7
...
8
9
Ein mit CaVer übersetzter Chrome-Browser läuft nach Angaben der
10
Wissenschaftler rund 7 Prozent langsamer, Firefox über 64 Prozent langsamer.
11
In Googles Browser prüfte es dabei rund 150.000 Cast-Operationen, bei
12
Firefox waren es über 1 Million.
Bei sovielen casts ist es kein wunder, wenn da mal was schief geht.
Schlimmer finde ich allerdings, das ein Sprachmittel, was die Sprache 
sicherer macht, verboten wird.

von Planlos (Gast)


Lesenswert?

Kaj G. schrieb:
> Schlimmer finde ich allerdings, das ein Sprachmittel, was die Sprache
> sicherer macht, verboten wird.

Das wiederum ist durchaus verständlich.
Sobald irgendwo im Code ein "dynamic_cast" verwendet wird, muss quer 
durch alles mit RTTI kompiliert werden. d.H. ein einziger Cast in nur 
einem Source-File, auch wenn er nie ausgeführt wird, macht potentiell 
alles andere langsamer, verschwendet Speicher usw.

RTTI ist beim GCC z.B. jetzt recht gut implementiert, mit minimalem 
Overhead. Das muss aber nicht bei allen Compilern so sein.

von Torsten R. (Firma: Torrox.de) (torstenrobitzki)


Lesenswert?

Kaj G. schrieb:
> Bei sovielen casts ist es kein wunder, wenn da mal was schief geht.
> Schlimmer finde ich allerdings, das ein Sprachmittel, was die Sprache
> sicherer macht, verboten wird.

Die Verwendung von `dynamic_cast` ist häufig ein Hinweis auf ein 
kaputtes design. Nicht jeder dynamic_cast kann durch einen static_cast 
ersetzt werden.

Wenn er ersetzt werden kann, dann macht er bei fehlerfreier Software 
funktional auch keinen Unterschied, er benötigt aber mehr Ressourcen.

Wenn er Software-Fehler finden soll, dann würde man ihn ggf. wie ein 
assert einsetzen:
1
template < class T, class S >
2
T* static_debug_cast( S* s )
3
{
4
    assert( dynamic_cast< T* >( s ) );
5
    return static_cast< T* >( s );
6
}

mfg Torsten

von Karl H. (kbuchegg)


Lesenswert?

Kaj G. schrieb:

> Bei sovielen casts ist es kein wunder, wenn da mal was schief geht.
> Schlimmer finde ich allerdings, das ein Sprachmittel, was die Sprache
> sicherer macht, verboten wird.

?
Falscher Ansatz.
Wenn in einem Programm exzessiv gecastet werden muss, dann ist am Design 
was faul!
In einem gut entworfenem C++ Programm kommen fast keine expliziten Casts 
vor.

von Planlos (Gast)


Lesenswert?

Karl H. schrieb:
> In einem gut entworfenem C++ Programm kommen fast keine expliziten Casts
> vor.

Wobei ich mir grad bei einem Browser und den durch DOM vorgegebenen 
Strukturen vorstellen kann, dass upcasts öfter mal nötig sind.

Aber: die DOM-Elemente enhalten sowieso Infos über Ihre "Class" in einem 
Member, führen also ihr eigenes "RTTI-Light" mit.

Dann sind alle Stellen, bei denen ein dynamic_cast ein anderes Ergebis 
als ein static_cast bringt, Hinweise auf einen handfesten Fehler.
==> Die "assert"-Lösung von Thorsten hift.

von Karl H. (kbuchegg)


Lesenswert?

Planlos schrieb:
> Karl H. schrieb:
>> In einem gut entworfenem C++ Programm kommen fast keine expliziten Casts
>> vor.
>
> Wobei ich mir grad bei einem Browser und den durch DOM vorgegebenen
> Strukturen vorstellen kann, dass upcasts öfter mal nötig sind.

Öfter mal, ok.
Aber nicht 1 Million

von Torsten R. (Firma: Torrox.de) (torstenrobitzki)


Lesenswert?

Karl H. schrieb:
> Öfter mal, ok.
> Aber nicht 1 Million

Naja, wer weis, wie die gezählt haben. Vielleicht ist da ein cast in 
einem häufig verwendeten Macro.

von Karl H. (kbuchegg)


Lesenswert?

https://labs.mwrinfosecurity.com/blog/2013/04/19/mwr-labs-pwn2own-2013-write-up---webkit-exploit/

Sag ich doch: Designfehler.

Entweder in einem SVG Document ist alles ein SVGElement oder ich kann 
das so nicht Casten. Wenn aber alles ein SVGElement ist, dann brauch ich 
den Cast in erster Linie gar nicht, weil von getElementById gar nichts 
anderes als ein SVGElement oder eien davon abgeleitete Klasse zurück 
kommen kann. Wozu daher Casten?

Wenn es möglich ist, in SVG ein foreignObject einzubetten, dann muss 
dies ebenfalls in Form eines SVGElements geschehen. Dann gibt es eben 
ein von SVGElement abgeleitetes SVGForeignObjectElement, welches als 
Proxy für das foreignObject fungiert.
Da ist nichts Geheimnisvolles dabei und es ist seit langem bekannt wie 
man solche Dinge löst.

Das Problem ist, dass viele Programmierer, gleich nachdem sie den Cast 
entdecken, den für die Lösung aller Probleme halten. Ich sitze auch 
gerade an so einem Programm, an dem mein (Anfänger) Vorgänger meinte 
alles und jeden umcasten zu müssen. Leider hat er sich dabei ein paar 
mal ein absolut notwendiges 'huge' weggecastet. Die Folge sind 
sporadische Speicherüberschreiber bzw. Zugriff auf falsche Werte, weil 
dann eben manchmal das Segmentregister doch nicht den Inhalt hat, den er 
gerne hätte. Das Pikante daran: nimmt man den Cast weg, dann warnt der 
Compiler auch brav, dass hier eine Pointerverkürzung statt findet.
Casts sind Waffen! Genauso wie _delay_ms in der AVR Programmierung sind 
sie oft nicht die Lösung sondern das Problem. Und genau so muss man sie 
dann auch behandeln.
Wenn ein Compiler einen Pointer Datentyp Mismatch anzeigt, dann ist 
manchmal ein Cast eine Lösung. Meistens aber nicht.

: Bearbeitet durch User
von Tom (Gast)


Lesenswert?

Karl H. schrieb:
> Wenn in einem Programm exzessiv gecastet werden muss, dann ist am Design
> was faul!
> In einem gut entworfenem C++ Programm kommen fast keine expliziten Casts
> vor.

Wenn man fremde Libraries (deren APIs grundsätzlich von betrunkenen 
Schimpansen entworfen werden) benutzen muss, verschwinden alle guten 
Vorsätze und man castet die schöne const-Korrektheit und viele andere 
gute Ideen aus dem eigenen Programm weg, damit es compiliert.

von Karl H. (kbuchegg)


Lesenswert?

Tom schrieb:
> Karl H. schrieb:
>> Wenn in einem Programm exzessiv gecastet werden muss, dann ist am Design
>> was faul!
>> In einem gut entworfenem C++ Programm kommen fast keine expliziten Casts
>> vor.
>
> Wenn man fremde Libraries (deren APIs grundsätzlich von betrunkenen
> Schimpansen entworfen werden) benutzen muss, verschwinden alle guten
> Vorsätze und man castet die schöne const-Korrektheit und viele andere
> gute Ideen aus dem eigenen Programm weg, damit es compiliert.

Ich gestehe zu, dass man an Schnittstellen des öfteren nicht umhin 
kommt, die Dinge zurecht zu casten. Aber das ist relativ isoliert. Wenn 
ich auf einer mittleren Programmebene rumcasten muss wie ein Wilder, 
dann ist das praktisch immer ein Hinweis auf einen Designfehler.

von Nase (Gast)


Lesenswert?

Karl H. schrieb:
> Wenn
> ich auf einer mittleren Programmebene rumcasten muss wie ein Wilder,
> dann ist das praktisch immer ein Hinweis auf einen Designfehler.

Dann guck besser mal nicht in die Quellen von Qt rein...

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.