Frage zu gets/fgets/scanf/fscanf



  • Hallo zusammen,

    eventuell kann mir jemand genauer erklären, warum gets und fgets fast keine Verwendung mehr finden, nur weil sie veraltet sind.
    Ich hörte oft "aus Sicherheitsgründen", aber was genau für Probleme gehen mit ihnen einher?

    Vielleicht weiß jm. ein wenig mehr darüber, wäre klasse.

    Dank und Gruß



  • int main(void)
    {
        char buffer[3];
        gets(buffer);
        return 0;
    }
    

    Tipp da mal "Hallo buffer overflow!" ein und drück Enter => Segfault

    Bei den (f)gets Funktionen hast du keine Möglichkeit die Größe deines Strings anzugeben. Die Funktionen ballern dir gnadenlos über alle Ränder hinweg in den Speicher, wenn die Eingabe zu lang ist.


  • Mod

    Bei gets hat der Programmierer keine Möglichkeit, einen Buffer overflow zu verhindern. Das heißt, man muss sich auf den guten Willen des Nutzers verlassen. Das geht gar nicht. Daher wurde gets auch abgeschafft.

    Bei fgets/scanf/fscanf liegt es in der Verantwortung des Programmierers, diese korrekt zu benutzen, um eine Buffer Overflow Attacke durch einen böswilligen Nutzer zu verhindern. Das kann ok sein, hat aber folgende mögliche Probleme:
    a) Schlechte Programmierer, die gar nicht an diese Möglichkeit denken
    b) Schlechte Programmierer, die es vermasseln
    c) Nachträgliche Änderungen an gänzlich anderen Stellen im Code (wahrscheinlich durch ganz andere Personen), die ursprünglich richtige fgets/scanf/fscanf-Aufrufe plötzlich unsicher machen.

    Besser ist es daher, wenn mögliche Probleme spätestens zur Laufzeit, besser aber noch zur Compilezeit automatisch erkannt werden.



  • Danke ersteimal für die ausführliche Beschreibung 👍

    Dann würde ich gern noch eine weitere Frage zu SeppJ anhängen.
    b) Gibt es in C die Möglichkeit (oder einen Art "standard Code") die "Unachtsamkeit" der Programmierers durch sichere Funtkionen ein zu dämmen,
    c) beziehungsweise nachträgliche Änderungen zu sichern?


  • Mod

    fgets nimmt die Pufferlänge als Argument, es ist also kein Problem, so lange der Programmierer die Länge nicht von Hand ausschreibt, sondern so etwas wie sizeof benutzt.

    (f)scanf hat das Problem, dass man die Länge nicht variabel angeben kann. K&R schlagen vor, zur Laufzeit den Formatstring aus der Längenangabe zu erzeugen (mit s(n)printf).

    Viele Compiler bieten spezielle Erweiterungen an, um das Problem zu lösen. Manche davon haben es sogar als optionales (sprich: plattformabhängiges) Feature in den Standard geschafft. Microsoft bietet da beispielsweise die *_s-Varianten der genannten Funktionen an (also z.B. scanf_s statt scanf. Achtung: Diese Funktionen sind anders zu benutzen als ihre Vorbilder!). POSIX kennt 'm' als "Längenangabe", welches einen ausreichend großen Puffer malloc't. Die GNU glibc bietet das gleiche unter dem Buchstaben 'a' (daher Achtung, wie man sein Programm genau übersetzt, denn 'a' ist bei Posix ein Formatspezifizierer für Fließkommazahlen).



  • Danke für die Informationen, diese haben mir weitergeholfen und ein besseres Verständnis verschafft. Nun habe ich auch gute Anhaltspunkte um weiter nach zu schlagen.

    Dank und Gruß


Anmelden zum Antworten