Aussehen
Suche Einloggen
[c] [meta] [fefe] [erp]

/c/ – Pufferüberlauf


Antwort erstellen

(≤ 4)



[Zurück]

  • [l] https://gcc.gnu.org/gcc-15/changes.html Felix Sun, 01 Jun 2025 06:16:13 GMT Nr. 157356
    WEBM 640×360 1:21 3.8M
    >This page is a "brief" summary of some of the huge number of improvements in GCC 15
    >...
    >{0} initializer in C or C++ for unions no longer guarantees clearing of the whole union (except for static storage duration initialization), it just initializes the first union member to zero. If initialization of the whole union including padding bits is desirable, use {} (valid in C23 or C++) or use -fzero-init-padding-bits=unions option to restore old GCC behavior.
    Ja, das ist wirklich eine großartige Verbesserung! Da kann man schon bildlich vor seinem inneren Auge die tausenden neuen CVEs sehen, die da bald kommen. Was rauchen die eigentlich bei GCC?
  • [l] Felix Sun, 01 Jun 2025 06:29:34 GMT Nr. 157357
    Weiß hier zufällig jemand, ob das auch structs betrifft oder nur unions?

    Vielleicht in Zukunft doch lieber wieder mit memset() initialisieren? Aber denen fällt bestimmt bald irgendwas ein, wie sie das auch noch kaputt kriegen.
  • [l] Felix Sun, 01 Jun 2025 10:55:42 GMT Nr. 157372
    >>157357
    Der C-Standard schreibt vor, dass alle verbleibenden Felder eines Structs inklusive Füllung leer-initialisiert werden, wenn mindestens ein Feld explizit initialisiert wird.
    Bezüglich Unions hat er aber immer nur vorausgesetzt, dass das benutzte Mitglied initialisiert wird, auch wenn man seit C99 per Bezeichner ein anderes wählen kann.
  • [l] Felix Sun, 01 Jun 2025 11:03:51 GMT Nr. 157374
    >>157372
    >Bezüglich Unions hat er aber immer nur vorausgesetzt, dass das benutzte Mitglied initialisiert wird, auch wenn man seit C99 per Bezeichner ein anderes wählen kann.
    Mag sein, trotzdem geht GCC hier vollretardiert. Welchen Nutzen soll das haben?
  • [l] Felix Sun, 01 Jun 2025 11:15:12 GMT Nr. 157376
    >Was rauchen die eigentlich bei GCC?
    Vorsicht, gleich pfostiert ein Felix die Bugzilla-Elfe mit Fefe und -fwrapv und erklärt dir, das alles, was im C-Standard legal ist, per definitionem eine gute Implementationsentscheidung ist.

    Tatsächlich wird diese Geschichte noch lustiger: Clang hatte dieses Verhalten in der Vergangenheit, schuf es dann aber wieder ab, weil es zu behindert war und GCC es richtig tat. Jetzt macht es Clang richtig aber GCC falsch.

    >>157357
    Nur Unionen. memset ist streng genommen übrigens auch nicht zuverlässig, da NULL und 0.0 nicht unbedingt durch Nullbytes repräsentiert werden müssen.

    >>157374
    >Welchen Nutzen soll das haben?
    Damit kann man behinderte Mikrobankmarken gewinnen.
  • [l] Felix Sun, 01 Jun 2025 12:02:47 GMT Nr. 157382
    >>157376
    >Damit kann man behinderte Mikrobankmarken gewinnen.
    Selbst das erscheint fraglich. Welche Mikrobankmarke soll das sein?

    union { char a; char b[10000]; } trololol = {0};
    

  • [l] Felix Sun, 01 Jun 2025 12:37:16 GMT Nr. 157384
    >>157374
    Die naheliegendste Erklärung für Felix ist, dass {0} wie in vorherigen Versionen von Clang entgegen der Intuition kein spezielles Muster für das Nullen des Unions ist (vor allem, wenn das erste Mitglied kein Standard-Datentyp ist, bei dem der Nullwert nicht vollständig aus Nullbits besteht), sondern schlicht das erste Mitglied auf Null setzt und jetzt das implizite Leeren des Rests wegfällt.

    Felix hat sich aufgrund dieses konstruierten Beispiels mit Godbolt angesehen, was das in der Praxis bedeutet:
    extern void dosomething(long *);
    void bla() {
        union { int i; long l; } U = {-42};
        dosomething(&U.l);
    }


    x86_64, gcc 14.3, -O0: gesamtes Union wird genullt und dann die unteren 32 Bit geschrieben
    x86_64, gcc 14.3, -O1: die oberen 32 Bit werden explizit auf Null gesetzt und dann die unteren 32 Bit geschrieben
    x86_64, gcc 14.3, -O2/-O3: 32 Bit werden in EAX geladen, damit implizit die oberen 32 Bit des Registers auf Null gesetzt und RAX in das Union geschrieben

    x86_64, gcc 15.1, -O0: nur die unteren 32 Bit werden geschrieben
    x86_64, gcc 15.1, -O1: wie gcc 14.3
    x86_64, gcc 15.1, -O2/-O3: wie gcc 14.3

    ARM64-Ausgabe verhält sich jeweils wie x86_64, nur dass für -O1 die stp-Instruktion in Kombination mit dem Nullregister benutzt wird.

    x86_64, clang, -O0: 64 Bit mit Nullpadding werden aus static storage gelesen und geschrieben
    x86_64, clang, -O1/-O2/-O3: wie gcc -O2

    ARM64-Ausgabe verhält sich jeweils wie x86_64, d.h. mit Optimierungen werden die oberen 32 Bit eines 64-Bit-Registers implizit genullt.

    x86_64, ARM64 MSVC unabhängig von Optimizer-Flags: nur die unteren 32 Bit werden geschrieben

    Für dieses Beispiel auf diesen zwei Plattformen macht GCC 15 also zufälligerweise etwas Sinnvolles, außer wenn Optimierungen deaktiviert sind.
  • [l] Felix Sun, 01 Jun 2025 12:48:00 GMT Nr. 157385 SÄGE
    >>157384
    Vergessen, dass MSVC ein ILP32-Speichermodell nutzt und long standardmäßig auch nur 32 Bits sind. Unter diesen Umständen stellt der Microsoft-Compiler ebenfalls immer sicher, dass die oberen 32 Bit genullt sind.
  • [l] Carnevals Club Felix Sun, 01 Jun 2025 18:00:09 GMT Nr. 157411
    >>157356
    >Was rauchen die eigentlich bei GCC?
    Bei GCC?
    Meinten Sie:
    >beim GCC?
    ...?
  • [l] Felix Sun, 01 Jun 2025 19:24:02 GMT Nr. 157420
    >>157356
    >Ja, das ist wirklich eine großartige Verbesserung!
    Sie haben immerhin von "huge number of improvements", nicht "huge improvements" geschrieben.

    >Da kann man schon bildlich vor seinem inneren Auge die tausenden neuen CVEs sehen, die da bald kommen.
    Felix kompiliert gerade sein komplettes Gentoo neu auf GCC 15, wünsch ihm Glück!

    >>157382
    Denk an die Vielzahl von Bankmarken, die wegen UB auf ein ret runterkompiliert werden können! Laufzeit: 0 ms, unbesiegt.

    >>157411
    Ghaos Computer Club

    Jetzt mal im Bernst: Gibt es wenigstens eine standardmäßige Warnung, wenn man ein so initialisiertes union dann als uninitialisierte Variable benutzt? Spätestens bei Übergabe an Funktionen könnte es schwierig zu detektieren werden...
  • [l] Felix Sun, 01 Jun 2025 19:34:43 GMT Nr. 157421
    >>157420
    >Jetzt mal im Bernst: Gibt es wenigstens eine standardmäßige Warnung
    Haha, nein. Sogar insofern verständlich, dass man dann bei jeder Nullinitialisierung einer betroffenen Union warnen müsste. Es gibt wohl die im OP erwähnte Flagge, um diesen Müll wieder abzuschalten, aber die existiert natürlich nicht unter GCC 14 und älter.
  • [l] Felix Sun, 01 Jun 2025 20:05:25 GMT Nr. 157422
    >>157421
    >dass man dann bei jeder Nullinitialisierung einer betroffenen Union warnen müsste.
    Felix ging es eher um den Zugriff auf ein Feld des Unions, das (für den Compiler beweisbar) nicht vollständig initialisiert wurde, wie in >>157384, aber zumindest ist Felixens Frage damit beantwortet. Felix hat auch gerade alle erdenklichen Variationen mit GCC 15 durchprobiert.


[Zurück]
[c] [meta] [fefe] [erp]