Geschwindigkeit vs. Sicherheit



  • groovemaster schrieb:

    [Das übliche: Man kann in C++ sicher programmieren, keiner zwingt einen, was mit Pointer-Arithmetik und Arrays zu machen und das ist ja so schön, dass man es sich genau aussuchen kann]

    In der Praxis funktioniert das nicht. Dazu braucht man eigentlich nur kurz einen Blick in die Welt hinaus werfen und sieht Sicherheitsprobleme hier und Sicherheitsprobleme da.

    Natürlich muss man da differenzieren. Es gibt Sicherheitsprobleme, die man mit keiner Sprache der Welt verhindern kann. Aber ein erstaunlich hoher Anteil sind buffer overruns, eine Trivialität eigentlich. Da hilft aber kein std::vector dagegen, denn die Ursachen sind meistens viel tiefgründiger als direkt ein falsch gesezter Index.

    Das können Fehler im Speicher-Management sein zum Beispiel ein Objekt zweimal gelöscht. Oder Funktionen, die nichts zurückgeben (== einen uninitialisierten Speicherblock zurückgeben), was C++ ja genialerweise erlaubt. Oder generell uninitialisierte lokale Variablen, was C++ ja genialerweise erlaubt (schön, dass man die Möglichkeit hat). Und überhaupt generell alles wofür der GEILE C++ Standard "undefiniertes" (== unsicheres) Verhalten vorsieht.

    Und wenn man sich ansieht, wo BEISPIELSWEISE Java (hier kann man eigentlich fast alle Sprachen die ich kenne einfügen) undefiniertes Verhalten vorsieht, dann ist doch klar, dass es auf Sprachebene die Möglichkeit gibt, sichere Programme zu begünstigen.

    Natürlich ist es möglich, auch in C++ ein fehlerfreies Programm zu entwickeln. Auch in einer beliebigen Assembler-Sprache und in Brainfuck ist es möglich. C++ und die anderen Alternativen (;)) haben aber ein paar Eigenarten, die das nicht gerade unterstützen und da Menschen programmieren, passieren Fehler.



  • groovemaster schrieb:

    Und das ist ja das schöne an C++. Du programmierst vollkommen ohne Overhead, und vertraust darauf, dass dich deine Programmierkünste nicht im Stich lassen. Oder du verwendest etwas Sicheres, weil du davon überzeugt bist, dass irgendwo schon ein Fehler sein wird oder dein Produkt diese Sicherheit einfach verlangt. Musst dann aber mit dem Overhead leben. Niemand zwingt dich zu irgendetwas. Für dich mag das ein Fluch sein, für andere ein Segen. Was gibt dir eigentlich das Recht, darüber zu urteilen?

    Dieser Segen sorgte halt bis dato für zahllose Sicherheitslücken und gott-weiss wieviel Milliarden Dollar Schaden. Aber offenbar war das alles bloß von Newbs zusammengefrickelter Code, während die Sicherheitsexperten alle hier im Forum sitzen. 🙄 😉



  • rüdiger schrieb:

    "Sicherheit von Bufferoverflows"? Und was hat das ganze mit C++ zu tun und was soll Java da besser machen?

    Ja entschuldigung, Sicherheit VOR buffer overflows. 🙄



  • Das können Fehler im Speicher-Management sein zum Beispiel ein Objekt zweimal gelöscht

    Smartpointer? Ist mittlerweile offizielle iSO-C++ bekannt! Kann ich garnicht ausversehen zweimal löschen. Klar, wenn ich rohe Pointer nutze. Stimmt.

    Oder Funktionen, die nichts zurückgeben (== einen uninitialisierten Speicherblock zurückgeben),

    Verstehe ich ehrlich gesagt nicht. Meinst du wenn ich Null zurück bekomme? Was hat das mit Sicherheit zutun?

    Da hilft aber kein std::vector dagegen, denn die Ursachen sind meistens viel tiefgründiger als direkt ein falsch gesezter Index.

    Beispiel?

    Oder generell uninitialisierte lokale Variablen, was C++ ja genialerweise erlaubt (schön, dass man die Möglichkeit hat).

    Und? Geht auch in Java. Bekomme ich halt nen Warning vom Compiler, macht aber mein MSVC7.1 auch!



  • groovemaster schrieb:

    Taschenlampe schrieb:

    Sind das nicht genau die Sachen, die Hacker nutzen um irgendwo Code hinzubringen?

    Das sind Bufferoverruns, wo lokale Arrays durch einen Fehler in der Anwendungen über das Ende hinaus beschrieben werden können, so dass die Rücksprungadresse der Funktion, welche sich auf dem Stack nach oben hin befindet, manipuliert wird. Bufferunderruns sind mir ehrlich gesagt in Verbindung mit C++ und Sicherheit unbekannt. Deshalb wollte ich es halt wissen. Ich kenne das nur im Zusammenhang mit dem Brennen von CDs.

    Das gibt es auch in Verbindung mit der Sicherheit von Software. ...beschreibt halt den gleichen Vorgang auf der anderen Seite des Arrays.

    ...Google präsentiert einem da bei einer passenden Suche gleich mal so ne Sicherheitslücke:

    http://archive.cert.uni-stuttgart.de/archive/win-sec-ssc/2006/09/msg00080.html schrieb:

    CVE-2006-4336 - Schwachstelle in gzip

    In gzip besteht eine Schwachstelle in der Funktion build_tree() in der Datei unpack.c. Eine Variable wird nicht richtig ueberprueft, was dazu fuehrt, dass eine defekte Leaf Count Tabelle mit einem negativen Index erzeugt wird (Buffer Underrun). Dadurch koennen Daten vor dem Puffer ueberschrieben werden. Ein entfernter Angreifer kann, indem er ein manipuliertes gzip Archiv zur Verfuegung stellt, diese Schwachstelle ausnutzen und das Programm zum Absturz bringen oder eventuell beliebigen Code mit den Rechten des Benutzers ausfuehren.

    ...ok, war da wohl C und nicht C++. 😉



  • Otze schrieb:

    Das jahr 2000 problem, halt nur mit 32 bit

    Bei Java: Das jahr 2000 problem, halt nur mit 64 bit.



  • Wenn ein Guru wie volkard von 15-20 Jahren spricht, nach denen man ordentlich C++ programmieren kann ist doch das absolute Killerargument schon genannt worden. Eine Sprache die eine längere Schulungsdauer als 6 Monate hat (aufbauend auf bisherigen Programmiererfahrungen) fällt in der Wirtschaft schon weg. Wurde halt leider gehyped bis zum geht nicht mehr, aber das passiert bei mehr Sprachen.

    In 10 Jahren wirds wieder was neues geben.

    MfG SideWinder



  • Artchi schrieb:

    Otze schrieb:

    Das jahr 2000 problem, halt nur mit 32 bit

    Bei Java: Das jahr 2000 problem, halt nur mit 64 bit.

    Das Y2K-Problem ist anderer Natur. Unabhängig davon hat Java dieses Problem allerdings nicht: Eine neue JRE löst das Problem.

    Aber auf solchen "Problemen" Programmiersprachenentscheidungen aufzubauen ist ohnehin lächerlich. Da baut man einen Workaround oder sonstwie einen fix und weiter gehts.

    Frage #1: Mit welcher Sprache erhalte ich maximalen Profit. Alle Faktoren einsammeln (Wartung, Schulungskosten, etc.) und unterm Strich steht heute sicher kein C++ mehr. C++ wird zwar immer noch viel geschrieben, aber es soll auch noch COBOL-Programmierer geben.

    MfG SideWinder



  • Volkard? Guru? Hab ich was verpasst? 😮 Habe nicht gewusst, das ich hier in einer Sekte bin. Und weil so ein mir unbekannter Typ was von 15-20 Jahren sagt, stimmt das. LOL



  • Artchi schrieb:

    Das können Fehler im Speicher-Management sein zum Beispiel ein Objekt zweimal gelöscht

    Smartpointer? Ist mittlerweile offizielle iSO-C++ bekannt! Kann ich garnicht ausversehen zweimal löschen. Klar, wenn ich rohe Pointer nutze. Stimmt.

    Smartpointer sind natürlich die Antwort auf alles.

    Oder Funktionen, die nichts zurückgeben (== einen uninitialisierten Speicherblock zurückgeben),

    Damit meine ich zum Beispiel:

    MyClass* foo() {
        for( ... )
             if( ... ) // programmierer denkt, das wird irgendwann schon true
                  return irgendwas;
    }
    

    Nicht dass ich das für ein ernsthaftes Problem halten würde. Aber ich würde auch einen möglichen buffer overflow allein nicht für ein ernsthaftes Problem halten. Aber an lauter solchen Trivialitäten erkennt man, dass man es im C++ Standard wohl nicht so wichtig mit der Sicherheit nimmt. Dinge wie diese sind für mich schwere Schäden an der Sprache und mir außerdem vollkommen unbegreiflich.

    Das Problem ist, immer wenn man ein einfaches Beispiel gibt, wo die Sprache kaputt ist, dann hacken alle darauf rum. "Ja wer SOWAS macht, ist selber schuld" Anscheinend gibt es genügend Leute, die kaputte Sachen machen und die Profis sitzen alle hier und labern, anstatt es besser zu machen. 😉
    Deshalb geb ich nicht gerne Beispiele.



  • Optimizer schrieb:

    groovemaster schrieb:

    [Das übliche: Man kann in C++ sicher programmieren, keiner zwingt einen, was mit Pointer-Arithmetik und Arrays zu machen und das ist ja so schön, dass man es sich genau aussuchen kann]

    In der Praxis funktioniert das nicht. Dazu braucht man eigentlich nur kurz einen Blick in die Welt hinaus werfen und sieht Sicherheitsprobleme hier und Sicherheitsprobleme da.

    Natürlich muss man da differenzieren. Es gibt Sicherheitsprobleme, die man mit keiner Sprache der Welt verhindern kann. Aber ein erstaunlich hoher Anteil sind buffer overruns, eine Trivialität eigentlich. Da hilft aber kein std::vector dagegen, denn die Ursachen sind meistens viel tiefgründiger als direkt ein falsch gesezter Index.

    Das können Fehler im Speicher-Management sein zum Beispiel ein Objekt zweimal gelöscht. Oder Funktionen, die nichts zurückgeben (== einen uninitialisierten Speicherblock zurückgeben), was C++ ja genialerweise erlaubt. Oder generell uninitialisierte lokale Variablen, was C++ ja genialerweise erlaubt (schön, dass man die Möglichkeit hat). Und überhaupt generell alles wofür der GEILE C++ Standard "undefiniertes" (== unsicheres) Verhalten vorsieht.

    Ja, das kann man vermeiden, mit modernen C++ Techniken. Das eine Code-Base die 10, 20 oder 30 Jahre alt ist, solche Techniken nicht kennt, ist eine andere Sache. Damals hatte man eben andere Anforderungen und Java-Software mit einer so alten Code-Base existiert ja wohl kaum.

    Und wenn man sich ansieht, wo BEISPIELSWEISE Java (hier kann man eigentlich fast alle Sprachen die ich kenne einfügen) undefiniertes Verhalten vorsieht, dann ist doch klar, dass es auf Sprachebene die Möglichkeit gibt, sichere Programme zu begünstigen.

    wow, ich habe keine Bufferoverflows. Meine Programme sind ja so sicher begünstigt. Wobei, wie schon mehrfach angedeutet wurde, Java ein schlechtes Beispiel ist um gegen Bufferoverflows zu wettern, da Java in den VMs ja selbst oft genug Bufferoverflows hatte.

    Natürlich ist es möglich, auch in C++ ein fehlerfreies Programm zu entwickeln. Auch in einer beliebigen Assembler-Sprache und in Brainfuck ist es möglich. C++ und die anderen Alternativen (;)) haben aber ein paar Eigenarten, die das nicht gerade unterstützen und da Menschen programmieren, passieren Fehler.

    Wie ich schon sagte, wenn man sich sichere Wrapper bastelt, dann hat man da auch keine Probleme.



  • @Optimizer: Das beispiel liefert wenn mich nicht alles täuscht einen Compilerfehler in meinem VC...

    @rüdiger: Du investierst in die falsche Sprache. Deine absolut unwirtschaftlichen Ausbrüche solltest du dir für C aufheben, dort ist Linux zu Hause 🙂

    MfG SideWinder



  • Wenn dir Smartpointer auch nicht reichen, nimm Hans Boehms Garbagecollector. Dann biste mit C++ auf Java-Level.



  • SideWinder schrieb:

    @rüdiger: Du investierst in die falsche Sprache. Deine absolut unwirtschaftlichen Ausbrüche solltest du dir für C aufheben, dort ist Linux zu Hause 🙂

    Bitte?!



  • otze schrieb:

    rüdiger schrieb:

    Taschenlampe schrieb:

    Wieso sagt eigentlich kein C++ befürworter was zu dem 2038er Problem?

    Welches 2038er Problem?

    Das jahr 2000 problem, halt nur mit 32 bit 😉

    ist aber imho echt kein problem, da im jahre 2038 wohl kein jetziges programm mehr im umlauf sein wird(technologie entwickelt sich halt weiter, ne?), und bis dahin time_t wohl schon lange 64bit hat.

    Das ist IMHO genau die Mentalität, die dann letztendlich zu einem y2038-Problem führen wird. War ja beim y2k-Problem genauso. ...wobei das y2k-Problem vielleicht überbewertet wurde. Letztendlich ist man zu diesem Problem gekommen, weil sich die Leute irgendwann gesagt hatten: Zu der Zeit wird mein Programm ja eh nicht mehr eingesetzt. Und das war halt falsch.

    So ein Problem würde vermutlich auch bei Java auftreten... ich gehe allerdings tatsächlich davon aus, dass Java im Vergleich zu C++ eine kürzere Halbwertszeit hat. 2038 wird man von Java auf eine andere Technologie umgestiegen sein. Damit meine ich nicht C++, sondern eine Technologie, die heute noch nicht da ist. C++ wird da IMHO länger leben. Grund: C++ ist flexibler, was die Anpassung an neue Technologien betrifft. Java wird da hingegen in absehbarer Zukunft ein paar Probleme bekommen. ...zum Beispiel, was die 64Bit-Fähigkeiten heutiger Prozessoren betrifft. Mit Java kann man die nicht so gut ausnutzen: Versuch mal, in Java ein Array mit 5 Mrd. Einträgen zu erstellen. Da wirst Du scheitern, auch wenn Du eine 64-Bit JVM hast.



  • Artchi schrieb:

    Wenn dir Smartpointer auch nicht reichen, nimm Hans Boehms Garbagecollector. Dann biste mit C++ auf Java-Level.

    Huh? Die Standardantwort auf alle Java-Vorteile gegenüber C++? "Aber man kann ja Java mit C++ nachbauen." ...zumindest mehr oder weniger. 😉



  • SideWinder schrieb:

    @Optimizer: Das beispiel liefert wenn mich nicht alles täuscht einen Compilerfehler in meinem VC...

    int* test() {
    	for( int i = 0;  i < 10;  ++i )
    		if( i == 10 )
    			return 0;
    }
    
    int main() {
    	int* blubb = test();
    	int i = *blubb;
    }
    

    Compiliert. In diesem billig-Fall kriegt man natürlich noch ne Warnung.

    Artchi schrieb:

    Wenn dir Smartpointer auch nicht reichen, nimm Hans Boehms Garbagecollector. Dann biste mit C++ auf Java-Level.

    Überhaupt nicht. Ein konservativer Garbage Collector (und keinen anderen kann man für Standard C++ implementieren) erreicht nicht annähernd eine vergleichbare Performance, da schlichtweg alle Algorithmen verboten sind, die Objekte verschieben würden. Das sind aber genau die Algorithmen, die heute in allen praktisch relevanten GCs implementiert sind.

    Desweiteren kann er verlassene Objekte nicht immer zuverlässig identifizieren (was die Definition eines konservativen Collectors ist). Das ist unerwünscht, wenn man den GC benutzt, um vergessene Handles und Socket-Verbindungen aufräumen zu lassen. C++ mit einem gescheiten GC wäre zum Beispiel C++/CLI - hierfür waren Spracherweiterungen nötig.



  • lolz schrieb:

    Warum lasst ihr euch eigentlich immer wieder auf eine Java vs. C++ Diskussion ein?

    Gute Frage. Schon mal aufgefallen, dass solche Sachen meistens von Java Anhängern ins Leben gerufen wird? Man mag ja 'ne Menge guter Sachen an Java finden, eine tolerante Community scheint wohl eher nicht dazu zu gehören.

    Gregor schrieb:

    Hmmm... Die C++ler sehen immer sämtliche Schuld beim Programmierer, die Javaleute gehen hingegen davon aus, dass es den perfekten Programmierer, der keine Fehler macht, nicht gibt.

    Ich denke, jeder der einschlägige Erfahrung mit Programmieren hat, wird das so sehen. Vollkommen unabhängig von der Sprache. Ich habe allerdings das Gefühl, dass durch die mittlerweile einfache Zugänglichkeit von Entwicklungstools zu viele glauben, sie könnten mal schnell Programmierer werden. Und regen sich dann auf, wenn eine Sprache für Ahnungslose zu viel Unsinn zulässt. Es gehört halt mehr dazu, als irgendwelchen Code in einen Editor abzutippen und sich jede Zeile in einem Forum vorkauen zu lassen.

    Gregor schrieb:

    Das ist ja auch ein Grund, warum die Javaleute eben Java nutzen: Da werden viele Fehler, die einem mit C++ assieren können, nicht ermöglicht.

    Was ja auch absolut ok ist. Aber für andere gibt es diese Notwendigkeit vllt. nicht. Soll das eine deshalb besser sein als das andere?

    Optimizer schrieb:

    Das können Fehler im Speicher-Management sein zum Beispiel ein Objekt zweimal gelöscht.

    Und was hat das mit C++ zu tun, wenn ein Container kaputt ist? Dann wird er halt gefixt. Am Clientcode ändert das jedoch rein gar nichts.

    Optimizer schrieb:

    Oder Funktionen, die nichts zurückgeben (== einen uninitialisierten Speicherblock zurückgeben), was C++ ja genialerweise erlaubt.

    Häää? Entweder du gibst etwas zurück oder nicht, dazwischen gibt es nichts.

    Optimizer schrieb:

    Oder generell uninitialisierte lokale Variablen, was C++ ja genialerweise erlaubt (schön, dass man die Möglichkeit hat).

    Auch in C++ ist RAII immer noch eine feine Sache. Und was soll das denn überhaupt für eine Argumentation sein? Soll ich jetzt kein Auto mehr kaufen, weil ich damit an einen Baum fahren kann?

    Optimizer schrieb:

    Natürlich ist es möglich, auch in C++ ein fehlerfreies Programm zu entwickeln. Auch in einer beliebigen Assembler-Sprache und in Brainfuck ist es möglich. C++ und die anderen Alternativen (;)) haben aber ein paar Eigenarten, die das nicht gerade unterstützen und da Menschen programmieren, passieren Fehler.

    Nö. Du kapierst überhaupt nicht worum es geht. Es geht nicht darum, dass ein perfekter Programmierer ohne Fehler fehlerfreie Anwendungen entwickeln kann. Es geht darum, dass du in C++ die Möglichkeit hast, entsprechende Alternativen zu nutzen, um, ohne sich den Kopf zerbrechen zu müssen, ebenfalls sicher entwickeln zu können.

    byto schrieb:

    Dieser Segen sorgte halt bis dato für zahllose Sicherheitslücken und gott-weiss wieviel Milliarden Dollar Schaden. Aber offenbar war das alles bloß von Newbs zusammengefrickelter Code, während die Sicherheitsexperten alle hier im Forum sitzen. 🙄 😉

    Netter Versuch, aber leider zu plump. 😉 Ich gehe mal davon aus, du sprichst hier Windows an. Da die relevanten Teile aber in C entwickelt wurden, ist das Offtopic.
    Und bevor hier jetzt noch jemand mit irgendwelchen sinnlosen Wunschvorstellungen über den Berg kommt, bitte nur mit aussagekräftigen Statistiken oder Belegen. Ansonsten hat das keinen Sinn.

    SideWinder schrieb:

    Das Y2K-Problem ist anderer Natur. Unabhängig davon hat Java dieses Problem allerdings nicht: Eine neue JRE löst das Problem.

    Und wo ist das Problem bei C++? Ein neuer Standard wird das Problem auch lösen. 😃 :p



  • Optimizer schrieb:

    Natürlich muss man da differenzieren. Es gibt Sicherheitsprobleme, die man mit keiner Sprache der Welt verhindern kann. Aber ein erstaunlich hoher Anteil sind buffer overruns, eine Trivialität eigentlich. Da hilft aber kein std::vector dagegen, denn die Ursachen sind meistens viel tiefgründiger als direkt ein falsch gesezter Index.

    ja. linuxer, die weiterhin c coden. und selbst, wenn sie nen c++-compiler benutzt haben, bleibt es c-stil.



  • Optimizer schrieb:

    Oder generell uninitialisierte lokale Variablen, was C++ ja genialerweise erlaubt (schön, dass man die Möglichkeit hat).

    bau nen konstruktor und der default-konstruktor ist weg. schon geht es nicht mehr, so ein objekt uninitialisiert zu lassen. wo ist dein problem?
    und uninitialisierte variablen sind wirklich ein anfängerfehler. damit überzeugst du keinen.


Anmelden zum Antworten